aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/cw1200/Kconfig46
-rw-r--r--drivers/net/wireless/cw1200/Makefile24
-rw-r--r--drivers/net/wireless/cw1200/bh.c616
-rw-r--r--drivers/net/wireless/cw1200/bh.h28
-rw-r--r--drivers/net/wireless/cw1200/cw1200.h332
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sagrad.c145
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sdio.c409
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c480
-rw-r--r--drivers/net/wireless/cw1200/debug.c664
-rw-r--r--drivers/net/wireless/cw1200/debug.h98
-rw-r--r--drivers/net/wireless/cw1200/fwio.c525
-rw-r--r--drivers/net/wireless/cw1200/fwio.h39
-rw-r--r--drivers/net/wireless/cw1200/hwio.c311
-rw-r--r--drivers/net/wireless/cw1200/hwio.h247
-rw-r--r--drivers/net/wireless/cw1200/itp.c730
-rw-r--r--drivers/net/wireless/cw1200/itp.h144
-rw-r--r--drivers/net/wireless/cw1200/main.c618
-rw-r--r--drivers/net/wireless/cw1200/pm.c367
-rw-r--r--drivers/net/wireless/cw1200/pm.h38
-rw-r--r--drivers/net/wireless/cw1200/queue.c583
-rw-r--r--drivers/net/wireless/cw1200/queue.h116
-rw-r--r--drivers/net/wireless/cw1200/sbus.h37
-rw-r--r--drivers/net/wireless/cw1200/scan.c461
-rw-r--r--drivers/net/wireless/cw1200/scan.h56
-rw-r--r--drivers/net/wireless/cw1200/sta.c2406
-rw-r--r--drivers/net/wireless/cw1200/sta.h123
-rw-r--r--drivers/net/wireless/cw1200/txrx.c1474
-rw-r--r--drivers/net/wireless/cw1200/txrx.h106
-rw-r--r--drivers/net/wireless/cw1200/wsm.c1884
-rw-r--r--drivers/net/wireless/cw1200/wsm.h1879
-rw-r--r--include/linux/cw1200_platform.h46
34 files changed, 15040 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 3d7782b9f90d..e5069c223391 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2299,6 +2299,11 @@ M: Jaya Kumar <jayakumar.alsa@gmail.com>
2299S: Maintained 2299S: Maintained
2300F: sound/pci/cs5535audio/ 2300F: sound/pci/cs5535audio/
2301 2301
2302CW1200 WLAN driver
2303M: Solomon Peachy <pizza@shaftnet.org>
2304S: Maintained
2305F: drivers/net/wireless/cw1200/
2306
2302CX18 VIDEO4LINUX DRIVER 2307CX18 VIDEO4LINUX DRIVER
2303M: Andy Walls <awalls@md.metrocast.net> 2308M: Andy Walls <awalls@md.metrocast.net>
2304L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) 2309L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f8f0156dff4e..200020eb3005 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -280,5 +280,6 @@ source "drivers/net/wireless/rtlwifi/Kconfig"
280source "drivers/net/wireless/ti/Kconfig" 280source "drivers/net/wireless/ti/Kconfig"
281source "drivers/net/wireless/zd1211rw/Kconfig" 281source "drivers/net/wireless/zd1211rw/Kconfig"
282source "drivers/net/wireless/mwifiex/Kconfig" 282source "drivers/net/wireless/mwifiex/Kconfig"
283source "drivers/net/wireless/cw1200/Kconfig"
283 284
284endif # WLAN 285endif # WLAN
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 67156efe14c4..0fab227025be 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -57,3 +57,5 @@ obj-$(CONFIG_MWIFIEX) += mwifiex/
57 57
58obj-$(CONFIG_BRCMFMAC) += brcm80211/ 58obj-$(CONFIG_BRCMFMAC) += brcm80211/
59obj-$(CONFIG_BRCMSMAC) += brcm80211/ 59obj-$(CONFIG_BRCMSMAC) += brcm80211/
60
61obj-$(CONFIG_CW1200) += cw1200/
diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
new file mode 100644
index 000000000000..13e36119ae9f
--- /dev/null
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -0,0 +1,46 @@
1config CW1200
2 tristate "CW1200 WLAN support"
3 depends on MAC80211 && CFG80211
4 help
5 This is a driver for the ST-E CW1100 & CW1200 WLAN chipsets.
6 This option just enables the driver core, see below for
7 specific bus support.
8
9if CW1200
10
11config CW1200_WLAN_SDIO
12 tristate "Support SDIO platforms"
13 depends on CW1200 && MMC
14 help
15 Enable support for the CW1200 connected via an SDIO bus.
16
17config CW1200_WLAN_SPI
18 tristate "Support SPI platforms"
19 depends on CW1200 && SPI
20 help
21 Enables support for the CW1200 connected via a SPI bus.
22
23config CW1200_WLAN_SAGRAD
24 tristate "Support Sagrad SG901-1091/1098 modules"
25 depends on CW1200_WLAN_SDIO
26 help
27 This provides the platform data glue to support the
28 Sagrad SG901-1091/1098 modules in their standard SDIO EVK.
29 It also includes example SPI platform data.
30
31menu "Driver debug features"
32 depends on CW1200 && DEBUG_FS
33
34config CW1200_ETF
35 bool "Enable CW1200 Engineering Test Framework hooks"
36 help
37 If you don't know what this is, just say N.
38
39config CW1200_ITP
40 bool "Enable ITP access"
41 help
42 If you don't know what this is, just say N.
43
44endmenu
45
46endif
diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile
new file mode 100644
index 000000000000..c19737276be2
--- /dev/null
+++ b/drivers/net/wireless/cw1200/Makefile
@@ -0,0 +1,24 @@
1cw1200_core-y := \
2 fwio.o \
3 txrx.o \
4 main.o \
5 queue.o \
6 hwio.o \
7 bh.o \
8 wsm.o \
9 sta.o \
10 scan.o \
11 pm.o \
12 debug.o
13cw1200_core-$(CONFIG_CW1200_ITP) += itp.o
14
15# CFLAGS_sta.o += -DDEBUG
16
17cw1200_wlan_sdio-y := cw1200_sdio.o
18cw1200_wlan_spi-y := cw1200_spi.o
19cw1200_wlan_sagrad-y := cw1200_sagrad.o
20
21obj-$(CONFIG_CW1200) += cw1200_core.o
22obj-$(CONFIG_CW1200_WLAN_SDIO) += cw1200_wlan_sdio.o
23obj-$(CONFIG_CW1200_WLAN_SPI) += cw1200_wlan_spi.o
24obj-$(CONFIG_CW1200_WLAN_SAGRAD) += cw1200_wlan_sagrad.o
diff --git a/drivers/net/wireless/cw1200/bh.c b/drivers/net/wireless/cw1200/bh.c
new file mode 100644
index 000000000000..cf7375f92fb3
--- /dev/null
+++ b/drivers/net/wireless/cw1200/bh.c
@@ -0,0 +1,616 @@
1/*
2 * Device handling thread implementation for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver, which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/module.h>
18#include <net/mac80211.h>
19#include <linux/kthread.h>
20#include <linux/timer.h>
21
22#include "cw1200.h"
23#include "bh.h"
24#include "hwio.h"
25#include "wsm.h"
26#include "sbus.h"
27#include "debug.h"
28#include "fwio.h"
29
30static int cw1200_bh(void *arg);
31
32#define DOWNLOAD_BLOCK_SIZE_WR (0x1000 - 4)
33/* an SPI message cannot be bigger than (2"12-1)*2 bytes
34 * "*2" to cvt to bytes */
35#define MAX_SZ_RD_WR_BUFFERS (DOWNLOAD_BLOCK_SIZE_WR*2)
36#define PIGGYBACK_CTRL_REG (2)
37#define EFFECTIVE_BUF_SIZE (MAX_SZ_RD_WR_BUFFERS - PIGGYBACK_CTRL_REG)
38
39/* Suspend state privates */
40enum cw1200_bh_pm_state {
41 CW1200_BH_RESUMED = 0,
42 CW1200_BH_SUSPEND,
43 CW1200_BH_SUSPENDED,
44 CW1200_BH_RESUME,
45};
46
47typedef int (*cw1200_wsm_handler)(struct cw1200_common *priv,
48 u8 *data, size_t size);
49
50static void cw1200_bh_work(struct work_struct *work)
51{
52 struct cw1200_common *priv =
53 container_of(work, struct cw1200_common, bh_work);
54 cw1200_bh(priv);
55}
56
57int cw1200_register_bh(struct cw1200_common *priv)
58{
59 int err = 0;
60 /* Realtime workqueue */
61 priv->bh_workqueue = alloc_workqueue("cw1200_bh",
62 WQ_MEM_RECLAIM | WQ_HIGHPRI
63 | WQ_CPU_INTENSIVE, 1);
64
65 if (!priv->bh_workqueue)
66 return -ENOMEM;
67
68 INIT_WORK(&priv->bh_work, cw1200_bh_work);
69
70 pr_debug("[BH] register.\n");
71
72 atomic_set(&priv->bh_rx, 0);
73 atomic_set(&priv->bh_tx, 0);
74 atomic_set(&priv->bh_term, 0);
75 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
76 priv->bh_error = 0;
77 priv->hw_bufs_used = 0;
78 priv->buf_id_tx = 0;
79 priv->buf_id_rx = 0;
80 init_waitqueue_head(&priv->bh_wq);
81 init_waitqueue_head(&priv->bh_evt_wq);
82
83 err = !queue_work(priv->bh_workqueue, &priv->bh_work);
84 WARN_ON(err);
85 return err;
86}
87
88void cw1200_unregister_bh(struct cw1200_common *priv)
89{
90 atomic_add(1, &priv->bh_term);
91 wake_up(&priv->bh_wq);
92
93 flush_workqueue(priv->bh_workqueue);
94
95 destroy_workqueue(priv->bh_workqueue);
96 priv->bh_workqueue = NULL;
97
98 pr_debug("[BH] unregistered.\n");
99}
100
101void cw1200_irq_handler(struct cw1200_common *priv)
102{
103 pr_debug("[BH] irq.\n");
104
105 /* Disable Interrupts! */
106 /* NOTE: sbus_ops->lock already held */
107 __cw1200_irq_enable(priv, 0);
108
109 if (/* WARN_ON */(priv->bh_error))
110 return;
111
112 if (atomic_add_return(1, &priv->bh_rx) == 1)
113 wake_up(&priv->bh_wq);
114}
115EXPORT_SYMBOL_GPL(cw1200_irq_handler);
116
117void cw1200_bh_wakeup(struct cw1200_common *priv)
118{
119 pr_debug("[BH] wakeup.\n");
120 if (priv->bh_error) {
121 pr_err("[BH] wakeup failed (BH error)\n");
122 return;
123 }
124
125 if (atomic_add_return(1, &priv->bh_tx) == 1)
126 wake_up(&priv->bh_wq);
127}
128
129int cw1200_bh_suspend(struct cw1200_common *priv)
130{
131 pr_debug("[BH] suspend.\n");
132 if (priv->bh_error) {
133 wiphy_warn(priv->hw->wiphy, "BH error -- can't suspend\n");
134 return -EINVAL;
135 }
136
137 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPEND);
138 wake_up(&priv->bh_wq);
139 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
140 (CW1200_BH_SUSPENDED == atomic_read(&priv->bh_suspend)),
141 1 * HZ) ? 0 : -ETIMEDOUT;
142}
143
144int cw1200_bh_resume(struct cw1200_common *priv)
145{
146 pr_debug("[BH] resume.\n");
147 if (priv->bh_error) {
148 wiphy_warn(priv->hw->wiphy, "BH error -- can't resume\n");
149 return -EINVAL;
150 }
151
152 atomic_set(&priv->bh_suspend, CW1200_BH_RESUME);
153 wake_up(&priv->bh_wq);
154 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
155 (CW1200_BH_RESUMED == atomic_read(&priv->bh_suspend)),
156 1 * HZ) ? 0 : -ETIMEDOUT;
157}
158
159static inline void wsm_alloc_tx_buffer(struct cw1200_common *priv)
160{
161 ++priv->hw_bufs_used;
162}
163
164int wsm_release_tx_buffer(struct cw1200_common *priv, int count)
165{
166 int ret = 0;
167 int hw_bufs_used = priv->hw_bufs_used;
168
169 priv->hw_bufs_used -= count;
170 if (WARN_ON(priv->hw_bufs_used < 0))
171 ret = -1;
172 else if (hw_bufs_used >= priv->wsm_caps.input_buffers)
173 ret = 1;
174 if (!priv->hw_bufs_used)
175 wake_up(&priv->bh_evt_wq);
176 return ret;
177}
178
179static int cw1200_bh_read_ctrl_reg(struct cw1200_common *priv,
180 u16 *ctrl_reg)
181{
182 int ret;
183
184 ret = cw1200_reg_read_16(priv,
185 ST90TDS_CONTROL_REG_ID, ctrl_reg);
186 if (ret) {
187 ret = cw1200_reg_read_16(priv,
188 ST90TDS_CONTROL_REG_ID, ctrl_reg);
189 if (ret)
190 pr_err("[BH] Failed to read control register.\n");
191 }
192
193 return ret;
194}
195
196static int cw1200_device_wakeup(struct cw1200_common *priv)
197{
198 u16 ctrl_reg;
199 int ret;
200
201 pr_debug("[BH] Device wakeup.\n");
202
203 /* First, set the dpll register */
204 ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
205 cw1200_dpll_from_clk(priv->hw_refclk));
206 if (WARN_ON(ret))
207 return ret;
208
209 /* To force the device to be always-on, the host sets WLAN_UP to 1 */
210 ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
211 ST90TDS_CONT_WUP_BIT);
212 if (WARN_ON(ret))
213 return ret;
214
215 ret = cw1200_bh_read_ctrl_reg(priv, &ctrl_reg);
216 if (WARN_ON(ret))
217 return ret;
218
219 /* If the device returns WLAN_RDY as 1, the device is active and will
220 * remain active. */
221 if (ctrl_reg & ST90TDS_CONT_RDY_BIT) {
222 pr_debug("[BH] Device awake.\n");
223 return 1;
224 }
225
226 return 0;
227}
228
229/* Must be called from BH thraed. */
230void cw1200_enable_powersave(struct cw1200_common *priv,
231 bool enable)
232{
233 pr_debug("[BH] Powerave is %s.\n",
234 enable ? "enabled" : "disabled");
235 priv->powersave_enabled = enable;
236}
237
238static int cw1200_bh_rx_helper(struct cw1200_common *priv,
239 uint16_t *ctrl_reg,
240 int *tx)
241{
242 size_t read_len = 0;
243 struct sk_buff *skb_rx = NULL;
244 struct wsm_hdr *wsm;
245 size_t wsm_len;
246 u16 wsm_id;
247 u8 wsm_seq;
248 int rx_resync = 1;
249
250 size_t alloc_len;
251 u8 *data;
252
253 read_len = (*ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) * 2;
254 if (!read_len)
255 return 0; /* No more work */
256
257 if (WARN_ON((read_len < sizeof(struct wsm_hdr)) ||
258 (read_len > EFFECTIVE_BUF_SIZE))) {
259 pr_debug("Invalid read len: %zu (%04x)",
260 read_len, *ctrl_reg);
261 goto err;
262 }
263
264 /* Add SIZE of PIGGYBACK reg (CONTROL Reg)
265 * to the NEXT Message length + 2 Bytes for SKB */
266 read_len = read_len + 2;
267
268 alloc_len = priv->sbus_ops->align_size(
269 priv->sbus_priv, read_len);
270
271 /* Check if not exceeding CW1200 capabilities */
272 if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE)) {
273 pr_debug("Read aligned len: %zu\n",
274 alloc_len);
275 }
276
277 skb_rx = dev_alloc_skb(alloc_len);
278 if (WARN_ON(!skb_rx))
279 goto err;
280
281 skb_trim(skb_rx, 0);
282 skb_put(skb_rx, read_len);
283 data = skb_rx->data;
284 if (WARN_ON(!data))
285 goto err;
286
287 if (WARN_ON(cw1200_data_read(priv, data, alloc_len))) {
288 pr_err("rx blew up, len %zu\n", alloc_len);
289 goto err;
290 }
291
292 /* Piggyback */
293 *ctrl_reg = __le16_to_cpu(
294 ((__le16 *)data)[alloc_len / 2 - 1]);
295
296 wsm = (struct wsm_hdr *)data;
297 wsm_len = __le16_to_cpu(wsm->len);
298 if (WARN_ON(wsm_len > read_len))
299 goto err;
300
301 if (priv->wsm_enable_wsm_dumps)
302 print_hex_dump_bytes("<-- ",
303 DUMP_PREFIX_NONE,
304 data, wsm_len);
305
306 wsm_id = __le16_to_cpu(wsm->id) & 0xFFF;
307 wsm_seq = (__le16_to_cpu(wsm->id) >> 13) & 7;
308
309 skb_trim(skb_rx, wsm_len);
310
311 if (wsm_id == 0x0800) {
312 wsm_handle_exception(priv,
313 &data[sizeof(*wsm)],
314 wsm_len - sizeof(*wsm));
315 goto err;
316 } else if (!rx_resync) {
317 if (WARN_ON(wsm_seq != priv->wsm_rx_seq))
318 goto err;
319 }
320 priv->wsm_rx_seq = (wsm_seq + 1) & 7;
321 rx_resync = 0;
322
323 if (wsm_id & 0x0400) {
324 int rc = wsm_release_tx_buffer(priv, 1);
325 if (WARN_ON(rc < 0))
326 return rc;
327 else if (rc > 0)
328 *tx = 1;
329 }
330
331 /* cw1200_wsm_rx takes care on SKB livetime */
332 if (WARN_ON(wsm_handle_rx(priv, wsm_id, wsm, &skb_rx)))
333 goto err;
334
335 if (skb_rx) {
336 dev_kfree_skb(skb_rx);
337 skb_rx = NULL;
338 }
339
340 return 0;
341
342err:
343 if (skb_rx) {
344 dev_kfree_skb(skb_rx);
345 skb_rx = NULL;
346 }
347 return -1;
348}
349
350static int cw1200_bh_tx_helper(struct cw1200_common *priv,
351 int *pending_tx,
352 int *tx_burst)
353{
354 size_t tx_len;
355 u8 *data;
356 int ret;
357 struct wsm_hdr *wsm;
358
359 if (priv->device_can_sleep) {
360 ret = cw1200_device_wakeup(priv);
361 if (WARN_ON(ret < 0)) { /* Error in wakeup */
362 *pending_tx = 1;
363 return 0;
364 } else if (ret) { /* Woke up */
365 priv->device_can_sleep = false;
366 } else { /* Did not awake */
367 *pending_tx = 1;
368 return 0;
369 }
370 }
371
372 wsm_alloc_tx_buffer(priv);
373 ret = wsm_get_tx(priv, &data, &tx_len, tx_burst);
374 if (ret <= 0) {
375 wsm_release_tx_buffer(priv, 1);
376 if (WARN_ON(ret < 0))
377 return ret; /* Error */
378 return 0; /* No work */
379 }
380
381 wsm = (struct wsm_hdr *)data;
382 BUG_ON(tx_len < sizeof(*wsm));
383 BUG_ON(__le16_to_cpu(wsm->len) != tx_len);
384
385 atomic_add(1, &priv->bh_tx);
386
387 tx_len = priv->sbus_ops->align_size(
388 priv->sbus_priv, tx_len);
389
390 /* Check if not exceeding CW1200 capabilities */
391 if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
392 pr_debug("Write aligned len: %zu\n", tx_len);
393
394 wsm->id &= __cpu_to_le16(0xffff ^ WSM_TX_SEQ(WSM_TX_SEQ_MAX));
395 wsm->id |= __cpu_to_le16(WSM_TX_SEQ(priv->wsm_tx_seq));
396
397 if (WARN_ON(cw1200_data_write(priv, data, tx_len))) {
398 pr_err("tx blew up, len %zu\n", tx_len);
399 wsm_release_tx_buffer(priv, 1);
400 return -1; /* Error */
401 }
402
403 if (priv->wsm_enable_wsm_dumps)
404 print_hex_dump_bytes("--> ",
405 DUMP_PREFIX_NONE,
406 data,
407 __le16_to_cpu(wsm->len));
408
409 wsm_txed(priv, data);
410 priv->wsm_tx_seq = (priv->wsm_tx_seq + 1) & WSM_TX_SEQ_MAX;
411
412 if (*tx_burst > 1) {
413 cw1200_debug_tx_burst(priv);
414 return 1; /* Work remains */
415 }
416
417 return 0;
418}
419
420static int cw1200_bh(void *arg)
421{
422 struct cw1200_common *priv = arg;
423 int rx, tx, term, suspend;
424 u16 ctrl_reg = 0;
425 int tx_allowed;
426 int pending_tx = 0;
427 int tx_burst;
428 long status;
429 u32 dummy;
430 int ret;
431
432 for (;;) {
433 if (!priv->hw_bufs_used &&
434 priv->powersave_enabled &&
435 !priv->device_can_sleep &&
436 !atomic_read(&priv->recent_scan)) {
437 status = 1 * HZ;
438 pr_debug("[BH] Device wakedown. No data.\n");
439 cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, 0);
440 priv->device_can_sleep = true;
441 } else if (priv->hw_bufs_used) {
442 /* Interrupt loss detection */
443 status = 1 * HZ;
444 } else {
445 status = MAX_SCHEDULE_TIMEOUT;
446 }
447
448 /* Dummy Read for SDIO retry mechanism*/
449 if ((priv->hw_type != -1) &&
450 (atomic_read(&priv->bh_rx) == 0) &&
451 (atomic_read(&priv->bh_tx) == 0))
452 cw1200_reg_read(priv, ST90TDS_CONFIG_REG_ID,
453 &dummy, sizeof(dummy));
454
455 pr_debug("[BH] waiting ...\n");
456 status = wait_event_interruptible_timeout(priv->bh_wq, ({
457 rx = atomic_xchg(&priv->bh_rx, 0);
458 tx = atomic_xchg(&priv->bh_tx, 0);
459 term = atomic_xchg(&priv->bh_term, 0);
460 suspend = pending_tx ?
461 0 : atomic_read(&priv->bh_suspend);
462 (rx || tx || term || suspend || priv->bh_error);
463 }), status);
464
465 pr_debug("[BH] - rx: %d, tx: %d, term: %d, suspend: %d, status: %ld\n",
466 rx, tx, term, suspend, status);
467
468 /* Did an error occur? */
469 if ((status < 0 && status != -ERESTARTSYS) ||
470 term || priv->bh_error) {
471 break;
472 }
473 if (!status) { /* wait_event timed out */
474 unsigned long timestamp = jiffies;
475 long timeout;
476 int pending = 0;
477 int i;
478
479 /* Check to see if we have any outstanding frames */
480 if (priv->hw_bufs_used && (!rx || !tx)) {
481 wiphy_warn(priv->hw->wiphy,
482 "Missed interrupt? (%d frames outstanding)\n",
483 priv->hw_bufs_used);
484 rx = 1;
485
486 /* Get a timestamp of "oldest" frame */
487 for (i = 0; i < 4; ++i)
488 pending += cw1200_queue_get_xmit_timestamp(
489 &priv->tx_queue[i],
490 &timestamp,
491 priv->pending_frame_id);
492
493 /* Check if frame transmission is timed out.
494 * Add an extra second with respect to possible
495 * interrupt loss.
496 */
497 timeout = timestamp +
498 WSM_CMD_LAST_CHANCE_TIMEOUT +
499 1 * HZ -
500 jiffies;
501
502 /* And terminate BH thread if the frame is "stuck" */
503 if (pending && timeout < 0) {
504 wiphy_warn(priv->hw->wiphy,
505 "Timeout waiting for TX confirm (%d/%d pending, %ld vs %lu).\n",
506 priv->hw_bufs_used, pending,
507 timestamp, jiffies);
508 break;
509 }
510 } else if (!priv->device_can_sleep &&
511 !atomic_read(&priv->recent_scan)) {
512 pr_debug("[BH] Device wakedown. Timeout.\n");
513 cw1200_reg_write_16(priv,
514 ST90TDS_CONTROL_REG_ID, 0);
515 priv->device_can_sleep = true;
516 }
517 goto done;
518 } else if (suspend) {
519 pr_debug("[BH] Device suspend.\n");
520 if (priv->powersave_enabled) {
521 pr_debug("[BH] Device wakedown. Suspend.\n");
522 cw1200_reg_write_16(priv,
523 ST90TDS_CONTROL_REG_ID, 0);
524 priv->device_can_sleep = true;
525 }
526
527 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPENDED);
528 wake_up(&priv->bh_evt_wq);
529 status = wait_event_interruptible(priv->bh_wq,
530 CW1200_BH_RESUME == atomic_read(&priv->bh_suspend));
531 if (status < 0) {
532 wiphy_err(priv->hw->wiphy,
533 "Failed to wait for resume: %ld.\n",
534 status);
535 break;
536 }
537 pr_debug("[BH] Device resume.\n");
538 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
539 wake_up(&priv->bh_evt_wq);
540 atomic_add(1, &priv->bh_rx);
541 goto done;
542 }
543
544 rx:
545 tx += pending_tx;
546 pending_tx = 0;
547
548 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
549 break;
550
551 /* Don't bother trying to rx unless we have data to read */
552 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
553 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
554 if (ret < 0)
555 break;
556 /* Double up here if there's more data.. */
557 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
558 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
559 if (ret < 0)
560 break;
561 }
562 }
563
564 tx:
565 if (tx) {
566 tx = 0;
567
568 BUG_ON(priv->hw_bufs_used > priv->wsm_caps.input_buffers);
569 tx_burst = priv->wsm_caps.input_buffers - priv->hw_bufs_used;
570 tx_allowed = tx_burst > 0;
571
572 if (!tx_allowed) {
573 /* Buffers full. Ensure we process tx
574 * after we handle rx..
575 */
576 pending_tx = tx;
577 goto done_rx;
578 }
579 ret = cw1200_bh_tx_helper(priv, &pending_tx, &tx_burst);
580 if (ret < 0)
581 break;
582 if (ret > 0) /* More to transmit */
583 tx = ret;
584
585 /* Re-read ctrl reg */
586 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
587 break;
588 }
589
590 done_rx:
591 if (priv->bh_error)
592 break;
593 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
594 goto rx;
595 if (tx)
596 goto tx;
597
598 done:
599 /* Re-enable device interrupts */
600 priv->sbus_ops->lock(priv->sbus_priv);
601 __cw1200_irq_enable(priv, 1);
602 priv->sbus_ops->unlock(priv->sbus_priv);
603 }
604
605 /* Explicitly disable device interrupts */
606 priv->sbus_ops->lock(priv->sbus_priv);
607 __cw1200_irq_enable(priv, 0);
608 priv->sbus_ops->unlock(priv->sbus_priv);
609
610 if (!term) {
611 pr_err("[BH] Fatal error, exiting.\n");
612 priv->bh_error = 1;
613 /* TODO: schedule_work(recovery) */
614 }
615 return 0;
616}
diff --git a/drivers/net/wireless/cw1200/bh.h b/drivers/net/wireless/cw1200/bh.h
new file mode 100644
index 000000000000..af6a4853728f
--- /dev/null
+++ b/drivers/net/wireless/cw1200/bh.h
@@ -0,0 +1,28 @@
1/*
2 * Device handling thread interface for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_BH_H
13#define CW1200_BH_H
14
15/* extern */ struct cw1200_common;
16
17int cw1200_register_bh(struct cw1200_common *priv);
18void cw1200_unregister_bh(struct cw1200_common *priv);
19void cw1200_irq_handler(struct cw1200_common *priv);
20void cw1200_bh_wakeup(struct cw1200_common *priv);
21int cw1200_bh_suspend(struct cw1200_common *priv);
22int cw1200_bh_resume(struct cw1200_common *priv);
23/* Must be called from BH thread. */
24void cw1200_enable_powersave(struct cw1200_common *priv,
25 bool enable);
26int wsm_release_tx_buffer(struct cw1200_common *priv, int count);
27
28#endif /* CW1200_BH_H */
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
new file mode 100644
index 000000000000..2aa17ca60ba8
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -0,0 +1,332 @@
1/*
2 * Common private data for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on the mac80211 Prism54 code, which is
8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9 *
10 * Based on the islsm (softmac prism54) driver, which is:
11 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#ifndef CW1200_H
19#define CW1200_H
20
21#include <linux/wait.h>
22#include <linux/version.h>
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25#include <net/mac80211.h>
26
27#include "queue.h"
28#include "wsm.h"
29#include "scan.h"
30#include "txrx.h"
31#include "pm.h"
32
33/* Forward declarations */
34struct sbus_ops;
35struct task_struct;
36struct cw1200_debug_priv;
37struct firmware;
38
39#ifdef CONFIG_CW1200_ETF
40extern int etf_mode;
41extern char *etf_firmware;
42#endif
43
44#define CW1200_MAX_CTRL_FRAME_LEN (0x1000)
45
46#define CW1200_MAX_STA_IN_AP_MODE (5)
47#define CW1200_LINK_ID_AFTER_DTIM (CW1200_MAX_STA_IN_AP_MODE + 1)
48#define CW1200_LINK_ID_UAPSD (CW1200_MAX_STA_IN_AP_MODE + 2)
49#define CW1200_LINK_ID_MAX (CW1200_MAX_STA_IN_AP_MODE + 3)
50#define CW1200_MAX_REQUEUE_ATTEMPTS (5)
51
52#define CW1200_MAX_TID (8)
53
54#define CW1200_BLOCK_ACK_CNT (30)
55#define CW1200_BLOCK_ACK_THLD (800)
56#define CW1200_BLOCK_ACK_HIST (3)
57#define CW1200_BLOCK_ACK_INTERVAL (1 * HZ / CW1200_BLOCK_ACK_HIST)
58
59#define CW1200_JOIN_TIMEOUT (1 * HZ)
60#define CW1200_AUTH_TIMEOUT (5 * HZ)
61
62struct cw1200_ht_info {
63 struct ieee80211_sta_ht_cap ht_cap;
64 enum nl80211_channel_type channel_type;
65 u16 operation_mode;
66};
67
68/* Please keep order */
69enum cw1200_join_status {
70 CW1200_JOIN_STATUS_PASSIVE = 0,
71 CW1200_JOIN_STATUS_MONITOR,
72 CW1200_JOIN_STATUS_JOINING,
73 CW1200_JOIN_STATUS_PRE_STA,
74 CW1200_JOIN_STATUS_STA,
75 CW1200_JOIN_STATUS_IBSS,
76 CW1200_JOIN_STATUS_AP,
77};
78
79enum cw1200_link_status {
80 CW1200_LINK_OFF,
81 CW1200_LINK_RESERVE,
82 CW1200_LINK_SOFT,
83 CW1200_LINK_HARD,
84 CW1200_LINK_RESET,
85 CW1200_LINK_RESET_REMAP,
86};
87
88extern int cw1200_power_mode;
89extern const char * const cw1200_fw_types[];
90
91struct cw1200_link_entry {
92 unsigned long timestamp;
93 enum cw1200_link_status status;
94 enum cw1200_link_status prev_status;
95 u8 mac[ETH_ALEN];
96 u8 buffered[CW1200_MAX_TID];
97 struct sk_buff_head rx_queue;
98};
99
100struct cw1200_common {
101 /* interfaces to the rest of the stack */
102 struct ieee80211_hw *hw;
103 struct ieee80211_vif *vif;
104 struct device *pdev;
105
106 /* Statistics */
107 struct ieee80211_low_level_stats stats;
108
109 /* Our macaddr */
110 u8 mac_addr[ETH_ALEN];
111
112 /* Hardware interface */
113 const struct sbus_ops *sbus_ops;
114 struct sbus_priv *sbus_priv;
115
116 /* Hardware information */
117 enum {
118 HIF_9000_SILICON_VERSATILE = 0,
119 HIF_8601_VERSATILE,
120 HIF_8601_SILICON,
121 } hw_type;
122 enum {
123 CW1200_HW_REV_CUT10 = 10,
124 CW1200_HW_REV_CUT11 = 11,
125 CW1200_HW_REV_CUT20 = 20,
126 CW1200_HW_REV_CUT22 = 22,
127 CW1X60_HW_REV = 40,
128 } hw_revision;
129 int hw_refclk;
130 bool hw_have_5ghz;
131 const struct firmware *sdd;
132 char *sdd_path;
133
134 struct cw1200_debug_priv *debug;
135
136 struct workqueue_struct *workqueue;
137 struct mutex conf_mutex;
138
139 struct cw1200_queue tx_queue[4];
140 struct cw1200_queue_stats tx_queue_stats;
141 int tx_burst_idx;
142
143 /* firmware/hardware info */
144 unsigned int tx_hdr_len;
145
146 /* Radio data */
147 int output_power;
148
149 /* BBP/MAC state */
150 struct ieee80211_rate *rates;
151 struct ieee80211_rate *mcs_rates;
152 struct ieee80211_channel *channel;
153 struct wsm_edca_params edca;
154 struct wsm_tx_queue_params tx_queue_params;
155 struct wsm_mib_association_mode association_mode;
156 struct wsm_set_bss_params bss_params;
157 struct cw1200_ht_info ht_info;
158 struct wsm_set_pm powersave_mode;
159 struct wsm_set_pm firmware_ps_mode;
160 int cqm_rssi_thold;
161 unsigned cqm_rssi_hyst;
162 bool cqm_use_rssi;
163 int cqm_beacon_loss_count;
164 int channel_switch_in_progress;
165 wait_queue_head_t channel_switch_done;
166 u8 long_frame_max_tx_count;
167 u8 short_frame_max_tx_count;
168 int mode;
169 bool enable_beacon;
170 int beacon_int;
171 bool listening;
172 struct wsm_rx_filter rx_filter;
173 struct wsm_mib_multicast_filter multicast_filter;
174 bool has_multicast_subscription;
175 bool disable_beacon_filter;
176 struct work_struct update_filtering_work;
177 struct work_struct set_beacon_wakeup_period_work;
178
179 u8 ba_rx_tid_mask;
180 u8 ba_tx_tid_mask;
181
182 struct cw1200_pm_state pm_state;
183
184 struct wsm_p2p_ps_modeinfo p2p_ps_modeinfo;
185 struct wsm_uapsd_info uapsd_info;
186 bool setbssparams_done;
187 bool bt_present;
188 u8 conf_listen_interval;
189 u32 listen_interval;
190 u32 erp_info;
191 u32 rts_threshold;
192
193 /* BH */
194 atomic_t bh_rx;
195 atomic_t bh_tx;
196 atomic_t bh_term;
197 atomic_t bh_suspend;
198
199 struct workqueue_struct *bh_workqueue;
200 struct work_struct bh_work;
201
202 int bh_error;
203 wait_queue_head_t bh_wq;
204 wait_queue_head_t bh_evt_wq;
205 u8 buf_id_tx;
206 u8 buf_id_rx;
207 u8 wsm_rx_seq;
208 u8 wsm_tx_seq;
209 int hw_bufs_used;
210 bool powersave_enabled;
211 bool device_can_sleep;
212
213 /* Scan status */
214 struct cw1200_scan scan;
215 /* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid
216 * FW issue with sleeping/waking up. */
217 atomic_t recent_scan;
218 struct delayed_work clear_recent_scan_work;
219
220 /* WSM */
221 struct wsm_startup_ind wsm_caps;
222 struct mutex wsm_cmd_mux;
223 struct wsm_buf wsm_cmd_buf;
224 struct wsm_cmd wsm_cmd;
225 wait_queue_head_t wsm_cmd_wq;
226 wait_queue_head_t wsm_startup_done;
227 int firmware_ready;
228 atomic_t tx_lock;
229
230 /* WSM debug */
231 int wsm_enable_wsm_dumps;
232
233 /* WSM Join */
234 enum cw1200_join_status join_status;
235 u32 pending_frame_id;
236 bool join_pending;
237 struct delayed_work join_timeout;
238 struct work_struct unjoin_work;
239 struct work_struct join_complete_work;
240 int join_complete_status;
241 int join_dtim_period;
242 bool delayed_unjoin;
243
244 /* TX/RX and security */
245 s8 wep_default_key_id;
246 struct work_struct wep_key_work;
247 u32 key_map;
248 struct wsm_add_key keys[WSM_KEY_MAX_INDEX + 1];
249
250 /* AP powersave */
251 u32 link_id_map;
252 struct cw1200_link_entry link_id_db[CW1200_MAX_STA_IN_AP_MODE];
253 struct work_struct link_id_work;
254 struct delayed_work link_id_gc_work;
255 u32 sta_asleep_mask;
256 u32 pspoll_mask;
257 bool aid0_bit_set;
258 spinlock_t ps_state_lock; /* Protect power save state */
259 bool buffered_multicasts;
260 bool tx_multicast;
261 struct work_struct set_tim_work;
262 struct work_struct set_cts_work;
263 struct work_struct multicast_start_work;
264 struct work_struct multicast_stop_work;
265 struct timer_list mcast_timeout;
266
267 /* WSM events and CQM implementation */
268 spinlock_t event_queue_lock; /* Protect event queue */
269 struct list_head event_queue;
270 struct work_struct event_handler;
271
272 struct delayed_work bss_loss_work;
273 spinlock_t bss_loss_lock; /* Protect BSS loss state */
274 int bss_loss_state;
275 int bss_loss_confirm_id;
276 int delayed_link_loss;
277 struct work_struct bss_params_work;
278
279 /* TX rate policy cache */
280 struct tx_policy_cache tx_policy_cache;
281 struct work_struct tx_policy_upload_work;
282
283 /* legacy PS mode switch in suspend */
284 int ps_mode_switch_in_progress;
285 wait_queue_head_t ps_mode_switch_done;
286
287 /* Workaround for WFD testcase 6.1.10*/
288 struct work_struct linkid_reset_work;
289 u8 action_frame_sa[ETH_ALEN];
290 u8 action_linkid;
291
292#ifdef CONFIG_CW1200_ETF
293 struct sk_buff_head etf_q;
294#endif
295};
296
297struct cw1200_sta_priv {
298 int link_id;
299};
300
301/* interfaces for the drivers */
302int cw1200_core_probe(const struct sbus_ops *sbus_ops,
303 struct sbus_priv *sbus,
304 struct device *pdev,
305 struct cw1200_common **pself,
306 int ref_clk, const u8 *macaddr,
307 const char *sdd_path, bool have_5ghz);
308void cw1200_core_release(struct cw1200_common *self);
309
310#define FWLOAD_BLOCK_SIZE (1024)
311
312static inline int cw1200_is_ht(const struct cw1200_ht_info *ht_info)
313{
314 return ht_info->channel_type != NL80211_CHAN_NO_HT;
315}
316
317static inline int cw1200_ht_greenfield(const struct cw1200_ht_info *ht_info)
318{
319 return cw1200_is_ht(ht_info) &&
320 (ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
321 !(ht_info->operation_mode &
322 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
323}
324
325static inline int cw1200_ht_ampdu_density(const struct cw1200_ht_info *ht_info)
326{
327 if (!cw1200_is_ht(ht_info))
328 return 0;
329 return ht_info->ht_cap.ampdu_density;
330}
331
332#endif /* CW1200_H */
diff --git a/drivers/net/wireless/cw1200/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
new file mode 100644
index 000000000000..a5ada0eda1dd
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200_sagrad.c
@@ -0,0 +1,145 @@
1/*
2 * Platform glue data for ST-Ericsson CW1200 driver
3 *
4 * Copyright (c) 2013, Sagrad, Inc
5 * Author: Solomon Peachy <speachy@sagrad.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/cw1200_platform.h>
14
15MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
16MODULE_DESCRIPTION("ST-Ericsson CW1200 Platform glue driver");
17MODULE_LICENSE("GPL");
18
19/* Define just one of these. Feel free to customize as needed */
20#define SAGRAD_1091_1098_EVK_SDIO
21/* #define SAGRAD_1091_1098_EVK_SPI */
22
23#ifdef SAGRAD_1091_1098_EVK_SDIO
24#if 0
25static struct resource cw1200_href_resources[] = {
26 {
27 .start = 215, /* fix me as appropriate */
28 .end = 215, /* ditto */
29 .flags = IORESOURCE_IO,
30 .name = "cw1200_wlan_reset",
31 },
32 {
33 .start = 216, /* fix me as appropriate */
34 .end = 216, /* ditto */
35 .flags = IORESOURCE_IO,
36 .name = "cw1200_wlan_powerup",
37 },
38 {
39 .start = NOMADIK_GPIO_TO_IRQ(216), /* fix me as appropriate */
40 .end = NOMADIK_GPIO_TO_IRQ(216), /* ditto */
41 .flags = IORESOURCE_IRQ,
42 .name = "cw1200_wlan_irq",
43 },
44};
45#endif
46
47static int cw1200_power_ctrl(const struct cw1200_platform_data_sdio *pdata,
48 bool enable)
49{
50 /* Control 3v3 and 1v8 to hardware as appropriate */
51 /* Note this is not needed if it's controlled elsewhere or always on */
52
53 /* May require delay for power to stabilize */
54 return 0;
55}
56
57static int cw1200_clk_ctrl(const struct cw1200_platform_data_sdio *pdata,
58 bool enable)
59{
60 /* Turn CLK_32K off and on as appropriate. */
61 /* Note this is not needed if it's always on */
62
63 /* May require delay for clock to stabilize */
64 return 0;
65}
66
67static struct cw1200_platform_data_sdio cw1200_platform_data = {
68 .ref_clk = 38400,
69 .have_5ghz = false,
70#if 0
71 .reset = &cw1200_href_resources[0],
72 .powerup = &cw1200_href_resources[1],
73 .irq = &cw1200_href_resources[2],
74#endif
75 .power_ctrl = cw1200_power_ctrl,
76 .clk_ctrl = cw1200_clk_ctrl,
77/* .macaddr = ??? */
78 .sdd_file = "sdd_sagrad_1091_1098.bin",
79};
80#endif
81
82#ifdef SAGRAD_1091_1098_EVK_SPI
83/* Note that this is an example of integrating into your board support file */
84static struct resource cw1200_href_resources[] = {
85 {
86 .start = GPIO_RF_RESET,
87 .end = GPIO_RF_RESET,
88 .flags = IORESOURCE_IO,
89 .name = "cw1200_wlan_reset",
90 },
91 {
92 .start = GPIO_RF_POWERUP,
93 .end = GPIO_RF_POWERUP,
94 .flags = IORESOURCE_IO,
95 .name = "cw1200_wlan_powerup",
96 },
97};
98
99static int cw1200_power_ctrl(const struct cw1200_platform_data_spi *pdata,
100 bool enable)
101{
102 /* Control 3v3 and 1v8 to hardware as appropriate */
103 /* Note this is not needed if it's controlled elsewhere or always on */
104
105 /* May require delay for power to stabilize */
106 return 0;
107}
108static int cw1200_clk_ctrl(const struct cw1200_platform_data_spi *pdata,
109 bool enable)
110{
111 /* Turn CLK_32K off and on as appropriate. */
112 /* Note this is not needed if it's always on */
113
114 /* May require delay for clock to stabilize */
115 return 0;
116}
117
118static struct cw1200_platform_data_spi cw1200_platform_data = {
119 .ref_clk = 38400,
120 .spi_bits_per_word = 16,
121 .reset = &cw1200_href_resources[0],
122 .powerup = &cw1200_href_resources[1],
123 .power_ctrl = cw1200_power_ctrl,
124 .clk_ctrl = cw1200_clk_ctrl,
125/* .macaddr = ??? */
126 .sdd_file = "sdd_sagrad_1091_1098.bin",
127};
128static struct spi_board_info myboard_spi_devices[] __initdata = {
129 {
130 .modalias = "cw1200_wlan_spi",
131 .max_speed_hz = 10000000, /* 52MHz Max */
132 .bus_num = 0,
133 .irq = WIFI_IRQ,
134 .platform_data = &cw1200_platform_data,
135 .chip_select = 0,
136 },
137};
138#endif
139
140
141const void *cw1200_get_platform_data(void)
142{
143 return &cw1200_platform_data;
144}
145EXPORT_SYMBOL_GPL(cw1200_get_platform_data);
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
new file mode 100644
index 000000000000..f6e22192d80a
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -0,0 +1,409 @@
1/*
2 * Mac80211 SDIO driver for ST-Ericsson CW1200 device
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/version.h>
13#include <linux/module.h>
14#include <linux/gpio.h>
15#include <linux/delay.h>
16#include <linux/mmc/host.h>
17#include <linux/mmc/sdio_func.h>
18#include <linux/mmc/card.h>
19#include <linux/mmc/sdio.h>
20#include <net/mac80211.h>
21
22#include "cw1200.h"
23#include "sbus.h"
24#include <linux/cw1200_platform.h>
25#include "hwio.h"
26
27MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
28MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SDIO driver");
29MODULE_LICENSE("GPL");
30
31#define SDIO_BLOCK_SIZE (512)
32
33struct sbus_priv {
34 struct sdio_func *func;
35 struct cw1200_common *core;
36 const struct cw1200_platform_data_sdio *pdata;
37};
38
39#ifndef SDIO_VENDOR_ID_STE
40#define SDIO_VENDOR_ID_STE 0x0020
41#endif
42
43#ifndef SDIO_DEVICE_ID_STE_CW1200
44#define SDIO_DEVICE_ID_STE_CW1200 0x2280
45#endif
46
47static const struct sdio_device_id cw1200_sdio_ids[] = {
48 { SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) },
49 { /* end: all zeroes */ },
50};
51
52/* sbus_ops implemetation */
53
54static int cw1200_sdio_memcpy_fromio(struct sbus_priv *self,
55 unsigned int addr,
56 void *dst, int count)
57{
58 return sdio_memcpy_fromio(self->func, dst, addr, count);
59}
60
61static int cw1200_sdio_memcpy_toio(struct sbus_priv *self,
62 unsigned int addr,
63 const void *src, int count)
64{
65 return sdio_memcpy_toio(self->func, addr, (void *)src, count);
66}
67
68static void cw1200_sdio_lock(struct sbus_priv *self)
69{
70 sdio_claim_host(self->func);
71}
72
73static void cw1200_sdio_unlock(struct sbus_priv *self)
74{
75 sdio_release_host(self->func);
76}
77
78static void cw1200_sdio_irq_handler(struct sdio_func *func)
79{
80 struct sbus_priv *self = sdio_get_drvdata(func);
81
82 /* note: sdio_host already claimed here. */
83 if (self->core)
84 cw1200_irq_handler(self->core);
85}
86
87static irqreturn_t cw1200_gpio_hardirq(int irq, void *dev_id)
88{
89 return IRQ_WAKE_THREAD;
90}
91
92static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
93{
94 struct sbus_priv *self = dev_id;
95
96 if (self->core) {
97 sdio_claim_host(self->func);
98 cw1200_irq_handler(self->core);
99 sdio_release_host(self->func);
100 return IRQ_HANDLED;
101 } else {
102 return IRQ_NONE;
103 }
104}
105
106static int cw1200_request_irq(struct sbus_priv *self)
107{
108 int ret;
109 const struct resource *irq = self->pdata->irq;
110 u8 cccr;
111
112 cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret);
113 if (WARN_ON(ret))
114 goto err;
115
116 /* Master interrupt enable ... */
117 cccr |= BIT(0);
118
119 /* ... for our function */
120 cccr |= BIT(self->func->num);
121
122 sdio_f0_writeb(self->func, cccr, SDIO_CCCR_IENx, &ret);
123 if (WARN_ON(ret))
124 goto err;
125
126 ret = enable_irq_wake(irq->start);
127 if (WARN_ON(ret))
128 goto err;
129
130 /* Request the IRQ */
131 ret = request_threaded_irq(irq->start, cw1200_gpio_hardirq,
132 cw1200_gpio_irq,
133 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
134 irq->name, self);
135 if (WARN_ON(ret))
136 goto err;
137
138 return 0;
139
140err:
141 return ret;
142}
143
144static int cw1200_sdio_irq_subscribe(struct sbus_priv *self)
145{
146 int ret = 0;
147
148 pr_debug("SW IRQ subscribe\n");
149 sdio_claim_host(self->func);
150 if (self->pdata->irq)
151 ret = cw1200_request_irq(self);
152 else
153 ret = sdio_claim_irq(self->func, cw1200_sdio_irq_handler);
154
155 sdio_release_host(self->func);
156 return ret;
157}
158
159static int cw1200_sdio_irq_unsubscribe(struct sbus_priv *self)
160{
161 int ret = 0;
162
163 pr_debug("SW IRQ unsubscribe\n");
164
165 if (self->pdata->irq) {
166 disable_irq_wake(self->pdata->irq->start);
167 free_irq(self->pdata->irq->start, self);
168 } else {
169 sdio_claim_host(self->func);
170 ret = sdio_release_irq(self->func);
171 sdio_release_host(self->func);
172 }
173 return ret;
174}
175
176static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
177{
178 const struct resource *reset = pdata->reset;
179
180 if (reset) {
181 gpio_set_value(reset->start, 0);
182 msleep(30); /* Min is 2 * CLK32K cycles */
183 gpio_free(reset->start);
184 }
185
186 if (pdata->power_ctrl)
187 pdata->power_ctrl(pdata, false);
188 if (pdata->clk_ctrl)
189 pdata->clk_ctrl(pdata, false);
190
191 return 0;
192}
193
194static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
195{
196 const struct resource *reset = pdata->reset;
197 const struct resource *powerup = pdata->reset;
198
199 /* Ensure I/Os are pulled low */
200 if (reset) {
201 gpio_request(reset->start, reset->name);
202 gpio_direction_output(reset->start, 0);
203 }
204 if (powerup) {
205 gpio_request(powerup->start, powerup->name);
206 gpio_direction_output(powerup->start, 0);
207 }
208 if (reset || powerup)
209 msleep(50); /* Settle time */
210
211 /* Enable 3v3 and 1v8 to hardware */
212 if (pdata->power_ctrl) {
213 if (pdata->power_ctrl(pdata, true)) {
214 pr_err("power_ctrl() failed!\n");
215 return -1;
216 }
217 }
218
219 /* Enable CLK32K */
220 if (pdata->clk_ctrl) {
221 if (pdata->clk_ctrl(pdata, true)) {
222 pr_err("clk_ctrl() failed!\n");
223 return -1;
224 }
225 msleep(10); /* Delay until clock is stable for 2 cycles */
226 }
227
228 /* Enable POWERUP signal */
229 if (powerup) {
230 gpio_set_value(powerup->start, 1);
231 msleep(250); /* or more..? */
232 }
233 /* Enable RSTn signal */
234 if (reset) {
235 gpio_set_value(reset->start, 1);
236 msleep(50); /* Or more..? */
237 }
238 return 0;
239}
240
241static size_t cw1200_sdio_align_size(struct sbus_priv *self, size_t size)
242{
243 if (self->pdata->no_nptb)
244 size = round_up(size, SDIO_BLOCK_SIZE);
245 else
246 size = sdio_align_size(self->func, size);
247
248 return size;
249}
250
251static int cw1200_sdio_pm(struct sbus_priv *self, bool suspend)
252{
253 int ret = 0;
254
255 if (self->pdata->irq)
256 ret = irq_set_irq_wake(self->pdata->irq->start, suspend);
257 return ret;
258}
259
260static struct sbus_ops cw1200_sdio_sbus_ops = {
261 .sbus_memcpy_fromio = cw1200_sdio_memcpy_fromio,
262 .sbus_memcpy_toio = cw1200_sdio_memcpy_toio,
263 .lock = cw1200_sdio_lock,
264 .unlock = cw1200_sdio_unlock,
265 .align_size = cw1200_sdio_align_size,
266 .power_mgmt = cw1200_sdio_pm,
267};
268
269/* Probe Function to be called by SDIO stack when device is discovered */
270static int cw1200_sdio_probe(struct sdio_func *func,
271 const struct sdio_device_id *id)
272{
273 struct sbus_priv *self;
274 int status;
275
276 pr_info("cw1200_wlan_sdio: Probe called\n");
277
278 /* We are only able to handle the wlan function */
279 if (func->num != 0x01)
280 return -ENODEV;
281
282 self = kzalloc(sizeof(*self), GFP_KERNEL);
283 if (!self) {
284 pr_err("Can't allocate SDIO sbus_priv.\n");
285 return -ENOMEM;
286 }
287
288 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
289
290 self->pdata = cw1200_get_platform_data();
291 self->func = func;
292 sdio_set_drvdata(func, self);
293 sdio_claim_host(func);
294 sdio_enable_func(func);
295 sdio_release_host(func);
296
297 status = cw1200_sdio_irq_subscribe(self);
298
299 status = cw1200_core_probe(&cw1200_sdio_sbus_ops,
300 self, &func->dev, &self->core,
301 self->pdata->ref_clk,
302 self->pdata->macaddr,
303 self->pdata->sdd_file,
304 self->pdata->have_5ghz);
305 if (status) {
306 cw1200_sdio_irq_unsubscribe(self);
307 sdio_claim_host(func);
308 sdio_disable_func(func);
309 sdio_release_host(func);
310 sdio_set_drvdata(func, NULL);
311 kfree(self);
312 }
313
314 return status;
315}
316
317/* Disconnect Function to be called by SDIO stack when
318 * device is disconnected */
319static void cw1200_sdio_disconnect(struct sdio_func *func)
320{
321 struct sbus_priv *self = sdio_get_drvdata(func);
322
323 if (self) {
324 cw1200_sdio_irq_unsubscribe(self);
325 if (self->core) {
326 cw1200_core_release(self->core);
327 self->core = NULL;
328 }
329 sdio_claim_host(func);
330 sdio_disable_func(func);
331 sdio_release_host(func);
332 sdio_set_drvdata(func, NULL);
333 kfree(self);
334 }
335}
336
337static int cw1200_sdio_suspend(struct device *dev)
338{
339 int ret;
340 struct sdio_func *func = dev_to_sdio_func(dev);
341 struct sbus_priv *self = sdio_get_drvdata(func);
342
343 if (!cw1200_can_suspend(self->core))
344 return -EAGAIN;
345
346 /* Notify SDIO that CW1200 will remain powered during suspend */
347 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
348 if (ret)
349 pr_err("Error setting SDIO pm flags: %i\n", ret);
350
351 return ret;
352}
353
354static int cw1200_sdio_resume(struct device *dev)
355{
356 return 0;
357}
358
359static const struct dev_pm_ops cw1200_pm_ops = {
360 .suspend = cw1200_sdio_suspend,
361 .resume = cw1200_sdio_resume,
362};
363
364static struct sdio_driver sdio_driver = {
365 .name = "cw1200_wlan_sdio",
366 .id_table = cw1200_sdio_ids,
367 .probe = cw1200_sdio_probe,
368 .remove = cw1200_sdio_disconnect,
369 .drv = {
370 .pm = &cw1200_pm_ops,
371 }
372};
373
374/* Init Module function -> Called by insmod */
375static int __init cw1200_sdio_init(void)
376{
377 const struct cw1200_platform_data_sdio *pdata;
378 int ret;
379
380 pdata = cw1200_get_platform_data();
381
382 if (cw1200_sdio_on(pdata)) {
383 ret = -1;
384 goto err;
385 }
386
387 ret = sdio_register_driver(&sdio_driver);
388 if (ret)
389 goto err;
390
391 return 0;
392
393err:
394 cw1200_sdio_off(pdata);
395 return ret;
396}
397
398/* Called at Driver Unloading */
399static void __exit cw1200_sdio_exit(void)
400{
401 const struct cw1200_platform_data_sdio *pdata;
402 pdata = cw1200_get_platform_data();
403 sdio_unregister_driver(&sdio_driver);
404 cw1200_sdio_off(pdata);
405}
406
407
408module_init(cw1200_sdio_init);
409module_exit(cw1200_sdio_exit);
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
new file mode 100644
index 000000000000..04af68534854
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -0,0 +1,480 @@
1/*
2 * Mac80211 SPI driver for ST-Ericsson CW1200 device
3 *
4 * Copyright (c) 2011, Sagrad Inc.
5 * Author: Solomon Peachy <speachy@sagrad.com>
6 *
7 * Based on cw1200_sdio.c
8 * Copyright (c) 2010, ST-Ericsson
9 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/version.h>
17#include <linux/module.h>
18#include <linux/gpio.h>
19#include <linux/delay.h>
20#include <linux/spinlock.h>
21#include <linux/interrupt.h>
22#include <net/mac80211.h>
23
24#include <linux/spi/spi.h>
25#include <linux/device.h>
26
27#include "cw1200.h"
28#include "sbus.h"
29#include <linux/cw1200_platform.h>
30#include "hwio.h"
31
32MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
33MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SPI driver");
34MODULE_LICENSE("GPL");
35MODULE_ALIAS("spi:cw1200_wlan_spi");
36
37/* #define SPI_DEBUG */
38
39struct sbus_priv {
40 struct spi_device *func;
41 struct cw1200_common *core;
42 const struct cw1200_platform_data_spi *pdata;
43 spinlock_t lock; /* Serialize all bus operations */
44 int claimed;
45};
46
47#define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
48#define SET_WRITE 0x7FFF /* usage: and operation */
49#define SET_READ 0x8000 /* usage: or operation */
50
51/*
52 Notes on byte ordering:
53 LE: B0 B1 B2 B3
54 BE: B3 B2 B1 B0
55
56 Hardware expects 32-bit data to be written as 16-bit BE words:
57
58 B1 B0 B3 B2
59
60*/
61
62static int cw1200_spi_memcpy_fromio(struct sbus_priv *self,
63 unsigned int addr,
64 void *dst, int count)
65{
66 int ret, i;
67 uint16_t regaddr;
68 struct spi_message m;
69
70 struct spi_transfer t_addr = {
71 .tx_buf = &regaddr,
72 .len = sizeof(regaddr),
73 };
74 struct spi_transfer t_msg = {
75 .rx_buf = dst,
76 .len = count,
77 };
78
79 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
80 regaddr |= SET_READ;
81 regaddr |= (count>>1);
82 regaddr = cpu_to_le16(regaddr);
83
84#ifdef SPI_DEBUG
85 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr,
86 le16_to_cpu(regaddr));
87#endif
88
89#if defined(__LITTLE_ENDIAN)
90 /* We have to byteswap if the SPI bus is limited to 8b operation */
91 if (self->func->bits_per_word == 8)
92#endif
93 regaddr = swab16(regaddr);
94
95 spi_message_init(&m);
96 spi_message_add_tail(&t_addr, &m);
97 spi_message_add_tail(&t_msg, &m);
98 ret = spi_sync(self->func, &m);
99
100#ifdef SPI_DEBUG
101 pr_info("READ : ");
102 for (i = 0; i < t_addr.len; i++)
103 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
104 printk(" : ");
105 for (i = 0; i < t_msg.len; i++)
106 printk("%02x ", ((u8 *)t_msg.rx_buf)[i]);
107 printk("\n");
108#endif
109
110#if defined(__LITTLE_ENDIAN)
111 /* We have to byteswap if the SPI bus is limited to 8b operation */
112 if (self->func->bits_per_word == 8)
113#endif
114 {
115 uint16_t *buf = (uint16_t *)dst;
116 for (i = 0; i < ((count + 1) >> 1); i++)
117 buf[i] = swab16(buf[i]);
118 }
119
120 return ret;
121}
122
123static int cw1200_spi_memcpy_toio(struct sbus_priv *self,
124 unsigned int addr,
125 const void *src, int count)
126{
127 int rval, i;
128 uint16_t regaddr;
129 struct spi_transfer t_addr = {
130 .tx_buf = &regaddr,
131 .len = sizeof(regaddr),
132 };
133 struct spi_transfer t_msg = {
134 .tx_buf = src,
135 .len = count,
136 };
137 struct spi_message m;
138
139 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
140 regaddr &= SET_WRITE;
141 regaddr |= (count>>1);
142 regaddr = cpu_to_le16(regaddr);
143
144#ifdef SPI_DEBUG
145 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr,
146 le16_to_cpu(regaddr));
147#endif
148
149#if defined(__LITTLE_ENDIAN)
150 /* We have to byteswap if the SPI bus is limited to 8b operation */
151 if (self->func->bits_per_word == 8)
152#endif
153 {
154 uint16_t *buf = (uint16_t *)src;
155 regaddr = swab16(regaddr);
156 for (i = 0; i < ((count + 1) >> 1); i++)
157 buf[i] = swab16(buf[i]);
158 }
159
160#ifdef SPI_DEBUG
161 pr_info("WRITE: ");
162 for (i = 0; i < t_addr.len; i++)
163 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
164 printk(" : ");
165 for (i = 0; i < t_msg.len; i++)
166 printk("%02x ", ((u8 *)t_msg.tx_buf)[i]);
167 printk("\n");
168#endif
169
170 spi_message_init(&m);
171 spi_message_add_tail(&t_addr, &m);
172 spi_message_add_tail(&t_msg, &m);
173 rval = spi_sync(self->func, &m);
174
175#ifdef SPI_DEBUG
176 pr_info("WROTE: %d\n", m.actual_length);
177#endif
178
179#if defined(__LITTLE_ENDIAN)
180 /* We have to byteswap if the SPI bus is limited to 8b operation */
181 if (self->func->bits_per_word == 8)
182#endif
183 {
184 uint16_t *buf = (uint16_t *)src;
185 for (i = 0; i < ((count + 1) >> 1); i++)
186 buf[i] = swab16(buf[i]);
187 }
188 return rval;
189}
190
191static void cw1200_spi_lock(struct sbus_priv *self)
192{
193 unsigned long flags;
194
195 might_sleep();
196
197 spin_lock_irqsave(&self->lock, flags);
198 while (1) {
199 set_current_state(TASK_UNINTERRUPTIBLE);
200 if (!self->claimed)
201 break;
202 spin_unlock_irqrestore(&self->lock, flags);
203 schedule();
204 spin_lock_irqsave(&self->lock, flags);
205 }
206 set_current_state(TASK_RUNNING);
207 self->claimed = 1;
208 spin_unlock_irqrestore(&self->lock, flags);
209
210 return;
211}
212
213static void cw1200_spi_unlock(struct sbus_priv *self)
214{
215 unsigned long flags;
216
217 spin_lock_irqsave(&self->lock, flags);
218 self->claimed = 0;
219 spin_unlock_irqrestore(&self->lock, flags);
220 return;
221}
222
223static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
224{
225 struct sbus_priv *self = dev_id;
226
227 if (self->core) {
228 cw1200_irq_handler(self->core);
229 return IRQ_HANDLED;
230 } else {
231 return IRQ_NONE;
232 }
233}
234
235static int cw1200_spi_irq_subscribe(struct sbus_priv *self)
236{
237 int ret;
238
239 pr_debug("SW IRQ subscribe\n");
240
241 ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler,
242 IRQF_TRIGGER_HIGH,
243 "cw1200_wlan_irq", self);
244 if (WARN_ON(ret < 0))
245 goto exit;
246
247 ret = enable_irq_wake(self->func->irq);
248 if (WARN_ON(ret))
249 goto free_irq;
250
251 return 0;
252
253free_irq:
254 free_irq(self->func->irq, self);
255exit:
256 return ret;
257}
258
259static int cw1200_spi_irq_unsubscribe(struct sbus_priv *self)
260{
261 int ret = 0;
262
263 pr_debug("SW IRQ unsubscribe\n");
264 disable_irq_wake(self->func->irq);
265 free_irq(self->func->irq, self);
266
267 return ret;
268}
269
270static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
271{
272 const struct resource *reset = pdata->reset;
273
274 if (reset) {
275 gpio_set_value(reset->start, 0);
276 msleep(30); /* Min is 2 * CLK32K cycles */
277 gpio_free(reset->start);
278 }
279
280 if (pdata->power_ctrl)
281 pdata->power_ctrl(pdata, false);
282 if (pdata->clk_ctrl)
283 pdata->clk_ctrl(pdata, false);
284
285 return 0;
286}
287
288static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
289{
290 const struct resource *reset = pdata->reset;
291 const struct resource *powerup = pdata->reset;
292
293 /* Ensure I/Os are pulled low */
294 if (reset) {
295 gpio_request(reset->start, reset->name);
296 gpio_direction_output(reset->start, 0);
297 }
298 if (powerup) {
299 gpio_request(powerup->start, powerup->name);
300 gpio_direction_output(powerup->start, 0);
301 }
302 if (reset || powerup)
303 msleep(10); /* Settle time? */
304
305 /* Enable 3v3 and 1v8 to hardware */
306 if (pdata->power_ctrl) {
307 if (pdata->power_ctrl(pdata, true)) {
308 pr_err("power_ctrl() failed!\n");
309 return -1;
310 }
311 }
312
313 /* Enable CLK32K */
314 if (pdata->clk_ctrl) {
315 if (pdata->clk_ctrl(pdata, true)) {
316 pr_err("clk_ctrl() failed!\n");
317 return -1;
318 }
319 msleep(10); /* Delay until clock is stable for 2 cycles */
320 }
321
322 /* Enable POWERUP signal */
323 if (powerup) {
324 gpio_set_value(powerup->start, 1);
325 msleep(250); /* or more..? */
326 }
327 /* Enable RSTn signal */
328 if (reset) {
329 gpio_set_value(reset->start, 1);
330 msleep(50); /* Or more..? */
331 }
332 return 0;
333}
334
335static size_t cw1200_spi_align_size(struct sbus_priv *self, size_t size)
336{
337 return size & 1 ? size + 1 : size;
338}
339
340static int cw1200_spi_pm(struct sbus_priv *self, bool suspend)
341{
342 return irq_set_irq_wake(self->func->irq, suspend);
343}
344
345static struct sbus_ops cw1200_spi_sbus_ops = {
346 .sbus_memcpy_fromio = cw1200_spi_memcpy_fromio,
347 .sbus_memcpy_toio = cw1200_spi_memcpy_toio,
348 .lock = cw1200_spi_lock,
349 .unlock = cw1200_spi_unlock,
350 .align_size = cw1200_spi_align_size,
351 .power_mgmt = cw1200_spi_pm,
352};
353
354/* Probe Function to be called by SPI stack when device is discovered */
355static int cw1200_spi_probe(struct spi_device *func)
356{
357 const struct cw1200_platform_data_spi *plat_data =
358 func->dev.platform_data;
359 struct sbus_priv *self;
360 int status;
361
362 /* Sanity check speed */
363 if (func->max_speed_hz > 52000000)
364 func->max_speed_hz = 52000000;
365 if (func->max_speed_hz < 1000000)
366 func->max_speed_hz = 1000000;
367
368 /* Fix up transfer size */
369 if (plat_data->spi_bits_per_word)
370 func->bits_per_word = plat_data->spi_bits_per_word;
371 if (!func->bits_per_word)
372 func->bits_per_word = 16;
373
374 /* And finally.. */
375 func->mode = SPI_MODE_0;
376
377 pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n",
378 func->chip_select, func->mode, func->bits_per_word,
379 func->max_speed_hz);
380
381 if (cw1200_spi_on(plat_data)) {
382 pr_err("spi_on() failed!\n");
383 return -1;
384 }
385
386 if (spi_setup(func)) {
387 pr_err("spi_setup() failed!\n");
388 return -1;
389 }
390
391 self = kzalloc(sizeof(*self), GFP_KERNEL);
392 if (!self) {
393 pr_err("Can't allocate SPI sbus_priv.");
394 return -ENOMEM;
395 }
396
397 self->pdata = plat_data;
398 self->func = func;
399 spin_lock_init(&self->lock);
400
401 spi_set_drvdata(func, self);
402
403 status = cw1200_spi_irq_subscribe(self);
404
405 status = cw1200_core_probe(&cw1200_spi_sbus_ops,
406 self, &func->dev, &self->core,
407 self->pdata->ref_clk,
408 self->pdata->macaddr,
409 self->pdata->sdd_file,
410 self->pdata->have_5ghz);
411
412 if (status) {
413 cw1200_spi_irq_unsubscribe(self);
414 cw1200_spi_off(plat_data);
415 kfree(self);
416 }
417
418 return status;
419}
420
421/* Disconnect Function to be called by SPI stack when device is disconnected */
422static int cw1200_spi_disconnect(struct spi_device *func)
423{
424 struct sbus_priv *self = spi_get_drvdata(func);
425
426 if (self) {
427 cw1200_spi_irq_unsubscribe(self);
428 if (self->core) {
429 cw1200_core_release(self->core);
430 self->core = NULL;
431 }
432 kfree(self);
433 }
434 cw1200_spi_off(func->dev.platform_data);
435
436 return 0;
437}
438
439static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
440{
441 struct sbus_priv *self = spi_get_drvdata(to_spi_device(dev));
442
443 if (!cw1200_can_suspend(self->core))
444 return -EAGAIN;
445
446 /* XXX notify host that we have to keep CW1200 powered on? */
447 return 0;
448}
449
450static int cw1200_spi_resume(struct device *dev)
451{
452 return 0;
453}
454
455static struct spi_driver spi_driver = {
456 .probe = cw1200_spi_probe,
457 .remove = cw1200_spi_disconnect,
458 .driver = {
459 .name = "cw1200_wlan_spi",
460 .bus = &spi_bus_type,
461 .owner = THIS_MODULE,
462 .suspend = cw1200_spi_suspend,
463 .resume = cw1200_spi_resume,
464 },
465};
466
467/* Init Module function -> Called by insmod */
468static int __init cw1200_spi_init(void)
469{
470 return spi_register_driver(&spi_driver);
471}
472
473/* Called at Driver Unloading */
474static void __exit cw1200_spi_exit(void)
475{
476 spi_unregister_driver(&spi_driver);
477}
478
479module_init(cw1200_spi_init);
480module_exit(cw1200_spi_exit);
diff --git a/drivers/net/wireless/cw1200/debug.c b/drivers/net/wireless/cw1200/debug.c
new file mode 100644
index 000000000000..b815181802e0
--- /dev/null
+++ b/drivers/net/wireless/cw1200/debug.c
@@ -0,0 +1,664 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 * DebugFS code
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/debugfs.h>
15#include <linux/seq_file.h>
16#include "cw1200.h"
17#include "debug.h"
18#include "fwio.h"
19
20/* join_status */
21static const char * const cw1200_debug_join_status[] = {
22 "passive",
23 "monitor",
24 "station (joining)",
25 "station (not authenticated yet)",
26 "station",
27 "adhoc",
28 "access point",
29};
30
31/* WSM_JOIN_PREAMBLE_... */
32static const char * const cw1200_debug_preamble[] = {
33 "long",
34 "short",
35 "long on 1 and 2 Mbps",
36};
37
38
39static const char * const cw1200_debug_link_id[] = {
40 "OFF",
41 "REQ",
42 "SOFT",
43 "HARD",
44};
45
46static const char *cw1200_debug_mode(int mode)
47{
48 switch (mode) {
49 case NL80211_IFTYPE_UNSPECIFIED:
50 return "unspecified";
51 case NL80211_IFTYPE_MONITOR:
52 return "monitor";
53 case NL80211_IFTYPE_STATION:
54 return "station";
55 case NL80211_IFTYPE_ADHOC:
56 return "adhoc";
57 case NL80211_IFTYPE_MESH_POINT:
58 return "mesh point";
59 case NL80211_IFTYPE_AP:
60 return "access point";
61 case NL80211_IFTYPE_P2P_CLIENT:
62 return "p2p client";
63 case NL80211_IFTYPE_P2P_GO:
64 return "p2p go";
65 default:
66 return "unsupported";
67 }
68}
69
70static void cw1200_queue_status_show(struct seq_file *seq,
71 struct cw1200_queue *q)
72{
73 int i;
74 seq_printf(seq, "Queue %d:\n", q->queue_id);
75 seq_printf(seq, " capacity: %zu\n", q->capacity);
76 seq_printf(seq, " queued: %zu\n", q->num_queued);
77 seq_printf(seq, " pending: %zu\n", q->num_pending);
78 seq_printf(seq, " sent: %zu\n", q->num_sent);
79 seq_printf(seq, " locked: %s\n", q->tx_locked_cnt ? "yes" : "no");
80 seq_printf(seq, " overfull: %s\n", q->overfull ? "yes" : "no");
81 seq_puts(seq, " link map: 0-> ");
82 for (i = 0; i < q->stats->map_capacity; ++i)
83 seq_printf(seq, "%.2d ", q->link_map_cache[i]);
84 seq_printf(seq, "<-%zu\n", q->stats->map_capacity);
85}
86
87static void cw1200_debug_print_map(struct seq_file *seq,
88 struct cw1200_common *priv,
89 const char *label,
90 u32 map)
91{
92 int i;
93 seq_printf(seq, "%s0-> ", label);
94 for (i = 0; i < priv->tx_queue_stats.map_capacity; ++i)
95 seq_printf(seq, "%s ", (map & BIT(i)) ? "**" : "..");
96 seq_printf(seq, "<-%zu\n", priv->tx_queue_stats.map_capacity - 1);
97}
98
99static int cw1200_status_show(struct seq_file *seq, void *v)
100{
101 int i;
102 struct list_head *item;
103 struct cw1200_common *priv = seq->private;
104 struct cw1200_debug_priv *d = priv->debug;
105
106 seq_puts(seq, "CW1200 Wireless LAN driver status\n");
107 seq_printf(seq, "Hardware: %d.%d\n",
108 priv->wsm_caps.hw_id,
109 priv->wsm_caps.hw_subid);
110 seq_printf(seq, "Firmware: %s %d.%d\n",
111 cw1200_fw_types[priv->wsm_caps.fw_type],
112 priv->wsm_caps.fw_ver,
113 priv->wsm_caps.fw_build);
114 seq_printf(seq, "FW API: %d\n",
115 priv->wsm_caps.fw_api);
116 seq_printf(seq, "FW caps: 0x%.4X\n",
117 priv->wsm_caps.fw_cap);
118 seq_printf(seq, "FW label: '%s'\n",
119 priv->wsm_caps.fw_label);
120 seq_printf(seq, "Mode: %s%s\n",
121 cw1200_debug_mode(priv->mode),
122 priv->listening ? " (listening)" : "");
123 seq_printf(seq, "Join state: %s\n",
124 cw1200_debug_join_status[priv->join_status]);
125 if (priv->channel)
126 seq_printf(seq, "Channel: %d%s\n",
127 priv->channel->hw_value,
128 priv->channel_switch_in_progress ?
129 " (switching)" : "");
130 if (priv->rx_filter.promiscuous)
131 seq_puts(seq, "Filter: promisc\n");
132 else if (priv->rx_filter.fcs)
133 seq_puts(seq, "Filter: fcs\n");
134 if (priv->rx_filter.bssid)
135 seq_puts(seq, "Filter: bssid\n");
136 if (!priv->disable_beacon_filter)
137 seq_puts(seq, "Filter: beacons\n");
138
139 if (priv->enable_beacon ||
140 priv->mode == NL80211_IFTYPE_AP ||
141 priv->mode == NL80211_IFTYPE_ADHOC ||
142 priv->mode == NL80211_IFTYPE_MESH_POINT ||
143 priv->mode == NL80211_IFTYPE_P2P_GO)
144 seq_printf(seq, "Beaconing: %s\n",
145 priv->enable_beacon ?
146 "enabled" : "disabled");
147
148 for (i = 0; i < 4; ++i)
149 seq_printf(seq, "EDCA(%d): %d, %d, %d, %d, %d\n", i,
150 priv->edca.params[i].cwmin,
151 priv->edca.params[i].cwmax,
152 priv->edca.params[i].aifns,
153 priv->edca.params[i].txop_limit,
154 priv->edca.params[i].max_rx_lifetime);
155
156 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
157 static const char *pm_mode = "unknown";
158 switch (priv->powersave_mode.mode) {
159 case WSM_PSM_ACTIVE:
160 pm_mode = "off";
161 break;
162 case WSM_PSM_PS:
163 pm_mode = "on";
164 break;
165 case WSM_PSM_FAST_PS:
166 pm_mode = "dynamic";
167 break;
168 }
169 seq_printf(seq, "Preamble: %s\n",
170 cw1200_debug_preamble[priv->association_mode.preamble]);
171 seq_printf(seq, "AMPDU spcn: %d\n",
172 priv->association_mode.mpdu_start_spacing);
173 seq_printf(seq, "Basic rate: 0x%.8X\n",
174 le32_to_cpu(priv->association_mode.basic_rate_set));
175 seq_printf(seq, "Bss lost: %d beacons\n",
176 priv->bss_params.beacon_lost_count);
177 seq_printf(seq, "AID: %d\n",
178 priv->bss_params.aid);
179 seq_printf(seq, "Rates: 0x%.8X\n",
180 priv->bss_params.operational_rate_set);
181 seq_printf(seq, "Powersave: %s\n", pm_mode);
182 }
183 seq_printf(seq, "HT: %s\n",
184 cw1200_is_ht(&priv->ht_info) ? "on" : "off");
185 if (cw1200_is_ht(&priv->ht_info)) {
186 seq_printf(seq, "Greenfield: %s\n",
187 cw1200_ht_greenfield(&priv->ht_info) ? "yes" : "no");
188 seq_printf(seq, "AMPDU dens: %d\n",
189 cw1200_ht_ampdu_density(&priv->ht_info));
190 }
191 seq_printf(seq, "RSSI thold: %d\n",
192 priv->cqm_rssi_thold);
193 seq_printf(seq, "RSSI hyst: %d\n",
194 priv->cqm_rssi_hyst);
195 seq_printf(seq, "Long retr: %d\n",
196 priv->long_frame_max_tx_count);
197 seq_printf(seq, "Short retr: %d\n",
198 priv->short_frame_max_tx_count);
199 spin_lock_bh(&priv->tx_policy_cache.lock);
200 i = 0;
201 list_for_each(item, &priv->tx_policy_cache.used)
202 ++i;
203 spin_unlock_bh(&priv->tx_policy_cache.lock);
204 seq_printf(seq, "RC in use: %d\n", i);
205
206 seq_puts(seq, "\n");
207 for (i = 0; i < 4; ++i) {
208 cw1200_queue_status_show(seq, &priv->tx_queue[i]);
209 seq_puts(seq, "\n");
210 }
211
212 cw1200_debug_print_map(seq, priv, "Link map: ",
213 priv->link_id_map);
214 cw1200_debug_print_map(seq, priv, "Asleep map: ",
215 priv->sta_asleep_mask);
216 cw1200_debug_print_map(seq, priv, "PSPOLL map: ",
217 priv->pspoll_mask);
218
219 seq_puts(seq, "\n");
220
221 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
222 if (priv->link_id_db[i].status) {
223 seq_printf(seq, "Link %d: %s, %pM\n",
224 i + 1,
225 cw1200_debug_link_id[priv->link_id_db[i].status],
226 priv->link_id_db[i].mac);
227 }
228 }
229
230 seq_puts(seq, "\n");
231
232 seq_printf(seq, "BH status: %s\n",
233 atomic_read(&priv->bh_term) ? "terminated" : "alive");
234 seq_printf(seq, "Pending RX: %d\n",
235 atomic_read(&priv->bh_rx));
236 seq_printf(seq, "Pending TX: %d\n",
237 atomic_read(&priv->bh_tx));
238 if (priv->bh_error)
239 seq_printf(seq, "BH errcode: %d\n",
240 priv->bh_error);
241 seq_printf(seq, "TX bufs: %d x %d bytes\n",
242 priv->wsm_caps.input_buffers,
243 priv->wsm_caps.input_buffer_size);
244 seq_printf(seq, "Used bufs: %d\n",
245 priv->hw_bufs_used);
246 seq_printf(seq, "Powermgmt: %s\n",
247 priv->powersave_enabled ? "on" : "off");
248 seq_printf(seq, "Device: %s\n",
249 priv->device_can_sleep ? "asleep" : "awake");
250
251 spin_lock(&priv->wsm_cmd.lock);
252 seq_printf(seq, "WSM status: %s\n",
253 priv->wsm_cmd.done ? "idle" : "active");
254 seq_printf(seq, "WSM cmd: 0x%.4X (%td bytes)\n",
255 priv->wsm_cmd.cmd, priv->wsm_cmd.len);
256 seq_printf(seq, "WSM retval: %d\n",
257 priv->wsm_cmd.ret);
258 spin_unlock(&priv->wsm_cmd.lock);
259
260 seq_printf(seq, "Datapath: %s\n",
261 atomic_read(&priv->tx_lock) ? "locked" : "unlocked");
262 if (atomic_read(&priv->tx_lock))
263 seq_printf(seq, "TXlock cnt: %d\n",
264 atomic_read(&priv->tx_lock));
265
266 seq_printf(seq, "TXed: %d\n",
267 d->tx);
268 seq_printf(seq, "AGG TXed: %d\n",
269 d->tx_agg);
270 seq_printf(seq, "MULTI TXed: %d (%d)\n",
271 d->tx_multi, d->tx_multi_frames);
272 seq_printf(seq, "RXed: %d\n",
273 d->rx);
274 seq_printf(seq, "AGG RXed: %d\n",
275 d->rx_agg);
276 seq_printf(seq, "TX miss: %d\n",
277 d->tx_cache_miss);
278 seq_printf(seq, "TX align: %d\n",
279 d->tx_align);
280 seq_printf(seq, "TX burst: %d\n",
281 d->tx_burst);
282 seq_printf(seq, "TX TTL: %d\n",
283 d->tx_ttl);
284 seq_printf(seq, "Scan: %s\n",
285 atomic_read(&priv->scan.in_progress) ? "active" : "idle");
286
287 return 0;
288}
289
290static int cw1200_status_open(struct inode *inode, struct file *file)
291{
292 return single_open(file, &cw1200_status_show,
293 inode->i_private);
294}
295
296static const struct file_operations fops_status = {
297 .open = cw1200_status_open,
298 .read = seq_read,
299 .llseek = seq_lseek,
300 .release = single_release,
301 .owner = THIS_MODULE,
302};
303
304static int cw1200_counters_show(struct seq_file *seq, void *v)
305{
306 int ret;
307 struct cw1200_common *priv = seq->private;
308 struct wsm_mib_counters_table counters;
309
310 ret = wsm_get_counters_table(priv, &counters);
311 if (ret)
312 return ret;
313
314#define PUT_COUNTER(tab, name) \
315 seq_printf(seq, "%s:" tab "%d\n", #name, \
316 __le32_to_cpu(counters.name))
317
318 PUT_COUNTER("\t\t", plcp_errors);
319 PUT_COUNTER("\t\t", fcs_errors);
320 PUT_COUNTER("\t\t", tx_packets);
321 PUT_COUNTER("\t\t", rx_packets);
322 PUT_COUNTER("\t\t", rx_packet_errors);
323 PUT_COUNTER("\t", rx_decryption_failures);
324 PUT_COUNTER("\t\t", rx_mic_failures);
325 PUT_COUNTER("\t", rx_no_key_failures);
326 PUT_COUNTER("\t", tx_multicast_frames);
327 PUT_COUNTER("\t", tx_frames_success);
328 PUT_COUNTER("\t", tx_frame_failures);
329 PUT_COUNTER("\t", tx_frames_retried);
330 PUT_COUNTER("\t", tx_frames_multi_retried);
331 PUT_COUNTER("\t", rx_frame_duplicates);
332 PUT_COUNTER("\t\t", rts_success);
333 PUT_COUNTER("\t\t", rts_failures);
334 PUT_COUNTER("\t\t", ack_failures);
335 PUT_COUNTER("\t", rx_multicast_frames);
336 PUT_COUNTER("\t", rx_frames_success);
337 PUT_COUNTER("\t", rx_cmac_icv_errors);
338 PUT_COUNTER("\t\t", rx_cmac_replays);
339 PUT_COUNTER("\t", rx_mgmt_ccmp_replays);
340
341#undef PUT_COUNTER
342
343 return 0;
344}
345
346static int cw1200_counters_open(struct inode *inode, struct file *file)
347{
348 return single_open(file, &cw1200_counters_show,
349 inode->i_private);
350}
351
352static const struct file_operations fops_counters = {
353 .open = cw1200_counters_open,
354 .read = seq_read,
355 .llseek = seq_lseek,
356 .release = single_release,
357 .owner = THIS_MODULE,
358};
359
360static int cw1200_generic_open(struct inode *inode, struct file *file)
361{
362 file->private_data = inode->i_private;
363 return 0;
364}
365
366#ifdef CONFIG_CW1200_ETF
367static int cw1200_etf_out_show(struct seq_file *seq, void *v)
368{
369 struct cw1200_common *priv = seq->private;
370 struct sk_buff *skb;
371 u32 len = 0;
372
373 skb = skb_dequeue(&priv->etf_q);
374
375 if (skb)
376 len = skb->len;
377
378 seq_write(seq, &len, sizeof(len));
379
380 if (skb) {
381 seq_write(seq, skb->data, len);
382 kfree_skb(skb);
383 }
384
385 return 0;
386}
387
388static int cw1200_etf_out_open(struct inode *inode, struct file *file)
389{
390 return single_open(file, &cw1200_etf_out_show,
391 inode->i_private);
392}
393
394static const struct file_operations fops_etf_out = {
395 .open = cw1200_etf_out_open,
396 .read = seq_read,
397 .llseek = seq_lseek,
398 .release = single_release,
399 .owner = THIS_MODULE,
400};
401
402struct etf_req_msg;
403static int etf_request(struct cw1200_common *priv,
404 struct etf_req_msg *msg, u32 len);
405
406#define MAX_RX_SZE 2600
407
408struct etf_in_state {
409 struct cw1200_common *priv;
410 u32 total_len;
411 u8 buf[MAX_RX_SZE];
412 u32 written;
413};
414
415static int cw1200_etf_in_open(struct inode *inode, struct file *file)
416{
417 struct etf_in_state *etf = kmalloc(sizeof(struct etf_in_state),
418 GFP_KERNEL);
419
420 if (!etf)
421 return -ENOMEM;
422
423 etf->written = 0;
424 etf->total_len = 0;
425 etf->priv = inode->i_private;
426
427 file->private_data = etf;
428
429 return 0;
430}
431
432static int cw1200_etf_in_release(struct inode *inode, struct file *file)
433{
434 kfree(file->private_data);
435 return 0;
436}
437
438static ssize_t cw1200_etf_in_write(struct file *file,
439 const char __user *user_buf, size_t count, loff_t *ppos)
440{
441 struct etf_in_state *etf = file->private_data;
442
443 ssize_t written = 0;
444
445 if (!etf->total_len) {
446 if (count < sizeof(etf->total_len)) {
447 pr_err("count < sizeof(total_len)\n");
448 return -EINVAL;
449 }
450
451 if (copy_from_user(&etf->total_len, user_buf,
452 sizeof(etf->total_len))) {
453 pr_err("copy_from_user (len) failed\n");
454 return -EFAULT;
455 }
456
457 written += sizeof(etf->total_len);
458 count -= sizeof(etf->total_len);
459 }
460
461 if (!count)
462 goto done;
463
464 if (copy_from_user(etf->buf + etf->written, user_buf + written,
465 count)) {
466 pr_err("copy_from_user (payload %zu) failed\n", count);
467 return -EFAULT;
468 }
469
470 written += count;
471 etf->written += count;
472
473 if (etf->written >= etf->total_len) {
474 if (etf_request(etf->priv, (struct etf_req_msg *)etf->buf,
475 etf->total_len)) {
476 pr_err("etf_request failed\n");
477 return -EIO;
478 }
479 }
480
481done:
482 return written;
483}
484
485static const struct file_operations fops_etf_in = {
486 .open = cw1200_etf_in_open,
487 .release = cw1200_etf_in_release,
488 .write = cw1200_etf_in_write,
489 .llseek = default_llseek,
490 .owner = THIS_MODULE,
491};
492#endif /* CONFIG_CW1200_ETF */
493
494static ssize_t cw1200_wsm_dumps(struct file *file,
495 const char __user *user_buf, size_t count, loff_t *ppos)
496{
497 struct cw1200_common *priv = file->private_data;
498 char buf[1];
499
500 if (!count)
501 return -EINVAL;
502 if (copy_from_user(buf, user_buf, 1))
503 return -EFAULT;
504
505 if (buf[0] == '1')
506 priv->wsm_enable_wsm_dumps = 1;
507 else
508 priv->wsm_enable_wsm_dumps = 0;
509
510 return count;
511}
512
513static const struct file_operations fops_wsm_dumps = {
514 .open = cw1200_generic_open,
515 .write = cw1200_wsm_dumps,
516 .llseek = default_llseek,
517};
518
519int cw1200_debug_init(struct cw1200_common *priv)
520{
521 int ret = -ENOMEM;
522 struct cw1200_debug_priv *d = kzalloc(sizeof(struct cw1200_debug_priv),
523 GFP_KERNEL);
524 priv->debug = d;
525 if (!d)
526 return ret;
527
528 d->debugfs_phy = debugfs_create_dir("cw1200",
529 priv->hw->wiphy->debugfsdir);
530 if (!d->debugfs_phy)
531 goto err;
532
533 if (!debugfs_create_file("status", S_IRUSR, d->debugfs_phy,
534 priv, &fops_status))
535 goto err;
536
537 if (!debugfs_create_file("counters", S_IRUSR, d->debugfs_phy,
538 priv, &fops_counters))
539 goto err;
540
541#ifdef CONFIG_CW1200_ETF
542 if (etf_mode) {
543 skb_queue_head_init(&priv->etf_q);
544
545 if (!debugfs_create_file("etf_out", S_IRUSR, d->debugfs_phy,
546 priv, &fops_etf_out))
547 goto err;
548 if (!debugfs_create_file("etf_in", S_IWUSR, d->debugfs_phy,
549 priv, &fops_etf_in))
550 goto err;
551 }
552#endif /* CONFIG_CW1200_ETF */
553
554 if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy,
555 priv, &fops_wsm_dumps))
556 goto err;
557
558 ret = cw1200_itp_init(priv);
559 if (ret)
560 goto err;
561
562 return 0;
563
564err:
565 priv->debug = NULL;
566 debugfs_remove_recursive(d->debugfs_phy);
567 kfree(d);
568 return ret;
569}
570
571void cw1200_debug_release(struct cw1200_common *priv)
572{
573 struct cw1200_debug_priv *d = priv->debug;
574 if (d) {
575 cw1200_itp_release(priv);
576 priv->debug = NULL;
577 kfree(d);
578 }
579}
580
581#ifdef CONFIG_CW1200_ETF
582struct cw1200_sdd {
583 u8 id;
584 u8 len;
585 u8 data[];
586};
587
588struct etf_req_msg {
589 u32 id;
590 u32 len;
591 u8 data[];
592};
593
594static int parse_sdd_file(struct cw1200_common *priv, u8 *data, u32 length)
595{
596 struct cw1200_sdd *ie;
597
598 while (length > 0) {
599 ie = (struct cw1200_sdd *)data;
600 if (ie->id == SDD_REFERENCE_FREQUENCY_ELT_ID) {
601 priv->hw_refclk = cpu_to_le16(*((u16 *)ie->data));
602 pr_info("Using Reference clock frequency %d KHz\n",
603 priv->hw_refclk);
604 break;
605 }
606
607 length -= ie->len + sizeof(*ie);
608 data += ie->len + sizeof(*ie);
609 }
610 return 0;
611}
612
613char *etf_firmware;
614
615#define ST90TDS_START_ADAPTER 0x09 /* Loads firmware too */
616#define ST90TDS_STOP_ADAPTER 0x0A
617#define ST90TDS_CONFIG_ADAPTER 0x0E /* Send configuration params */
618#define ST90TDS_SBUS_READ 0x13
619#define ST90TDS_SBUS_WRITE 0x14
620#define ST90TDS_GET_DEVICE_OPTION 0x19
621#define ST90TDS_SET_DEVICE_OPTION 0x1A
622#define ST90TDS_SEND_SDD 0x1D /* SDD File used to find DPLL */
623
624#include "fwio.h"
625
626static int etf_request(struct cw1200_common *priv,
627 struct etf_req_msg *msg,
628 u32 len)
629{
630 int rval = -1;
631 switch (msg->id) {
632 case ST90TDS_START_ADAPTER:
633 etf_firmware = "cw1200_etf.bin";
634 pr_info("ETF_START (len %d, '%s')\n", len, etf_firmware);
635 rval = cw1200_load_firmware(priv);
636 break;
637 case ST90TDS_STOP_ADAPTER:
638 pr_info("ETF_STOP (unhandled)\n");
639 break;
640 case ST90TDS_SEND_SDD:
641 pr_info("ETF_SDD\n");
642 rval = parse_sdd_file(priv, msg->data, msg->len);
643 break;
644 case ST90TDS_CONFIG_ADAPTER:
645 pr_info("ETF_CONFIG_ADAP (unhandled)\n");
646 break;
647 case ST90TDS_SBUS_READ:
648 pr_info("ETF_SBUS_READ (unhandled)\n");
649 break;
650 case ST90TDS_SBUS_WRITE:
651 pr_info("ETF_SBUS_WRITE (unhandled)\n");
652 break;
653 case ST90TDS_SET_DEVICE_OPTION:
654 pr_info("ETF_SET_DEV_OPT (unhandled)\n");
655 break;
656 default:
657 pr_info("ETF_PASSTHRU (0x%08x)\n", msg->id);
658 rval = wsm_raw_cmd(priv, (u8 *)msg, len);
659 break;
660 }
661
662 return rval;
663}
664#endif /* CONFIG_CW1200_ETF */
diff --git a/drivers/net/wireless/cw1200/debug.h b/drivers/net/wireless/cw1200/debug.h
new file mode 100644
index 000000000000..1fea5b29a819
--- /dev/null
+++ b/drivers/net/wireless/cw1200/debug.h
@@ -0,0 +1,98 @@
1/*
2 * DebugFS code for ST-Ericsson CW1200 mac80211 driver
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_DEBUG_H_INCLUDED
13#define CW1200_DEBUG_H_INCLUDED
14
15#include "itp.h"
16
17struct cw1200_debug_priv {
18 struct dentry *debugfs_phy;
19 int tx;
20 int tx_agg;
21 int rx;
22 int rx_agg;
23 int tx_multi;
24 int tx_multi_frames;
25 int tx_cache_miss;
26 int tx_align;
27 int tx_ttl;
28 int tx_burst;
29 int ba_cnt;
30 int ba_acc;
31 int ba_cnt_rx;
32 int ba_acc_rx;
33#ifdef CONFIG_CW1200_ITP
34 struct cw1200_itp itp;
35#endif /* CONFIG_CW1200_ITP */
36};
37
38int cw1200_debug_init(struct cw1200_common *priv);
39void cw1200_debug_release(struct cw1200_common *priv);
40
41static inline void cw1200_debug_txed(struct cw1200_common *priv)
42{
43 ++priv->debug->tx;
44}
45
46static inline void cw1200_debug_txed_agg(struct cw1200_common *priv)
47{
48 ++priv->debug->tx_agg;
49}
50
51static inline void cw1200_debug_txed_multi(struct cw1200_common *priv,
52 int count)
53{
54 ++priv->debug->tx_multi;
55 priv->debug->tx_multi_frames += count;
56}
57
58static inline void cw1200_debug_rxed(struct cw1200_common *priv)
59{
60 ++priv->debug->rx;
61}
62
63static inline void cw1200_debug_rxed_agg(struct cw1200_common *priv)
64{
65 ++priv->debug->rx_agg;
66}
67
68static inline void cw1200_debug_tx_cache_miss(struct cw1200_common *priv)
69{
70 ++priv->debug->tx_cache_miss;
71}
72
73static inline void cw1200_debug_tx_align(struct cw1200_common *priv)
74{
75 ++priv->debug->tx_align;
76}
77
78static inline void cw1200_debug_tx_ttl(struct cw1200_common *priv)
79{
80 ++priv->debug->tx_ttl;
81}
82
83static inline void cw1200_debug_tx_burst(struct cw1200_common *priv)
84{
85 ++priv->debug->tx_burst;
86}
87
88static inline void cw1200_debug_ba(struct cw1200_common *priv,
89 int ba_cnt, int ba_acc,
90 int ba_cnt_rx, int ba_acc_rx)
91{
92 priv->debug->ba_cnt = ba_cnt;
93 priv->debug->ba_acc = ba_acc;
94 priv->debug->ba_cnt_rx = ba_cnt_rx;
95 priv->debug->ba_acc_rx = ba_acc_rx;
96}
97
98#endif /* CW1200_DEBUG_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
new file mode 100644
index 000000000000..ad01cd2a59ec
--- /dev/null
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -0,0 +1,525 @@
1/*
2 * Firmware I/O code for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/init.h>
18#include <linux/vmalloc.h>
19#include <linux/sched.h>
20#include <linux/firmware.h>
21
22#include "cw1200.h"
23#include "fwio.h"
24#include "hwio.h"
25#include "sbus.h"
26#include "bh.h"
27
28static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
29{
30 int hw_type = -1;
31 u32 silicon_type = (config_reg_val >> 24) & 0x7;
32 u32 silicon_vers = (config_reg_val >> 31) & 0x1;
33
34 switch (silicon_type) {
35 case 0x00:
36 *major_revision = 1;
37 hw_type = HIF_9000_SILICON_VERSATILE;
38 break;
39 case 0x01:
40 case 0x02: /* CW1x00 */
41 case 0x04: /* CW1x60 */
42 *major_revision = silicon_type;
43 if (silicon_vers)
44 hw_type = HIF_8601_VERSATILE;
45 else
46 hw_type = HIF_8601_SILICON;
47 break;
48 default:
49 break;
50 }
51
52 return hw_type;
53}
54
55static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
56{
57 int ret, block, num_blocks;
58 unsigned i;
59 u32 val32;
60 u32 put = 0, get = 0;
61 u8 *buf = NULL;
62 const char *fw_path;
63 const struct firmware *firmware = NULL;
64
65 /* Macroses are local. */
66#define APB_WRITE(reg, val) \
67 do { \
68 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
69 if (ret < 0) \
70 goto error; \
71 } while (0)
72#define APB_READ(reg, val) \
73 do { \
74 ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
75 if (ret < 0) \
76 goto error; \
77 } while (0)
78#define REG_WRITE(reg, val) \
79 do { \
80 ret = cw1200_reg_write_32(priv, (reg), (val)); \
81 if (ret < 0) \
82 goto error; \
83 } while (0)
84#define REG_READ(reg, val) \
85 do { \
86 ret = cw1200_reg_read_32(priv, (reg), &(val)); \
87 if (ret < 0) \
88 goto error; \
89 } while (0)
90
91 switch (priv->hw_revision) {
92 case CW1200_HW_REV_CUT10:
93 fw_path = FIRMWARE_CUT10;
94 if (!priv->sdd_path)
95 priv->sdd_path = SDD_FILE_10;
96 break;
97 case CW1200_HW_REV_CUT11:
98 fw_path = FIRMWARE_CUT11;
99 if (!priv->sdd_path)
100 priv->sdd_path = SDD_FILE_11;
101 break;
102 case CW1200_HW_REV_CUT20:
103 fw_path = FIRMWARE_CUT20;
104 if (!priv->sdd_path)
105 priv->sdd_path = SDD_FILE_20;
106 break;
107 case CW1200_HW_REV_CUT22:
108 fw_path = FIRMWARE_CUT22;
109 if (!priv->sdd_path)
110 priv->sdd_path = SDD_FILE_22;
111 break;
112 case CW1X60_HW_REV:
113 fw_path = FIRMWARE_CW1X60;
114 if (!priv->sdd_path)
115 priv->sdd_path = SDD_FILE_CW1X60;
116 break;
117 default:
118 pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
119 return -EINVAL;
120 }
121
122 /* Initialize common registers */
123 APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
124 APB_WRITE(DOWNLOAD_PUT_REG, 0);
125 APB_WRITE(DOWNLOAD_GET_REG, 0);
126 APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
127 APB_WRITE(DOWNLOAD_FLAGS_REG, 0);
128
129 /* Write the NOP Instruction */
130 REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
131 REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
132
133 /* Release CPU from RESET */
134 REG_READ(ST90TDS_CONFIG_REG_ID, val32);
135 val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT;
136 REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
137
138 /* Enable Clock */
139 val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
140 REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
141
142#ifdef CONFIG_CW1200_ETF
143 if (etf_mode)
144 fw_path = etf_firmware;
145#endif
146
147 /* Load a firmware file */
148 ret = request_firmware(&firmware, fw_path, priv->pdev);
149 if (ret) {
150 pr_err("Can't load firmware file %s.\n", fw_path);
151 goto error;
152 }
153
154 buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
155 if (!buf) {
156 pr_err("Can't allocate firmware load buffer.\n");
157 ret = -ENOMEM;
158 goto error;
159 }
160
161 /* Check if the bootloader is ready */
162 for (i = 0; i < 100; i += 1 + i / 2) {
163 APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32);
164 if (val32 == DOWNLOAD_I_AM_HERE)
165 break;
166 mdelay(i);
167 } /* End of for loop */
168
169 if (val32 != DOWNLOAD_I_AM_HERE) {
170 pr_err("Bootloader is not ready.\n");
171 ret = -ETIMEDOUT;
172 goto error;
173 }
174
175 /* Calculcate number of download blocks */
176 num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;
177
178 /* Updating the length in Download Ctrl Area */
179 val32 = firmware->size; /* Explicit cast from size_t to u32 */
180 APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, val32);
181
182 /* Firmware downloading loop */
183 for (block = 0; block < num_blocks; block++) {
184 size_t tx_size;
185 size_t block_size;
186
187 /* check the download status */
188 APB_READ(DOWNLOAD_STATUS_REG, val32);
189 if (val32 != DOWNLOAD_PENDING) {
190 pr_err("Bootloader reported error %d.\n", val32);
191 ret = -EIO;
192 goto error;
193 }
194
195 /* loop until put - get <= 24K */
196 for (i = 0; i < 100; i++) {
197 APB_READ(DOWNLOAD_GET_REG, get);
198 if ((put - get) <=
199 (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
200 break;
201 mdelay(i);
202 }
203
204 if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
205 pr_err("Timeout waiting for FIFO.\n");
206 ret = -ETIMEDOUT;
207 goto error;
208 }
209
210 /* calculate the block size */
211 tx_size = block_size = min((size_t)(firmware->size - put),
212 (size_t)DOWNLOAD_BLOCK_SIZE);
213
214 memcpy(buf, &firmware->data[put], block_size);
215 if (block_size < DOWNLOAD_BLOCK_SIZE) {
216 memset(&buf[block_size], 0,
217 DOWNLOAD_BLOCK_SIZE - block_size);
218 tx_size = DOWNLOAD_BLOCK_SIZE;
219 }
220
221 /* send the block to sram */
222 ret = cw1200_apb_write(priv,
223 CW1200_APB(DOWNLOAD_FIFO_OFFSET +
224 (put & (DOWNLOAD_FIFO_SIZE - 1))),
225 buf, tx_size);
226 if (ret < 0) {
227 pr_err("Can't write firmware block @ %d!\n",
228 put & (DOWNLOAD_FIFO_SIZE - 1));
229 goto error;
230 }
231
232 /* update the put register */
233 put += block_size;
234 APB_WRITE(DOWNLOAD_PUT_REG, put);
235 } /* End of firmware download loop */
236
237 /* Wait for the download completion */
238 for (i = 0; i < 300; i += 1 + i / 2) {
239 APB_READ(DOWNLOAD_STATUS_REG, val32);
240 if (val32 != DOWNLOAD_PENDING)
241 break;
242 mdelay(i);
243 }
244 if (val32 != DOWNLOAD_SUCCESS) {
245 pr_err("Wait for download completion failed: 0x%.8X\n", val32);
246 ret = -ETIMEDOUT;
247 goto error;
248 } else {
249 pr_info("Firmware download completed.\n");
250 ret = 0;
251 }
252
253error:
254 kfree(buf);
255 if (firmware)
256 release_firmware(firmware);
257 return ret;
258
259#undef APB_WRITE
260#undef APB_READ
261#undef REG_WRITE
262#undef REG_READ
263}
264
265
266static int config_reg_read(struct cw1200_common *priv, u32 *val)
267{
268 switch (priv->hw_type) {
269 case HIF_9000_SILICON_VERSATILE: {
270 u16 val16;
271 int ret = cw1200_reg_read_16(priv,
272 ST90TDS_CONFIG_REG_ID,
273 &val16);
274 if (ret < 0)
275 return ret;
276 *val = val16;
277 return 0;
278 }
279 case HIF_8601_VERSATILE:
280 case HIF_8601_SILICON:
281 default:
282 cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, val);
283 break;
284 }
285 return 0;
286}
287
288static int config_reg_write(struct cw1200_common *priv, u32 val)
289{
290 switch (priv->hw_type) {
291 case HIF_9000_SILICON_VERSATILE:
292 return cw1200_reg_write_16(priv,
293 ST90TDS_CONFIG_REG_ID,
294 (u16)val);
295 case HIF_8601_VERSATILE:
296 case HIF_8601_SILICON:
297 default:
298 return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
299 break;
300 }
301 return 0;
302}
303
304int cw1200_load_firmware(struct cw1200_common *priv)
305{
306 int ret;
307 int i;
308 u32 val32;
309 u16 val16;
310 int major_revision = -1;
311
312 /* Read CONFIG Register */
313 ret = cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
314 if (ret < 0) {
315 pr_err("Can't read config register.\n");
316 goto out;
317 }
318
319 if (val32 == 0 || val32 == 0xffffffff) {
320 pr_err("Bad config register value (0x%08x)\n", val32);
321 ret = -EIO;
322 goto out;
323 }
324
325 priv->hw_type = cw1200_get_hw_type(val32, &major_revision);
326 if (priv->hw_type < 0) {
327 pr_err("Can't deduce hardware type.\n");
328 ret = -ENOTSUPP;
329 goto out;
330 }
331
332 /* Set DPLL Reg value, and read back to confirm writes work */
333 ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
334 cw1200_dpll_from_clk(priv->hw_refclk));
335 if (ret < 0) {
336 pr_err("Can't write DPLL register.\n");
337 goto out;
338 }
339
340 msleep(20);
341
342 ret = cw1200_reg_read_32(priv,
343 ST90TDS_TSET_GEN_R_W_REG_ID, &val32);
344 if (ret < 0) {
345 pr_err("Can't read DPLL register.\n");
346 goto out;
347 }
348
349 if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
350 pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
351 cw1200_dpll_from_clk(priv->hw_refclk), val32);
352 ret = -EIO;
353 goto out;
354 }
355
356 /* Set wakeup bit in device */
357 ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16);
358 if (ret < 0) {
359 pr_err("set_wakeup: can't read control register.\n");
360 goto out;
361 }
362
363 ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
364 val16 | ST90TDS_CONT_WUP_BIT);
365 if (ret < 0) {
366 pr_err("set_wakeup: can't write control register.\n");
367 goto out;
368 }
369
370 /* Wait for wakeup */
371 for (i = 0; i < 300; i += (1 + i / 2)) {
372 ret = cw1200_reg_read_16(priv,
373 ST90TDS_CONTROL_REG_ID, &val16);
374 if (ret < 0) {
375 pr_err("wait_for_wakeup: can't read control register.\n");
376 goto out;
377 }
378
379 if (val16 & ST90TDS_CONT_RDY_BIT)
380 break;
381
382 msleep(i);
383 }
384
385 if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
386 pr_err("wait_for_wakeup: device is not responding.\n");
387 ret = -ETIMEDOUT;
388 goto out;
389 }
390
391 switch (major_revision) {
392 case 1:
393 /* CW1200 Hardware detection logic : Check for CUT1.1 */
394 ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32);
395 if (ret) {
396 pr_err("HW detection: can't read CUT ID.\n");
397 goto out;
398 }
399
400 switch (val32) {
401 case CW1200_CUT_11_ID_STR:
402 pr_info("CW1x00 Cut 1.1 silicon detected.\n");
403 priv->hw_revision = CW1200_HW_REV_CUT11;
404 break;
405 default:
406 pr_info("CW1x00 Cut 1.0 silicon detected.\n");
407 priv->hw_revision = CW1200_HW_REV_CUT10;
408 break;
409 }
410
411 /* According to ST-E, CUT<2.0 has busted BA TID0-3.
412 Just disable it entirely...
413 */
414 priv->ba_rx_tid_mask = 0;
415 priv->ba_tx_tid_mask = 0;
416 break;
417 case 2: {
418 u32 ar1, ar2, ar3;
419 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR, &ar1);
420 if (ret) {
421 pr_err("(1) HW detection: can't read CUT ID\n");
422 goto out;
423 }
424 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 4, &ar2);
425 if (ret) {
426 pr_err("(2) HW detection: can't read CUT ID.\n");
427 goto out;
428 }
429
430 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 8, &ar3);
431 if (ret) {
432 pr_err("(3) HW detection: can't read CUT ID.\n");
433 goto out;
434 }
435
436 if (ar1 == CW1200_CUT_22_ID_STR1 &&
437 ar2 == CW1200_CUT_22_ID_STR2 &&
438 ar3 == CW1200_CUT_22_ID_STR3) {
439 pr_info("CW1x00 Cut 2.2 silicon detected.\n");
440 priv->hw_revision = CW1200_HW_REV_CUT22;
441 } else {
442 pr_info("CW1x00 Cut 2.0 silicon detected.\n");
443 priv->hw_revision = CW1200_HW_REV_CUT20;
444 }
445 break;
446 }
447 case 4:
448 pr_info("CW1x60 silicon detected.\n");
449 priv->hw_revision = CW1X60_HW_REV;
450 break;
451 default:
452 pr_err("Unsupported silicon major revision %d.\n",
453 major_revision);
454 ret = -ENOTSUPP;
455 goto out;
456 }
457
458 /* Checking for access mode */
459 ret = config_reg_read(priv, &val32);
460 if (ret < 0) {
461 pr_err("Can't read config register.\n");
462 goto out;
463 }
464
465 if (!(val32 & ST90TDS_CONFIG_ACCESS_MODE_BIT)) {
466 pr_err("Device is already in QUEUE mode!\n");
467 ret = -EINVAL;
468 goto out;
469 }
470
471 switch (priv->hw_type) {
472 case HIF_8601_SILICON:
473 if (priv->hw_revision == CW1X60_HW_REV) {
474 pr_err("Can't handle CW1160/1260 firmware load yet.\n");
475 ret = -ENOTSUPP;
476 goto out;
477 }
478 ret = cw1200_load_firmware_cw1200(priv);
479 break;
480 default:
481 pr_err("Can't perform firmware load for hw type %d.\n",
482 priv->hw_type);
483 ret = -ENOTSUPP;
484 goto out;
485 }
486 if (ret < 0) {
487 pr_err("Firmware load error.\n");
488 goto out;
489 }
490
491 /* Enable interrupt signalling */
492 priv->sbus_ops->lock(priv->sbus_priv);
493 ret = __cw1200_irq_enable(priv, 1);
494 priv->sbus_ops->unlock(priv->sbus_priv);
495 if (ret < 0)
496 goto unsubscribe;
497
498 /* Configure device for MESSSAGE MODE */
499 ret = config_reg_read(priv, &val32);
500 if (ret < 0) {
501 pr_err("Can't read config register.\n");
502 goto unsubscribe;
503 }
504 ret = config_reg_write(priv, val32 & ~ST90TDS_CONFIG_ACCESS_MODE_BIT);
505 if (ret < 0) {
506 pr_err("Can't write config register.\n");
507 goto unsubscribe;
508 }
509
510 /* Unless we read the CONFIG Register we are
511 * not able to get an interrupt
512 */
513 mdelay(10);
514 config_reg_read(priv, &val32);
515
516out:
517 return ret;
518
519unsubscribe:
520 /* Disable interrupt signalling */
521 priv->sbus_ops->lock(priv->sbus_priv);
522 ret = __cw1200_irq_enable(priv, 0);
523 priv->sbus_ops->unlock(priv->sbus_priv);
524 return ret;
525}
diff --git a/drivers/net/wireless/cw1200/fwio.h b/drivers/net/wireless/cw1200/fwio.h
new file mode 100644
index 000000000000..ea3099362cdf
--- /dev/null
+++ b/drivers/net/wireless/cw1200/fwio.h
@@ -0,0 +1,39 @@
1/*
2 * Firmware API for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef FWIO_H_INCLUDED
18#define FWIO_H_INCLUDED
19
20#define BOOTLOADER_CW1X60 "boot_cw1x60.bin"
21#define FIRMWARE_CW1X60 "wsm_cw1x60.bin"
22#define FIRMWARE_CUT22 "wsm_22.bin"
23#define FIRMWARE_CUT20 "wsm_20.bin"
24#define FIRMWARE_CUT11 "wsm_11.bin"
25#define FIRMWARE_CUT10 "wsm_10.bin"
26#define SDD_FILE_CW1X60 "sdd_cw1x60.bin"
27#define SDD_FILE_22 "sdd_22.bin"
28#define SDD_FILE_20 "sdd_20.bin"
29#define SDD_FILE_11 "sdd_11.bin"
30#define SDD_FILE_10 "sdd_10.bin"
31
32int cw1200_load_firmware(struct cw1200_common *priv);
33
34/* SDD definitions */
35#define SDD_PTA_CFG_ELT_ID 0xEB
36#define SDD_REFERENCE_FREQUENCY_ELT_ID 0xc5
37u32 cw1200_dpll_from_clk(u16 clk);
38
39#endif
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
new file mode 100644
index 000000000000..1af7b3d421b2
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -0,0 +1,311 @@
1/*
2 * Low-level device IO routines for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver, which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@lockless.no>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/types.h>
18
19#include "cw1200.h"
20#include "hwio.h"
21#include "sbus.h"
22
23 /* Sdio addr is 4*spi_addr */
24#define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
25#define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
26 ((((buf_id) & 0x1F) << 7) \
27 | (((mpf) & 1) << 6) \
28 | (((rfu) & 1) << 5) \
29 | (((reg_id_ofs) & 0x1F) << 0))
30#define MAX_RETRY 3
31
32
33static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
34 void *buf, size_t buf_len, int buf_id)
35{
36 u16 addr_sdio;
37 u32 sdio_reg_addr_17bit;
38
39 /* Check if buffer is aligned to 4 byte boundary */
40 if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
41 pr_err("buffer is not aligned.\n");
42 return -EINVAL;
43 }
44
45 /* Convert to SDIO Register Address */
46 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
47 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
48
49 return priv->sbus_ops->sbus_memcpy_fromio(priv->sbus_priv,
50 sdio_reg_addr_17bit,
51 buf, buf_len);
52}
53
54static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
55 const void *buf, size_t buf_len, int buf_id)
56{
57 u16 addr_sdio;
58 u32 sdio_reg_addr_17bit;
59
60 /* Convert to SDIO Register Address */
61 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
62 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
63
64 return priv->sbus_ops->sbus_memcpy_toio(priv->sbus_priv,
65 sdio_reg_addr_17bit,
66 buf, buf_len);
67}
68
69static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
70 u16 addr, u32 *val)
71{
72 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
73 *val = le32_to_cpu(*val);
74 return i;
75}
76
77static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
78 u16 addr, u32 val)
79{
80 val = cpu_to_le32(val);
81 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
82}
83
84static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
85 u16 addr, u16 *val)
86{
87 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
88 *val = le16_to_cpu(*val);
89 return i;
90}
91
92static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
93 u16 addr, u16 val)
94{
95 val = cpu_to_le16(val);
96 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
97}
98
99int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
100 size_t buf_len)
101{
102 int ret;
103 priv->sbus_ops->lock(priv->sbus_priv);
104 ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
105 priv->sbus_ops->unlock(priv->sbus_priv);
106 return ret;
107}
108
109int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
110 size_t buf_len)
111{
112 int ret;
113 priv->sbus_ops->lock(priv->sbus_priv);
114 ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
115 priv->sbus_ops->unlock(priv->sbus_priv);
116 return ret;
117}
118
119int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
120{
121 int ret, retry = 1;
122 int buf_id_rx = priv->buf_id_rx;
123
124 priv->sbus_ops->lock(priv->sbus_priv);
125
126 while (retry <= MAX_RETRY) {
127 ret = __cw1200_reg_read(priv,
128 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
129 buf_len, buf_id_rx + 1);
130 if (!ret) {
131 buf_id_rx = (buf_id_rx + 1) & 3;
132 priv->buf_id_rx = buf_id_rx;
133 break;
134 } else {
135 retry++;
136 mdelay(1);
137 pr_err("error :[%d]\n", ret);
138 }
139 }
140
141 priv->sbus_ops->unlock(priv->sbus_priv);
142 return ret;
143}
144
145int cw1200_data_write(struct cw1200_common *priv, const void *buf,
146 size_t buf_len)
147{
148 int ret, retry = 1;
149 int buf_id_tx = priv->buf_id_tx;
150
151 priv->sbus_ops->lock(priv->sbus_priv);
152
153 while (retry <= MAX_RETRY) {
154 ret = __cw1200_reg_write(priv,
155 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
156 buf_len, buf_id_tx);
157 if (!ret) {
158 buf_id_tx = (buf_id_tx + 1) & 31;
159 priv->buf_id_tx = buf_id_tx;
160 break;
161 } else {
162 retry++;
163 mdelay(1);
164 pr_err("error :[%d]\n", ret);
165 }
166 }
167
168 priv->sbus_ops->unlock(priv->sbus_priv);
169 return ret;
170}
171
172int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
173 size_t buf_len, u32 prefetch, u16 port_addr)
174{
175 u32 val32 = 0;
176 int i, ret;
177
178 if ((buf_len / 2) >= 0x1000) {
179 pr_err("Can't read more than 0xfff words.\n");
180 return -EINVAL;
181 goto out;
182 }
183
184 priv->sbus_ops->lock(priv->sbus_priv);
185 /* Write address */
186 ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
187 if (ret < 0) {
188 pr_err("Can't write address register.\n");
189 goto out;
190 }
191
192 /* Read CONFIG Register Value - We will read 32 bits */
193 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
194 if (ret < 0) {
195 pr_err("Can't read config register.\n");
196 goto out;
197 }
198
199 /* Set PREFETCH bit */
200 ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID,
201 val32 | prefetch);
202 if (ret < 0) {
203 pr_err("Can't write prefetch bit.\n");
204 goto out;
205 }
206
207 /* Check for PRE-FETCH bit to be cleared */
208 for (i = 0; i < 20; i++) {
209 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
210 if (ret < 0) {
211 pr_err("Can't check prefetch bit.\n");
212 goto out;
213 }
214 if (!(val32 & prefetch))
215 break;
216
217 mdelay(i);
218 }
219
220 if (val32 & prefetch) {
221 pr_err("Prefetch bit is not cleared.\n");
222 goto out;
223 }
224
225 /* Read data port */
226 ret = __cw1200_reg_read(priv, port_addr, buf, buf_len, 0);
227 if (ret < 0) {
228 pr_err("Can't read data port.\n");
229 goto out;
230 }
231
232out:
233 priv->sbus_ops->unlock(priv->sbus_priv);
234 return ret;
235}
236
237int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
238 size_t buf_len)
239{
240 int ret;
241
242 if ((buf_len / 2) >= 0x1000) {
243 pr_err("Can't write more than 0xfff words.\n");
244 return -EINVAL;
245 }
246
247 priv->sbus_ops->lock(priv->sbus_priv);
248
249 /* Write address */
250 ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
251 if (ret < 0) {
252 pr_err("Can't write address register.\n");
253 goto out;
254 }
255
256 /* Write data port */
257 ret = __cw1200_reg_write(priv, ST90TDS_SRAM_DPORT_REG_ID,
258 buf, buf_len, 0);
259 if (ret < 0) {
260 pr_err("Can't write data port.\n");
261 goto out;
262 }
263
264out:
265 priv->sbus_ops->unlock(priv->sbus_priv);
266 return ret;
267}
268
269int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
270{
271 u32 val32;
272 u16 val16;
273 int ret;
274
275 if (HIF_8601_SILICON == priv->hw_type) {
276 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
277 if (ret < 0) {
278 pr_err("Can't read config register.\n");
279 return ret;
280 }
281
282 if (enable)
283 val32 |= ST90TDS_CONF_IRQ_RDY_ENABLE;
284 else
285 val32 &= ~ST90TDS_CONF_IRQ_RDY_ENABLE;
286
287 ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val32);
288 if (ret < 0) {
289 pr_err("Can't write config register.\n");
290 return ret;
291 }
292 } else {
293 ret = __cw1200_reg_read_16(priv, ST90TDS_CONFIG_REG_ID, &val16);
294 if (ret < 0) {
295 pr_err("Can't read control register.\n");
296 return ret;
297 }
298
299 if (enable)
300 val16 |= ST90TDS_CONT_IRQ_RDY_ENABLE;
301 else
302 val16 &= ~ST90TDS_CONT_IRQ_RDY_ENABLE;
303
304 ret = __cw1200_reg_write_16(priv, ST90TDS_CONFIG_REG_ID, val16);
305 if (ret < 0) {
306 pr_err("Can't write control register.\n");
307 return ret;
308 }
309 }
310 return 0;
311}
diff --git a/drivers/net/wireless/cw1200/hwio.h b/drivers/net/wireless/cw1200/hwio.h
new file mode 100644
index 000000000000..7ee73fe32ccf
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwio.h
@@ -0,0 +1,247 @@
1/*
2 * Low-level API for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef CW1200_HWIO_H_INCLUDED
18#define CW1200_HWIO_H_INCLUDED
19
20/* extern */ struct cw1200_common;
21
22#define CW1200_CUT_11_ID_STR (0x302E3830)
23#define CW1200_CUT_22_ID_STR1 (0x302e3132)
24#define CW1200_CUT_22_ID_STR2 (0x32302e30)
25#define CW1200_CUT_22_ID_STR3 (0x3335)
26#define CW1200_CUT_ID_ADDR (0xFFF17F90)
27#define CW1200_CUT2_ID_ADDR (0xFFF1FF90)
28
29/* Download control area */
30/* boot loader start address in SRAM */
31#define DOWNLOAD_BOOT_LOADER_OFFSET (0x00000000)
32/* 32K, 0x4000 to 0xDFFF */
33#define DOWNLOAD_FIFO_OFFSET (0x00004000)
34/* 32K */
35#define DOWNLOAD_FIFO_SIZE (0x00008000)
36/* 128 bytes, 0xFF80 to 0xFFFF */
37#define DOWNLOAD_CTRL_OFFSET (0x0000FF80)
38#define DOWNLOAD_CTRL_DATA_DWORDS (32-6)
39
40struct download_cntl_t {
41 /* size of whole firmware file (including Cheksum), host init */
42 u32 image_size;
43 /* downloading flags */
44 u32 flags;
45 /* No. of bytes put into the download, init & updated by host */
46 u32 put;
47 /* last traced program counter, last ARM reg_pc */
48 u32 trace_pc;
49 /* No. of bytes read from the download, host init, device updates */
50 u32 get;
51 /* r0, boot losader status, host init to pending, device updates */
52 u32 status;
53 /* Extra debug info, r1 to r14 if status=r0=DOWNLOAD_EXCEPTION */
54 u32 debug_data[DOWNLOAD_CTRL_DATA_DWORDS];
55};
56
57#define DOWNLOAD_IMAGE_SIZE_REG \
58 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, image_size))
59#define DOWNLOAD_FLAGS_REG \
60 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, flags))
61#define DOWNLOAD_PUT_REG \
62 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, put))
63#define DOWNLOAD_TRACE_PC_REG \
64 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, trace_pc))
65#define DOWNLOAD_GET_REG \
66 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, get))
67#define DOWNLOAD_STATUS_REG \
68 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, status))
69#define DOWNLOAD_DEBUG_DATA_REG \
70 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, debug_data))
71#define DOWNLOAD_DEBUG_DATA_LEN (108)
72
73#define DOWNLOAD_BLOCK_SIZE (1024)
74
75/* For boot loader detection */
76#define DOWNLOAD_ARE_YOU_HERE (0x87654321)
77#define DOWNLOAD_I_AM_HERE (0x12345678)
78
79/* Download error code */
80#define DOWNLOAD_PENDING (0xFFFFFFFF)
81#define DOWNLOAD_SUCCESS (0)
82#define DOWNLOAD_EXCEPTION (1)
83#define DOWNLOAD_ERR_MEM_1 (2)
84#define DOWNLOAD_ERR_MEM_2 (3)
85#define DOWNLOAD_ERR_SOFTWARE (4)
86#define DOWNLOAD_ERR_FILE_SIZE (5)
87#define DOWNLOAD_ERR_CHECKSUM (6)
88#define DOWNLOAD_ERR_OVERFLOW (7)
89#define DOWNLOAD_ERR_IMAGE (8)
90#define DOWNLOAD_ERR_HOST (9)
91#define DOWNLOAD_ERR_ABORT (10)
92
93
94#define SYS_BASE_ADDR_SILICON (0)
95#define PAC_BASE_ADDRESS_SILICON (SYS_BASE_ADDR_SILICON + 0x09000000)
96#define PAC_SHARED_MEMORY_SILICON (PAC_BASE_ADDRESS_SILICON)
97
98#define CW1200_APB(addr) (PAC_SHARED_MEMORY_SILICON + (addr))
99
100/* ***************************************************************
101*Device register definitions
102*************************************************************** */
103/* WBF - SPI Register Addresses */
104#define ST90TDS_ADDR_ID_BASE (0x0000)
105/* 16/32 bits */
106#define ST90TDS_CONFIG_REG_ID (0x0000)
107/* 16/32 bits */
108#define ST90TDS_CONTROL_REG_ID (0x0001)
109/* 16 bits, Q mode W/R */
110#define ST90TDS_IN_OUT_QUEUE_REG_ID (0x0002)
111/* 32 bits, AHB bus R/W */
112#define ST90TDS_AHB_DPORT_REG_ID (0x0003)
113/* 16/32 bits */
114#define ST90TDS_SRAM_BASE_ADDR_REG_ID (0x0004)
115/* 32 bits, APB bus R/W */
116#define ST90TDS_SRAM_DPORT_REG_ID (0x0005)
117/* 32 bits, t_settle/general */
118#define ST90TDS_TSET_GEN_R_W_REG_ID (0x0006)
119/* 16 bits, Q mode read, no length */
120#define ST90TDS_FRAME_OUT_REG_ID (0x0007)
121#define ST90TDS_ADDR_ID_MAX (ST90TDS_FRAME_OUT_REG_ID)
122
123/* WBF - Control register bit set */
124/* next o/p length, bit 11 to 0 */
125#define ST90TDS_CONT_NEXT_LEN_MASK (0x0FFF)
126#define ST90TDS_CONT_WUP_BIT (BIT(12))
127#define ST90TDS_CONT_RDY_BIT (BIT(13))
128#define ST90TDS_CONT_IRQ_ENABLE (BIT(14))
129#define ST90TDS_CONT_RDY_ENABLE (BIT(15))
130#define ST90TDS_CONT_IRQ_RDY_ENABLE (BIT(14)|BIT(15))
131
132/* SPI Config register bit set */
133#define ST90TDS_CONFIG_FRAME_BIT (BIT(2))
134#define ST90TDS_CONFIG_WORD_MODE_BITS (BIT(3)|BIT(4))
135#define ST90TDS_CONFIG_WORD_MODE_1 (BIT(3))
136#define ST90TDS_CONFIG_WORD_MODE_2 (BIT(4))
137#define ST90TDS_CONFIG_ERROR_0_BIT (BIT(5))
138#define ST90TDS_CONFIG_ERROR_1_BIT (BIT(6))
139#define ST90TDS_CONFIG_ERROR_2_BIT (BIT(7))
140/* TBD: Sure??? */
141#define ST90TDS_CONFIG_CSN_FRAME_BIT (BIT(7))
142#define ST90TDS_CONFIG_ERROR_3_BIT (BIT(8))
143#define ST90TDS_CONFIG_ERROR_4_BIT (BIT(9))
144/* QueueM */
145#define ST90TDS_CONFIG_ACCESS_MODE_BIT (BIT(10))
146/* AHB bus */
147#define ST90TDS_CONFIG_AHB_PRFETCH_BIT (BIT(11))
148#define ST90TDS_CONFIG_CPU_CLK_DIS_BIT (BIT(12))
149/* APB bus */
150#define ST90TDS_CONFIG_PRFETCH_BIT (BIT(13))
151/* cpu reset */
152#define ST90TDS_CONFIG_CPU_RESET_BIT (BIT(14))
153#define ST90TDS_CONFIG_CLEAR_INT_BIT (BIT(15))
154
155/* For CW1200 the IRQ Enable and Ready Bits are in CONFIG register */
156#define ST90TDS_CONF_IRQ_ENABLE (BIT(16))
157#define ST90TDS_CONF_RDY_ENABLE (BIT(17))
158#define ST90TDS_CONF_IRQ_RDY_ENABLE (BIT(16)|BIT(17))
159
160int cw1200_data_read(struct cw1200_common *priv,
161 void *buf, size_t buf_len);
162int cw1200_data_write(struct cw1200_common *priv,
163 const void *buf, size_t buf_len);
164
165int cw1200_reg_read(struct cw1200_common *priv, u16 addr,
166 void *buf, size_t buf_len);
167int cw1200_reg_write(struct cw1200_common *priv, u16 addr,
168 const void *buf, size_t buf_len);
169
170static inline int cw1200_reg_read_16(struct cw1200_common *priv,
171 u16 addr, u16 *val)
172{
173 u32 tmp;
174 int i;
175 i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
176 tmp = le32_to_cpu(tmp);
177 *val = tmp & 0xffff;
178 return i;
179}
180
181static inline int cw1200_reg_write_16(struct cw1200_common *priv,
182 u16 addr, u16 val)
183{
184 u32 tmp = val;
185 tmp = cpu_to_le32(tmp);
186 return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp));
187}
188
189static inline int cw1200_reg_read_32(struct cw1200_common *priv,
190 u16 addr, u32 *val)
191{
192 int i = cw1200_reg_read(priv, addr, val, sizeof(*val));
193 *val = le32_to_cpu(*val);
194 return i;
195}
196
197static inline int cw1200_reg_write_32(struct cw1200_common *priv,
198 u16 addr, u32 val)
199{
200 val = cpu_to_le32(val);
201 return cw1200_reg_write(priv, addr, &val, sizeof(val));
202}
203
204int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
205 size_t buf_len, u32 prefetch, u16 port_addr);
206int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
207 size_t buf_len);
208
209static inline int cw1200_apb_read(struct cw1200_common *priv, u32 addr,
210 void *buf, size_t buf_len)
211{
212 return cw1200_indirect_read(priv, addr, buf, buf_len,
213 ST90TDS_CONFIG_PRFETCH_BIT,
214 ST90TDS_SRAM_DPORT_REG_ID);
215}
216
217static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr,
218 void *buf, size_t buf_len)
219{
220 return cw1200_indirect_read(priv, addr, buf, buf_len,
221 ST90TDS_CONFIG_AHB_PRFETCH_BIT,
222 ST90TDS_AHB_DPORT_REG_ID);
223}
224
225static inline int cw1200_apb_read_32(struct cw1200_common *priv,
226 u32 addr, u32 *val)
227{
228 int i = cw1200_apb_read(priv, addr, val, sizeof(*val));
229 *val = le32_to_cpu(*val);
230 return i;
231}
232
233static inline int cw1200_apb_write_32(struct cw1200_common *priv,
234 u32 addr, u32 val)
235{
236 val = cpu_to_le32(val);
237 return cw1200_apb_write(priv, addr, &val, sizeof(val));
238}
239static inline int cw1200_ahb_read_32(struct cw1200_common *priv,
240 u32 addr, u32 *val)
241{
242 int i = cw1200_ahb_read(priv, addr, val, sizeof(*val));
243 *val = le32_to_cpu(*val);
244 return i;
245}
246
247#endif /* CW1200_HWIO_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/itp.c b/drivers/net/wireless/cw1200/itp.c
new file mode 100644
index 000000000000..c0730bb49b75
--- /dev/null
+++ b/drivers/net/wireless/cw1200/itp.c
@@ -0,0 +1,730 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 * ITP code
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/debugfs.h>
15#include <linux/poll.h>
16#include <linux/time.h>
17#include <linux/random.h>
18#include <linux/kallsyms.h>
19#include <net/mac80211.h>
20#include "cw1200.h"
21#include "debug.h"
22#include "itp.h"
23#include "sta.h"
24
25static int __cw1200_itp_open(struct cw1200_common *priv);
26static int __cw1200_itp_close(struct cw1200_common *priv);
27static void cw1200_itp_rx_start(struct cw1200_common *priv);
28static void cw1200_itp_rx_stop(struct cw1200_common *priv);
29static void cw1200_itp_rx_stats(struct cw1200_common *priv);
30static void cw1200_itp_rx_reset(struct cw1200_common *priv);
31static void cw1200_itp_tx_stop(struct cw1200_common *priv);
32static void cw1200_itp_handle(struct cw1200_common *priv,
33 struct sk_buff *skb);
34static void cw1200_itp_err(struct cw1200_common *priv,
35 int err,
36 int arg);
37static void __cw1200_itp_tx_stop(struct cw1200_common *priv);
38
39static ssize_t cw1200_itp_read(struct file *file,
40 char __user *user_buf, size_t count, loff_t *ppos)
41{
42 struct cw1200_common *priv = file->private_data;
43 struct cw1200_itp *itp = &priv->debug->itp;
44 struct sk_buff *skb;
45 int ret;
46
47 if (skb_queue_empty(&itp->log_queue))
48 return 0;
49
50 skb = skb_dequeue(&itp->log_queue);
51 ret = copy_to_user(user_buf, skb->data, skb->len);
52 *ppos += skb->len;
53 skb->data[skb->len] = 0;
54 pr_debug("[ITP] >>> %s", skb->data);
55 consume_skb(skb);
56
57 return skb->len - ret;
58}
59
60static ssize_t cw1200_itp_write(struct file *file,
61 const char __user *user_buf, size_t count, loff_t *ppos)
62{
63 struct cw1200_common *priv = file->private_data;
64 struct sk_buff *skb;
65
66 if (!count || count > 1024)
67 return -EINVAL;
68 skb = dev_alloc_skb(count + 1);
69 if (!skb)
70 return -ENOMEM;
71 skb_trim(skb, 0);
72 skb_put(skb, count + 1);
73 if (copy_from_user(skb->data, user_buf, count)) {
74 kfree_skb(skb);
75 return -EFAULT;
76 }
77 skb->data[count] = 0;
78
79 cw1200_itp_handle(priv, skb);
80 consume_skb(skb);
81 return count;
82}
83
84static unsigned int cw1200_itp_poll(struct file *file, poll_table *wait)
85{
86 struct cw1200_common *priv = file->private_data;
87 struct cw1200_itp *itp = &priv->debug->itp;
88 unsigned int mask = 0;
89
90 poll_wait(file, &itp->read_wait, wait);
91
92 if (!skb_queue_empty(&itp->log_queue))
93 mask |= POLLIN | POLLRDNORM;
94
95 mask |= POLLOUT | POLLWRNORM;
96
97 return mask;
98}
99
100static int cw1200_itp_open(struct inode *inode, struct file *file)
101{
102 struct cw1200_common *priv = inode->i_private;
103 struct cw1200_itp *itp = &priv->debug->itp;
104 int ret = 0;
105
106 file->private_data = priv;
107 if (atomic_inc_return(&itp->open_count) == 1) {
108 ret = __cw1200_itp_open(priv);
109 if (ret && !atomic_dec_return(&itp->open_count))
110 __cw1200_itp_close(priv);
111 } else {
112 atomic_dec(&itp->open_count);
113 ret = -EBUSY;
114 }
115
116 return ret;
117}
118
119static int cw1200_itp_close(struct inode *inode, struct file *file)
120{
121 struct cw1200_common *priv = file->private_data;
122 struct cw1200_itp *itp = &priv->debug->itp;
123 if (!atomic_dec_return(&itp->open_count)) {
124 __cw1200_itp_close(priv);
125 wake_up(&itp->close_wait);
126 }
127 return 0;
128}
129
130static const struct file_operations fops_itp = {
131 .open = cw1200_itp_open,
132 .read = cw1200_itp_read,
133 .write = cw1200_itp_write,
134 .poll = cw1200_itp_poll,
135 .release = cw1200_itp_close,
136 .llseek = default_llseek,
137 .owner = THIS_MODULE,
138};
139
140static void cw1200_itp_fill_pattern(u8 *data, int size,
141 enum cw1200_itp_data_modes mode)
142{
143 if (size <= 0)
144 return;
145
146 switch (mode) {
147 default:
148 case ITP_DATA_ZEROS:
149 memset(data, 0x0, size);
150 break;
151 case ITP_DATA_ONES:
152 memset(data, 0xff, size);
153 break;
154 case ITP_DATA_ZERONES:
155 memset(data, 0x55, size);
156 break;
157 case ITP_DATA_RANDOM:
158 get_random_bytes(data, size);
159 break;
160 }
161 return;
162}
163
164static void cw1200_itp_tx_work(struct work_struct *work)
165{
166 struct cw1200_itp *itp = container_of(work, struct cw1200_itp,
167 tx_work.work);
168 struct cw1200_common *priv = itp->priv;
169 atomic_set(&priv->bh_tx, 1);
170 wake_up(&priv->bh_wq);
171}
172
173static void cw1200_itp_tx_finish(struct work_struct *work)
174{
175 struct cw1200_itp *itp = container_of(work, struct cw1200_itp,
176 tx_finish.work);
177 __cw1200_itp_tx_stop(itp->priv);
178}
179
180int cw1200_itp_init(struct cw1200_common *priv)
181{
182 struct cw1200_itp *itp = &priv->debug->itp;
183
184 itp->priv = priv;
185 atomic_set(&itp->open_count, 0);
186 atomic_set(&itp->stop_tx, 0);
187 atomic_set(&itp->awaiting_confirm, 0);
188 skb_queue_head_init(&itp->log_queue);
189 spin_lock_init(&itp->tx_lock);
190 init_waitqueue_head(&itp->read_wait);
191 init_waitqueue_head(&itp->write_wait);
192 init_waitqueue_head(&itp->close_wait);
193 INIT_DELAYED_WORK(&itp->tx_work, cw1200_itp_tx_work);
194 INIT_DELAYED_WORK(&itp->tx_finish, cw1200_itp_tx_finish);
195 itp->data = NULL;
196 itp->hdr_len = WSM_TX_EXTRA_HEADROOM +
197 sizeof(struct ieee80211_hdr_3addr);
198
199 if (!debugfs_create_file("itp", S_IRUSR | S_IWUSR,
200 priv->debug->debugfs_phy, priv, &fops_itp))
201 return -ENOMEM;
202
203 return 0;
204}
205
206void cw1200_itp_release(struct cw1200_common *priv)
207{
208 struct cw1200_itp *itp = &priv->debug->itp;
209
210 wait_event_interruptible(itp->close_wait,
211 !atomic_read(&itp->open_count));
212
213 WARN_ON(atomic_read(&itp->open_count));
214
215 skb_queue_purge(&itp->log_queue);
216 cw1200_itp_tx_stop(priv);
217}
218
219static int __cw1200_itp_open(struct cw1200_common *priv)
220{
221 struct cw1200_itp *itp = &priv->debug->itp;
222
223 if (!priv->vif)
224 return -EINVAL;
225 if (priv->join_status)
226 return -EINVAL;
227 itp->saved_channel = priv->channel;
228 if (!priv->channel)
229 priv->channel = &priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
230 wsm_set_bssid_filtering(priv, false);
231 cw1200_itp_rx_reset(priv);
232 return 0;
233}
234
235static int __cw1200_itp_close(struct cw1200_common *priv)
236{
237 struct cw1200_itp *itp = &priv->debug->itp;
238 if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST)
239 cw1200_itp_rx_stop(priv);
240 cw1200_itp_tx_stop(priv);
241 cw1200_disable_listening(priv);
242 cw1200_update_filtering(priv);
243 priv->channel = itp->saved_channel;
244 return 0;
245}
246
247bool cw1200_is_itp(struct cw1200_common *priv)
248{
249 struct cw1200_itp *itp = &priv->debug->itp;
250 return atomic_read(&itp->open_count) != 0;
251}
252
253static void cw1200_itp_rx_reset(struct cw1200_common *priv)
254{
255 struct cw1200_itp *itp = &priv->debug->itp;
256 itp->rx_cnt = 0;
257 itp->rx_rssi = 0;
258 itp->rx_rssi_max = -1000;
259 itp->rx_rssi_min = 1000;
260}
261
262static void cw1200_itp_rx_start(struct cw1200_common *priv)
263{
264 struct cw1200_itp *itp = &priv->debug->itp;
265
266 pr_debug("[ITP] RX start, band = %d, ch = %d\n",
267 itp->band, itp->ch);
268 atomic_set(&itp->test_mode, TEST_MODE_RX_TEST);
269 cw1200_update_listening(priv, false);
270 priv->channel = &priv->hw->
271 wiphy->bands[itp->band]->channels[itp->ch];
272 cw1200_update_listening(priv, true);
273 wsm_set_bssid_filtering(priv, false);
274}
275
276static void cw1200_itp_rx_stop(struct cw1200_common *priv)
277{
278 struct cw1200_itp *itp = &priv->debug->itp;
279 pr_debug("[ITP] RX stop\n");
280 atomic_set(&itp->test_mode, TEST_MODE_NO_TEST);
281 cw1200_itp_rx_reset(priv);
282}
283
284static void cw1200_itp_rx_stats(struct cw1200_common *priv)
285{
286 struct cw1200_itp *itp = &priv->debug->itp;
287 struct sk_buff *skb;
288 char buf[128];
289 int len, ret;
290 struct wsm_mib_counters_table counters;
291
292 ret = wsm_get_counters_table(priv, &counters);
293
294 if (ret)
295 cw1200_itp_err(priv, -EBUSY, 20);
296
297 if (!itp->rx_cnt)
298 len = snprintf(buf, sizeof(buf), "1,0,0,0,0,%d\n",
299 counters.rx_packet_errors);
300 else
301 len = snprintf(buf, sizeof(buf), "1,%d,%ld,%d,%d,%d\n",
302 itp->rx_cnt,
303 itp->rx_cnt ? itp->rx_rssi / itp->rx_cnt : 0,
304 itp->rx_rssi_min, itp->rx_rssi_max,
305 counters.rx_packet_errors);
306
307 if (len <= 0) {
308 cw1200_itp_err(priv, -EBUSY, 21);
309 return;
310 }
311
312 skb = dev_alloc_skb(len);
313 if (!skb) {
314 cw1200_itp_err(priv, -ENOMEM, 22);
315 return;
316 }
317
318 itp->rx_cnt = 0;
319 itp->rx_rssi = 0;
320 itp->rx_rssi_max = -1000;
321 itp->rx_rssi_min = 1000;
322
323 skb_trim(skb, 0);
324 skb_put(skb, len);
325
326 memcpy(skb->data, buf, len);
327 skb_queue_tail(&itp->log_queue, skb);
328 wake_up(&itp->read_wait);
329}
330
331static void cw1200_itp_tx_start(struct cw1200_common *priv)
332{
333 struct wsm_tx *tx;
334 struct ieee80211_hdr_3addr *hdr;
335 struct cw1200_itp *itp = &priv->debug->itp;
336 struct wsm_mib_association_mode assoc_mode = {
337 .flags = WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE,
338 .preamble = itp->preamble,
339 };
340 int len;
341 u8 da_addr[6] = ITP_DEFAULT_DA_ADDR;
342
343 /* Rates index 4 and 5 are not supported */
344 if (itp->rate > 3)
345 itp->rate += 2;
346
347 pr_debug("[ITP] TX start: band = %d, ch = %d, rate = %d, preamble = %d, number = %d, data_mode = %d, interval = %d, power = %d, data_len = %d\n",
348 itp->band, itp->ch, itp->rate, itp->preamble,
349 itp->number, itp->data_mode, itp->interval_us,
350 itp->power, itp->data_len);
351
352 len = itp->hdr_len + itp->data_len;
353
354 itp->data = kmalloc(len, GFP_KERNEL);
355 tx = (struct wsm_tx *)itp->data;
356 tx->hdr.len = itp->data_len + itp->hdr_len;
357 tx->hdr.id = __cpu_to_le16(0x0004 | 1 << 6);
358 tx->max_tx_rate = itp->rate;
359 tx->queue_id = 3;
360 tx->more = 0;
361 tx->flags = 0xc;
362 tx->packet_id = 0x55ff55;
363 tx->reserved = 0;
364 tx->expire_time = 1;
365
366 if (itp->preamble == ITP_PREAMBLE_GREENFIELD)
367 tx->ht_tx_parameters = WSM_HT_TX_GREENFIELD;
368 else if (itp->preamble == ITP_PREAMBLE_MIXED)
369 tx->ht_tx_parameters = WSM_HT_TX_MIXED;
370
371 hdr = (struct ieee80211_hdr_3addr *)&itp->data[sizeof(struct wsm_tx)];
372 memset(hdr, 0, sizeof(*hdr));
373 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
374 memcpy(hdr->addr1, da_addr, ETH_ALEN);
375 memcpy(hdr->addr2, priv->vif->addr, ETH_ALEN);
376 memcpy(hdr->addr3, da_addr, ETH_ALEN);
377
378 cw1200_itp_fill_pattern(&itp->data[itp->hdr_len],
379 itp->data_len, itp->data_mode);
380
381 cw1200_update_listening(priv, false);
382 priv->channel = &priv->hw->wiphy->bands[itp->band]->channels[itp->ch];
383 WARN_ON(wsm_set_output_power(priv, itp->power));
384 if (itp->preamble == ITP_PREAMBLE_SHORT ||
385 itp->preamble == ITP_PREAMBLE_LONG)
386 WARN_ON(wsm_set_association_mode(priv,
387 &assoc_mode));
388 wsm_set_bssid_filtering(priv, false);
389 cw1200_update_listening(priv, true);
390
391 spin_lock_bh(&itp->tx_lock);
392 atomic_set(&itp->test_mode, TEST_MODE_TX_TEST);
393 atomic_set(&itp->awaiting_confirm, 0);
394 atomic_set(&itp->stop_tx, 0);
395 atomic_set(&priv->bh_tx, 1);
396 ktime_get_ts(&itp->last_sent);
397 wake_up(&priv->bh_wq);
398 spin_unlock_bh(&itp->tx_lock);
399}
400
401void __cw1200_itp_tx_stop(struct cw1200_common *priv)
402{
403 struct cw1200_itp *itp = &priv->debug->itp;
404 spin_lock_bh(&itp->tx_lock);
405 kfree(itp->data);
406 itp->data = NULL;
407 atomic_set(&itp->test_mode, TEST_MODE_NO_TEST);
408 spin_unlock_bh(&itp->tx_lock);
409}
410
411static void cw1200_itp_tx_stop(struct cw1200_common *priv)
412{
413 struct cw1200_itp *itp = &priv->debug->itp;
414 pr_debug("[ITP] TX stop\n");
415 atomic_set(&itp->stop_tx, 1);
416 flush_workqueue(priv->workqueue);
417
418 /* time for FW to confirm all tx requests */
419 msleep(500);
420
421 __cw1200_itp_tx_stop(priv);
422}
423
424static int cw1200_print_fw_version(struct cw1200_common *priv,
425 u8 *buf, size_t len)
426{
427 return snprintf(buf, len, "%s %d.%d",
428 cw1200_fw_types[priv->wsm_caps.fw_type],
429 priv->wsm_caps.fw_ver,
430 priv->wsm_caps.fw_build);
431}
432
433static void cw1200_itp_get_version(struct cw1200_common *priv,
434 enum cw1200_itp_version_type type)
435{
436 struct cw1200_itp *itp = &priv->debug->itp;
437 struct sk_buff *skb;
438 char buf[ITP_BUF_SIZE];
439 size_t size = 0;
440 int len;
441 pr_debug("[ITP] print %s version\n",
442 type == ITP_CHIP_ID ? "chip" : "firmware");
443
444 len = snprintf(buf, ITP_BUF_SIZE, "2,");
445 if (len <= 0) {
446 cw1200_itp_err(priv, -EINVAL, 40);
447 return;
448 }
449 size += len;
450
451 switch (type) {
452 case ITP_CHIP_ID:
453 len = cw1200_print_fw_version(priv, buf+size,
454 ITP_BUF_SIZE - size);
455
456 if (len <= 0) {
457 cw1200_itp_err(priv, -EINVAL, 41);
458 return;
459 }
460 size += len;
461 break;
462 case ITP_FW_VER:
463 len = snprintf(buf+size, ITP_BUF_SIZE - size,
464 "%d.%d", priv->wsm_caps.hw_id,
465 priv->wsm_caps.hw_subid);
466 if (len <= 0) {
467 cw1200_itp_err(priv, -EINVAL, 42);
468 return;
469 }
470 size += len;
471 break;
472 default:
473 cw1200_itp_err(priv, -EINVAL, 43);
474 break;
475 }
476
477 len = snprintf(buf+size, ITP_BUF_SIZE-size, "\n");
478 if (len <= 0) {
479 cw1200_itp_err(priv, -EINVAL, 44);
480 return;
481 }
482 size += len;
483
484 skb = dev_alloc_skb(size);
485 if (!skb) {
486 cw1200_itp_err(priv, -ENOMEM, 45);
487 return;
488 }
489
490 skb_trim(skb, 0);
491 skb_put(skb, size);
492
493 memcpy(skb->data, buf, size);
494 skb_queue_tail(&itp->log_queue, skb);
495 wake_up(&itp->read_wait);
496}
497
498int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
499 size_t *tx_len, int *burst)
500{
501 struct cw1200_itp *itp;
502 struct timespec now;
503 int time_left_us;
504
505 if (!priv->debug)
506 return 0;
507
508 itp = &priv->debug->itp;
509
510 if (!itp)
511 return 0;
512
513 spin_lock_bh(&itp->tx_lock);
514 if (atomic_read(&itp->test_mode) != TEST_MODE_TX_TEST)
515 goto out;
516
517 if (atomic_read(&itp->stop_tx))
518 goto out;
519
520 if (itp->number == 0) {
521 atomic_set(&itp->stop_tx, 1);
522 queue_delayed_work(priv->workqueue, &itp->tx_finish, HZ/10);
523 goto out;
524 }
525
526 if (!itp->data)
527 goto out;
528
529 if (priv->hw_bufs_used >= 2) {
530 if (!atomic_read(&priv->bh_rx))
531 atomic_set(&priv->bh_rx, 1);
532 atomic_set(&priv->bh_tx, 1);
533 goto out;
534 }
535
536 ktime_get_ts(&now);
537 time_left_us = (itp->last_sent.tv_sec - now.tv_sec)*1000000 +
538 (itp->last_sent.tv_nsec - now.tv_nsec)/1000 +
539 itp->interval_us;
540
541 if (time_left_us > ITP_TIME_THRES_US) {
542 queue_delayed_work(priv->workqueue, &itp->tx_work,
543 ITP_US_TO_MS(time_left_us)*HZ/1000);
544 goto out;
545 }
546
547 if (time_left_us > 50)
548 udelay(time_left_us);
549
550 if (itp->number > 0)
551 itp->number--;
552
553 *data = itp->data;
554 *tx_len = itp->data_len + itp->hdr_len;
555
556 if (itp->data_mode == ITP_DATA_RANDOM)
557 cw1200_itp_fill_pattern(&itp->data[itp->hdr_len],
558 itp->data_len, itp->data_mode);
559 *burst = 2;
560 atomic_set(&priv->bh_tx, 1);
561 ktime_get_ts(&itp->last_sent);
562 atomic_add(1, &itp->awaiting_confirm);
563 spin_unlock_bh(&itp->tx_lock);
564 return 1;
565
566out:
567 spin_unlock_bh(&itp->tx_lock);
568 return 0;
569}
570
571bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb)
572{
573 struct cw1200_itp *itp = &priv->debug->itp;
574 struct ieee80211_rx_status *rx = IEEE80211_SKB_RXCB(skb);
575 int signal;
576
577 if (atomic_read(&itp->test_mode) != TEST_MODE_RX_TEST)
578 return cw1200_is_itp(priv);
579 if (rx->freq != priv->channel->center_freq)
580 return true;
581
582 signal = rx->signal;
583 itp->rx_cnt++;
584 itp->rx_rssi += signal;
585 if (itp->rx_rssi_min > rx->signal)
586 itp->rx_rssi_min = rx->signal;
587 if (itp->rx_rssi_max < rx->signal)
588 itp->rx_rssi_max = rx->signal;
589
590 return true;
591}
592
593void cw1200_itp_wake_up_tx(struct cw1200_common *priv)
594{
595 wake_up(&priv->debug->itp.write_wait);
596}
597
598bool cw1200_itp_tx_running(struct cw1200_common *priv)
599{
600 if (atomic_read(&priv->debug->itp.awaiting_confirm) ||
601 atomic_read(&priv->debug->itp.test_mode) ==
602 TEST_MODE_TX_TEST) {
603 atomic_sub(1, &priv->debug->itp.awaiting_confirm);
604 return true;
605 }
606 return false;
607}
608
609static void cw1200_itp_handle(struct cw1200_common *priv,
610 struct sk_buff *skb)
611{
612 struct cw1200_itp *itp = &priv->debug->itp;
613 const struct wiphy *wiphy = priv->hw->wiphy;
614 int cmd;
615 int ret;
616
617 pr_debug("[ITP] <<< %s", skb->data);
618 if (sscanf(skb->data, "%d", &cmd) != 1) {
619 cw1200_itp_err(priv, -EINVAL, 1);
620 return;
621 }
622
623 switch (cmd) {
624 case 1: /* RX test */
625 if (atomic_read(&itp->test_mode)) {
626 cw1200_itp_err(priv, -EBUSY, 0);
627 return;
628 }
629 ret = sscanf(skb->data, "%d,%d,%d",
630 &cmd, &itp->band, &itp->ch);
631 if (ret != 3) {
632 cw1200_itp_err(priv, -EINVAL, ret + 1);
633 return;
634 }
635 if (itp->band >= 2) {
636 cw1200_itp_err(priv, -EINVAL, 2);
637 } else if (!wiphy->bands[itp->band]) {
638 cw1200_itp_err(priv, -EINVAL, 2);
639 } else if (itp->ch >= wiphy->bands[itp->band]->n_channels) {
640 cw1200_itp_err(priv, -EINVAL, 3);
641 } else {
642 cw1200_itp_rx_stats(priv);
643 cw1200_itp_rx_start(priv);
644 }
645 break;
646 case 2: /* RX stat */
647 cw1200_itp_rx_stats(priv);
648 break;
649 case 3: /* RX/TX stop */
650 if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST) {
651 cw1200_itp_rx_stats(priv);
652 cw1200_itp_rx_stop(priv);
653 } else if (atomic_read(&itp->test_mode) == TEST_MODE_TX_TEST) {
654 cw1200_itp_tx_stop(priv);
655 } else {
656 cw1200_itp_err(priv, -EBUSY, 0);
657 }
658 break;
659 case 4: /* TX start */
660 if (atomic_read(&itp->test_mode) != TEST_MODE_NO_TEST) {
661 cw1200_itp_err(priv, -EBUSY, 0);
662 return;
663 }
664 ret = sscanf(skb->data, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
665 &cmd, &itp->band, &itp->ch, &itp->rate,
666 &itp->preamble, &itp->number, &itp->data_mode,
667 &itp->interval_us, &itp->power, &itp->data_len);
668 if (ret != 10) {
669 cw1200_itp_err(priv, -EINVAL, ret + 1);
670 return;
671 }
672 if (itp->band >= 2) {
673 cw1200_itp_err(priv, -EINVAL, 2);
674 } else if (!wiphy->bands[itp->band]) {
675 cw1200_itp_err(priv, -EINVAL, 2);
676 } else if (itp->ch >= wiphy->bands[itp->band]->n_channels) {
677 cw1200_itp_err(priv, -EINVAL, 3);
678 } else if (itp->rate >= 20) {
679 cw1200_itp_err(priv, -EINVAL, 4);
680 } else if (itp->preamble >= ITP_PREAMBLE_MAX) {
681 cw1200_itp_err(priv, -EINVAL, 5);
682 } else if (itp->data_mode >= ITP_DATA_MAX_MODE) {
683 cw1200_itp_err(priv, -EINVAL, 7);
684 } else if (itp->data_len < ITP_MIN_DATA_SIZE ||
685 itp->data_len > (priv->wsm_caps.input_buffer_size - itp->hdr_len)) {
686 cw1200_itp_err(priv, -EINVAL, 8);
687 } else {
688 cw1200_itp_tx_start(priv);
689 }
690 break;
691 case 5:
692 cw1200_itp_get_version(priv, ITP_CHIP_ID);
693 break;
694 case 6:
695 cw1200_itp_get_version(priv, ITP_FW_VER);
696 break;
697 }
698}
699
700static void cw1200_itp_err(struct cw1200_common *priv,
701 int err, int arg)
702{
703 struct cw1200_itp *itp = &priv->debug->itp;
704 struct sk_buff *skb;
705 static char buf[255];
706 int len;
707
708 len = snprintf(buf, sizeof(buf), "%d,%d\n",
709 err, arg);
710 if (len <= 0)
711 return;
712
713 skb = dev_alloc_skb(len);
714 if (!skb)
715 return;
716
717 skb_trim(skb, 0);
718 skb_put(skb, len);
719
720 memcpy(skb->data, buf, len);
721 skb_queue_tail(&itp->log_queue, skb);
722 wake_up(&itp->read_wait);
723
724 len = sprint_symbol(buf,
725 (unsigned long)__builtin_return_address(0));
726 if (len <= 0)
727 return;
728 pr_debug("[ITP] error %d,%d from %s\n",
729 err, arg, buf);
730}
diff --git a/drivers/net/wireless/cw1200/itp.h b/drivers/net/wireless/cw1200/itp.h
new file mode 100644
index 000000000000..1e9dfb7fcadc
--- /dev/null
+++ b/drivers/net/wireless/cw1200/itp.h
@@ -0,0 +1,144 @@
1/*
2 * ITP code for ST-Ericsson CW1200 mac80211 driver
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_ITP_H_INCLUDED
13#define CW1200_ITP_H_INCLUDED
14
15struct cw200_common;
16struct wsm_tx_confirm;
17struct dentry;
18
19#ifdef CONFIG_CW1200_ITP
20
21/*extern*/ struct ieee80211_channel;
22
23#define TEST_MODE_NO_TEST (0)
24#define TEST_MODE_RX_TEST (1)
25#define TEST_MODE_TX_TEST (2)
26#define ITP_DEFAULT_DA_ADDR {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
27#define ITP_MIN_DATA_SIZE 6
28#define ITP_MAX_DATA_SIZE 1600
29#define ITP_TIME_THRES_US 10000
30#define ITP_US_TO_MS(x) ((x)/1000)
31#define ITP_MS_TO_US(x) ((x)*1000)
32#define ITP_BUF_SIZE 255
33
34
35enum cw1200_itp_data_modes {
36 ITP_DATA_ZEROS,
37 ITP_DATA_ONES,
38 ITP_DATA_ZERONES,
39 ITP_DATA_RANDOM,
40 ITP_DATA_MAX_MODE,
41};
42
43enum cw1200_itp_version_type {
44 ITP_CHIP_ID,
45 ITP_FW_VER,
46};
47
48enum cw1200_itp_preamble_type {
49 ITP_PREAMBLE_LONG,
50 ITP_PREAMBLE_SHORT,
51 ITP_PREAMBLE_OFDM,
52 ITP_PREAMBLE_MIXED,
53 ITP_PREAMBLE_GREENFIELD,
54 ITP_PREAMBLE_MAX,
55};
56
57
58struct cw1200_itp {
59 struct cw1200_common *priv;
60 atomic_t open_count;
61 atomic_t awaiting_confirm;
62 struct sk_buff_head log_queue;
63 wait_queue_head_t read_wait;
64 wait_queue_head_t write_wait;
65 wait_queue_head_t close_wait;
66 struct ieee80211_channel *saved_channel;
67 atomic_t stop_tx;
68 struct delayed_work tx_work;
69 struct delayed_work tx_finish;
70 spinlock_t tx_lock;
71 struct timespec last_sent;
72 atomic_t test_mode;
73 int rx_cnt;
74 long rx_rssi;
75 int rx_rssi_max;
76 int rx_rssi_min;
77 unsigned band;
78 unsigned ch;
79 unsigned rate;
80 unsigned preamble;
81 unsigned int number;
82 unsigned data_mode;
83 int interval_us;
84 int power;
85 u8 *data;
86 int hdr_len;
87 int data_len;
88};
89
90int cw1200_itp_init(struct cw1200_common *priv);
91void cw1200_itp_release(struct cw1200_common *priv);
92
93bool cw1200_is_itp(struct cw1200_common *priv);
94bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb);
95void cw1200_itp_wake_up_tx(struct cw1200_common *priv);
96int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
97 size_t *tx_len, int *burst);
98bool cw1200_itp_tx_running(struct cw1200_common *priv);
99
100#else /* CONFIG_CW1200_ITP */
101
102static inline int cw1200_itp_init(struct cw1200_common *priv)
103{
104 return 0;
105}
106
107static inline void cw1200_itp_release(struct cw1200_common *priv)
108{
109}
110
111static inline bool cw1200_is_itp(struct cw1200_common *priv)
112{
113 return false;
114}
115
116static inline bool cw1200_itp_rxed(struct cw1200_common *priv,
117 struct sk_buff *skb)
118{
119 return false;
120}
121
122
123static inline void cw1200_itp_consume_txed(struct cw1200_common *priv)
124{
125}
126
127static inline void cw1200_itp_wake_up_tx(struct cw1200_common *priv)
128{
129}
130
131static inline int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
132 size_t *tx_len, int *burst)
133{
134 return 0;
135}
136
137static inline bool cw1200_itp_tx_running(struct cw1200_common *priv)
138{
139 return false;
140}
141
142#endif /* CONFIG_CW1200_ITP */
143
144#endif /* CW1200_ITP_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
new file mode 100644
index 000000000000..8426d3d7607e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/main.c
@@ -0,0 +1,618 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
10 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
11 *
12 * Based on:
13 * - the islsm (softmac prism54) driver, which is:
14 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
15 * - stlc45xx driver
16 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/firmware.h>
26#include <linux/etherdevice.h>
27#include <linux/vmalloc.h>
28#include <linux/random.h>
29#include <linux/sched.h>
30#include <net/mac80211.h>
31
32#include "cw1200.h"
33#include "txrx.h"
34#include "sbus.h"
35#include "fwio.h"
36#include "hwio.h"
37#include "bh.h"
38#include "sta.h"
39#include "scan.h"
40#include "debug.h"
41#include "pm.h"
42
43MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
44MODULE_DESCRIPTION("Softmac ST-Ericsson CW1200 common code");
45MODULE_LICENSE("GPL");
46MODULE_ALIAS("cw1200_core");
47
48/* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */
49static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
50module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, S_IRUGO);
51MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
52
53static char *cw1200_sdd_path;
54module_param(cw1200_sdd_path, charp, 0644);
55MODULE_PARM_DESC(cw1200_sdd_path, "Override platform_data SDD file");
56static int cw1200_refclk;
57module_param(cw1200_refclk, int, 0644);
58MODULE_PARM_DESC(cw1200_refclk, "Override platform_data reference clock");
59
60int cw1200_power_mode = wsm_power_mode_quiescent;
61module_param(cw1200_power_mode, int, 0644);
62MODULE_PARM_DESC(cw1200_power_mode, "WSM power mode. 0 == active, 1 == doze, 2 == quiescent (default)");
63
64#ifdef CONFIG_CW1200_ETF
65int etf_mode;
66module_param(etf_mode, int, 0644);
67MODULE_PARM_DESC(etf_mode, "Enable EngineeringTestingFramework operation");
68#endif
69
70#define RATETAB_ENT(_rate, _rateid, _flags) \
71 { \
72 .bitrate = (_rate), \
73 .hw_value = (_rateid), \
74 .flags = (_flags), \
75 }
76
77static struct ieee80211_rate cw1200_rates[] = {
78 RATETAB_ENT(10, 0, 0),
79 RATETAB_ENT(20, 1, 0),
80 RATETAB_ENT(55, 2, 0),
81 RATETAB_ENT(110, 3, 0),
82 RATETAB_ENT(60, 6, 0),
83 RATETAB_ENT(90, 7, 0),
84 RATETAB_ENT(120, 8, 0),
85 RATETAB_ENT(180, 9, 0),
86 RATETAB_ENT(240, 10, 0),
87 RATETAB_ENT(360, 11, 0),
88 RATETAB_ENT(480, 12, 0),
89 RATETAB_ENT(540, 13, 0),
90};
91
92static struct ieee80211_rate cw1200_mcs_rates[] = {
93 RATETAB_ENT(65, 14, IEEE80211_TX_RC_MCS),
94 RATETAB_ENT(130, 15, IEEE80211_TX_RC_MCS),
95 RATETAB_ENT(195, 16, IEEE80211_TX_RC_MCS),
96 RATETAB_ENT(260, 17, IEEE80211_TX_RC_MCS),
97 RATETAB_ENT(390, 18, IEEE80211_TX_RC_MCS),
98 RATETAB_ENT(520, 19, IEEE80211_TX_RC_MCS),
99 RATETAB_ENT(585, 20, IEEE80211_TX_RC_MCS),
100 RATETAB_ENT(650, 21, IEEE80211_TX_RC_MCS),
101};
102
103#define cw1200_a_rates (cw1200_rates + 4)
104#define cw1200_a_rates_size (ARRAY_SIZE(cw1200_rates) - 4)
105#define cw1200_g_rates (cw1200_rates + 0)
106#define cw1200_g_rates_size (ARRAY_SIZE(cw1200_rates))
107#define cw1200_n_rates (cw1200_mcs_rates)
108#define cw1200_n_rates_size (ARRAY_SIZE(cw1200_mcs_rates))
109
110
111#define CHAN2G(_channel, _freq, _flags) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (_freq), \
114 .hw_value = (_channel), \
115 .flags = (_flags), \
116 .max_antenna_gain = 0, \
117 .max_power = 30, \
118}
119
120#define CHAN5G(_channel, _flags) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = 5000 + (5 * (_channel)), \
123 .hw_value = (_channel), \
124 .flags = (_flags), \
125 .max_antenna_gain = 0, \
126 .max_power = 30, \
127}
128
129static struct ieee80211_channel cw1200_2ghz_chantable[] = {
130 CHAN2G(1, 2412, 0),
131 CHAN2G(2, 2417, 0),
132 CHAN2G(3, 2422, 0),
133 CHAN2G(4, 2427, 0),
134 CHAN2G(5, 2432, 0),
135 CHAN2G(6, 2437, 0),
136 CHAN2G(7, 2442, 0),
137 CHAN2G(8, 2447, 0),
138 CHAN2G(9, 2452, 0),
139 CHAN2G(10, 2457, 0),
140 CHAN2G(11, 2462, 0),
141 CHAN2G(12, 2467, 0),
142 CHAN2G(13, 2472, 0),
143 CHAN2G(14, 2484, 0),
144};
145
146static struct ieee80211_channel cw1200_5ghz_chantable[] = {
147 CHAN5G(34, 0), CHAN5G(36, 0),
148 CHAN5G(38, 0), CHAN5G(40, 0),
149 CHAN5G(42, 0), CHAN5G(44, 0),
150 CHAN5G(46, 0), CHAN5G(48, 0),
151 CHAN5G(52, 0), CHAN5G(56, 0),
152 CHAN5G(60, 0), CHAN5G(64, 0),
153 CHAN5G(100, 0), CHAN5G(104, 0),
154 CHAN5G(108, 0), CHAN5G(112, 0),
155 CHAN5G(116, 0), CHAN5G(120, 0),
156 CHAN5G(124, 0), CHAN5G(128, 0),
157 CHAN5G(132, 0), CHAN5G(136, 0),
158 CHAN5G(140, 0), CHAN5G(149, 0),
159 CHAN5G(153, 0), CHAN5G(157, 0),
160 CHAN5G(161, 0), CHAN5G(165, 0),
161 CHAN5G(184, 0), CHAN5G(188, 0),
162 CHAN5G(192, 0), CHAN5G(196, 0),
163 CHAN5G(200, 0), CHAN5G(204, 0),
164 CHAN5G(208, 0), CHAN5G(212, 0),
165 CHAN5G(216, 0),
166};
167
168static struct ieee80211_supported_band cw1200_band_2ghz = {
169 .channels = cw1200_2ghz_chantable,
170 .n_channels = ARRAY_SIZE(cw1200_2ghz_chantable),
171 .bitrates = cw1200_g_rates,
172 .n_bitrates = cw1200_g_rates_size,
173 .ht_cap = {
174 .cap = IEEE80211_HT_CAP_GRN_FLD |
175 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
176 IEEE80211_HT_CAP_MAX_AMSDU,
177 .ht_supported = 1,
178 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
179 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
180 .mcs = {
181 .rx_mask[0] = 0xFF,
182 .rx_highest = __cpu_to_le16(0x41),
183 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
184 },
185 },
186};
187
188static struct ieee80211_supported_band cw1200_band_5ghz = {
189 .channels = cw1200_5ghz_chantable,
190 .n_channels = ARRAY_SIZE(cw1200_5ghz_chantable),
191 .bitrates = cw1200_a_rates,
192 .n_bitrates = cw1200_a_rates_size,
193 .ht_cap = {
194 .cap = IEEE80211_HT_CAP_GRN_FLD |
195 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
196 IEEE80211_HT_CAP_MAX_AMSDU,
197 .ht_supported = 1,
198 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
199 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
200 .mcs = {
201 .rx_mask[0] = 0xFF,
202 .rx_highest = __cpu_to_le16(0x41),
203 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
204 },
205 },
206};
207
208static const unsigned long cw1200_ttl[] = {
209 1 * HZ, /* VO */
210 2 * HZ, /* VI */
211 5 * HZ, /* BE */
212 10 * HZ /* BK */
213};
214
215static const struct ieee80211_ops cw1200_ops = {
216 .start = cw1200_start,
217 .stop = cw1200_stop,
218 .add_interface = cw1200_add_interface,
219 .remove_interface = cw1200_remove_interface,
220 .change_interface = cw1200_change_interface,
221 .tx = cw1200_tx,
222 .hw_scan = cw1200_hw_scan,
223 .set_tim = cw1200_set_tim,
224 .sta_notify = cw1200_sta_notify,
225 .sta_add = cw1200_sta_add,
226 .sta_remove = cw1200_sta_remove,
227 .set_key = cw1200_set_key,
228 .set_rts_threshold = cw1200_set_rts_threshold,
229 .config = cw1200_config,
230 .bss_info_changed = cw1200_bss_info_changed,
231 .prepare_multicast = cw1200_prepare_multicast,
232 .configure_filter = cw1200_configure_filter,
233 .conf_tx = cw1200_conf_tx,
234 .get_stats = cw1200_get_stats,
235 .ampdu_action = cw1200_ampdu_action,
236 .flush = cw1200_flush,
237 .suspend = cw1200_wow_suspend,
238 .resume = cw1200_wow_resume,
239 /* Intentionally not offloaded: */
240 /*.channel_switch = cw1200_channel_switch, */
241 /*.remain_on_channel = cw1200_remain_on_channel, */
242 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */
243};
244
245int cw1200_ba_rx_tids = -1;
246int cw1200_ba_tx_tids = -1;
247module_param(cw1200_ba_rx_tids, int, 0644);
248module_param(cw1200_ba_tx_tids, int, 0644);
249MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
250MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs");
251
252static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
253 const bool have_5ghz)
254{
255 int i, band;
256 struct ieee80211_hw *hw;
257 struct cw1200_common *priv;
258
259 hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
260 if (!hw)
261 return NULL;
262
263 priv = hw->priv;
264 priv->hw = hw;
265 priv->hw_type = -1;
266 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
267 priv->rates = cw1200_rates; /* TODO: fetch from FW */
268 priv->mcs_rates = cw1200_n_rates;
269 if (cw1200_ba_rx_tids != -1)
270 priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
271 else
272 priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
273 if (cw1200_ba_tx_tids != -1)
274 priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
275 else
276 priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */
277
278 hw->flags = IEEE80211_HW_SIGNAL_DBM |
279 IEEE80211_HW_SUPPORTS_PS |
280 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
281 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
282 IEEE80211_HW_SUPPORTS_UAPSD |
283 IEEE80211_HW_CONNECTION_MONITOR |
284 IEEE80211_HW_AMPDU_AGGREGATION |
285 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
286 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC;
287
288 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
289 BIT(NL80211_IFTYPE_ADHOC) |
290 BIT(NL80211_IFTYPE_AP) |
291 BIT(NL80211_IFTYPE_MESH_POINT) |
292 BIT(NL80211_IFTYPE_P2P_CLIENT) |
293 BIT(NL80211_IFTYPE_P2P_GO);
294
295 /* Support only for limited wowlan functionalities */
296 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
297 WIPHY_WOWLAN_DISCONNECT;
298 hw->wiphy->wowlan.n_patterns = 0;
299
300 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
301
302 hw->channel_change_time = 1000; /* TODO: find actual value */
303 hw->queues = 4;
304
305 priv->rts_threshold = -1;
306
307 hw->max_rates = 8;
308 hw->max_rate_tries = 15;
309 hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
310 8; /* TKIP IV */
311
312 hw->sta_data_size = sizeof(struct cw1200_sta_priv);
313
314 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &cw1200_band_2ghz;
315 if (have_5ghz)
316 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &cw1200_band_5ghz;
317
318 /* Channel params have to be cleared before registering wiphy again */
319 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
320 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
321 if (!sband)
322 continue;
323 for (i = 0; i < sband->n_channels; i++) {
324 sband->channels[i].flags = 0;
325 sband->channels[i].max_antenna_gain = 0;
326 sband->channels[i].max_power = 30;
327 }
328 }
329
330 hw->wiphy->max_scan_ssids = 2;
331 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
332
333 if (macaddr)
334 SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
335 else
336 SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
337
338 /* Fix up mac address if necessary */
339 if (hw->wiphy->perm_addr[3] == 0 &&
340 hw->wiphy->perm_addr[4] == 0 &&
341 hw->wiphy->perm_addr[5] == 0) {
342 get_random_bytes(&hw->wiphy->perm_addr[3], 3);
343 }
344
345 mutex_init(&priv->wsm_cmd_mux);
346 mutex_init(&priv->conf_mutex);
347 priv->workqueue = create_singlethread_workqueue("cw1200_wq");
348 sema_init(&priv->scan.lock, 1);
349 INIT_WORK(&priv->scan.work, cw1200_scan_work);
350 INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
351 INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
352 INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
353 cw1200_clear_recent_scan_work);
354 INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
355 INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
356 INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
357 INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
358 INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
359 spin_lock_init(&priv->event_queue_lock);
360 INIT_LIST_HEAD(&priv->event_queue);
361 INIT_WORK(&priv->event_handler, cw1200_event_handler);
362 INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
363 INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
364 spin_lock_init(&priv->bss_loss_lock);
365 spin_lock_init(&priv->ps_state_lock);
366 INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
367 INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
368 INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
369 INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
370 INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
371 INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
372 INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
373 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
374 INIT_WORK(&priv->set_beacon_wakeup_period_work,
375 cw1200_set_beacon_wakeup_period_work);
376 init_timer(&priv->mcast_timeout);
377 priv->mcast_timeout.data = (unsigned long)priv;
378 priv->mcast_timeout.function = cw1200_mcast_timeout;
379
380 if (cw1200_queue_stats_init(&priv->tx_queue_stats,
381 CW1200_LINK_ID_MAX,
382 cw1200_skb_dtor,
383 priv)) {
384 ieee80211_free_hw(hw);
385 return NULL;
386 }
387
388 for (i = 0; i < 4; ++i) {
389 if (cw1200_queue_init(&priv->tx_queue[i],
390 &priv->tx_queue_stats, i, 16,
391 cw1200_ttl[i])) {
392 for (; i > 0; i--)
393 cw1200_queue_deinit(&priv->tx_queue[i - 1]);
394 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
395 ieee80211_free_hw(hw);
396 return NULL;
397 }
398 }
399
400 init_waitqueue_head(&priv->channel_switch_done);
401 init_waitqueue_head(&priv->wsm_cmd_wq);
402 init_waitqueue_head(&priv->wsm_startup_done);
403 init_waitqueue_head(&priv->ps_mode_switch_done);
404 wsm_buf_init(&priv->wsm_cmd_buf);
405 spin_lock_init(&priv->wsm_cmd.lock);
406 priv->wsm_cmd.done = 1;
407 tx_policy_init(priv);
408
409 return hw;
410}
411
412static int cw1200_register_common(struct ieee80211_hw *dev)
413{
414 struct cw1200_common *priv = dev->priv;
415 int err;
416
417#ifdef CONFIG_CW1200_ETF
418 if (etf_mode)
419 goto done;
420#endif
421
422 err = cw1200_pm_init(&priv->pm_state, priv);
423 if (err) {
424 pr_err("Cannot init PM. (%d).\n",
425 err);
426 return err;
427 }
428
429 err = ieee80211_register_hw(dev);
430 if (err) {
431 pr_err("Cannot register device (%d).\n",
432 err);
433 cw1200_pm_deinit(&priv->pm_state);
434 return err;
435 }
436
437#ifdef CONFIG_CW1200_ETF
438done:
439#endif
440 cw1200_debug_init(priv);
441
442 pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
443 return 0;
444}
445
446static void cw1200_free_common(struct ieee80211_hw *dev)
447{
448 ieee80211_free_hw(dev);
449}
450
451static void cw1200_unregister_common(struct ieee80211_hw *dev)
452{
453 struct cw1200_common *priv = dev->priv;
454 int i;
455
456#ifdef CONFIG_CW1200_ETF
457 if (!etf_mode) {
458#endif
459 ieee80211_unregister_hw(dev);
460#ifdef CONFIG_CW1200_ETF
461 }
462#endif
463
464 del_timer_sync(&priv->mcast_timeout);
465 cw1200_unregister_bh(priv);
466
467 cw1200_debug_release(priv);
468
469 mutex_destroy(&priv->conf_mutex);
470
471 wsm_buf_deinit(&priv->wsm_cmd_buf);
472
473 destroy_workqueue(priv->workqueue);
474 priv->workqueue = NULL;
475
476 if (priv->sdd) {
477 release_firmware(priv->sdd);
478 priv->sdd = NULL;
479 }
480
481 for (i = 0; i < 4; ++i)
482 cw1200_queue_deinit(&priv->tx_queue[i]);
483
484 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
485 cw1200_pm_deinit(&priv->pm_state);
486}
487
488/* Clock is in KHz */
489u32 cw1200_dpll_from_clk(u16 clk_khz)
490{
491 switch (clk_khz) {
492 case 0x32C8: /* 13000 KHz */
493 return 0x1D89D241;
494 case 0x3E80: /* 16000 KHz */
495 return 0x000001E1;
496 case 0x41A0: /* 16800 KHz */
497 return 0x124931C1;
498 case 0x4B00: /* 19200 KHz */
499 return 0x00000191;
500 case 0x5DC0: /* 24000 KHz */
501 return 0x00000141;
502 case 0x6590: /* 26000 KHz */
503 return 0x0EC4F121;
504 case 0x8340: /* 33600 KHz */
505 return 0x092490E1;
506 case 0x9600: /* 38400 KHz */
507 return 0x100010C1;
508 case 0x9C40: /* 40000 KHz */
509 return 0x000000C1;
510 case 0xBB80: /* 48000 KHz */
511 return 0x000000A1;
512 case 0xCB20: /* 52000 KHz */
513 return 0x07627091;
514 default:
515 pr_err("Unknown Refclk freq (0x%04x), using 2600KHz\n",
516 clk_khz);
517 return 0x0EC4F121;
518 }
519}
520
521int cw1200_core_probe(const struct sbus_ops *sbus_ops,
522 struct sbus_priv *sbus,
523 struct device *pdev,
524 struct cw1200_common **core,
525 int ref_clk, const u8 *macaddr,
526 const char *sdd_path, bool have_5ghz)
527{
528 int err = -EINVAL;
529 struct ieee80211_hw *dev;
530 struct cw1200_common *priv;
531 struct wsm_operational_mode mode = {
532 .power_mode = cw1200_power_mode,
533 .disable_more_flag_usage = true,
534 };
535
536 dev = cw1200_init_common(macaddr, have_5ghz);
537 if (!dev)
538 goto err;
539
540 priv = dev->priv;
541 priv->hw_refclk = ref_clk;
542 if (cw1200_refclk)
543 priv->hw_refclk = cw1200_refclk;
544
545 priv->sdd_path = (char *)sdd_path;
546 if (cw1200_sdd_path)
547 priv->sdd_path = cw1200_sdd_path;
548
549 priv->sbus_ops = sbus_ops;
550 priv->sbus_priv = sbus;
551 priv->pdev = pdev;
552 SET_IEEE80211_DEV(priv->hw, pdev);
553
554 /* Pass struct cw1200_common back up */
555 *core = priv;
556
557 err = cw1200_register_bh(priv);
558 if (err)
559 goto err1;
560
561#ifdef CONFIG_CW1200_ETF
562 if (etf_mode)
563 goto skip_fw;
564#endif
565
566 err = cw1200_load_firmware(priv);
567 if (err)
568 goto err2;
569
570 if (wait_event_interruptible_timeout(priv->wsm_startup_done,
571 priv->firmware_ready,
572 3*HZ) <= 0) {
573 /* TODO: Need to find how to reset device
574 in QUEUE mode properly.
575 */
576 pr_err("Timeout waiting on device startup\n");
577 err = -ETIMEDOUT;
578 goto err2;
579 }
580
581 /* Set low-power mode. */
582 wsm_set_operational_mode(priv, &mode);
583
584 /* Enable multi-TX confirmation */
585 wsm_use_multi_tx_conf(priv, true);
586
587#ifdef CONFIG_CW1200_ETF
588skip_fw:
589#endif
590 err = cw1200_register_common(dev);
591 if (err)
592 goto err2;
593
594 return err;
595
596err2:
597 cw1200_unregister_bh(priv);
598err1:
599 cw1200_free_common(dev);
600err:
601 *core = NULL;
602 return err;
603}
604EXPORT_SYMBOL_GPL(cw1200_core_probe);
605
606void cw1200_core_release(struct cw1200_common *self)
607{
608 /* Disable device interrupts */
609 self->sbus_ops->lock(self->sbus_priv);
610 __cw1200_irq_enable(self, 0);
611 self->sbus_ops->unlock(self->sbus_priv);
612
613 /* And then clean up */
614 cw1200_unregister_common(self->hw);
615 cw1200_free_common(self->hw);
616 return;
617}
618EXPORT_SYMBOL_GPL(cw1200_core_release);
diff --git a/drivers/net/wireless/cw1200/pm.c b/drivers/net/wireless/cw1200/pm.c
new file mode 100644
index 000000000000..79edfb93b292
--- /dev/null
+++ b/drivers/net/wireless/cw1200/pm.c
@@ -0,0 +1,367 @@
1/*
2 * Mac80211 power management API for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/if_ether.h>
14#include "cw1200.h"
15#include "pm.h"
16#include "sta.h"
17#include "bh.h"
18#include "sbus.h"
19
20#define CW1200_BEACON_SKIPPING_MULTIPLIER 3
21
22struct cw1200_udp_port_filter {
23 struct wsm_udp_port_filter_hdr hdr;
24 /* Up to 4 filters are allowed. */
25 struct wsm_udp_port_filter filters[WSM_MAX_FILTER_ELEMENTS];
26} __packed;
27
28struct cw1200_ether_type_filter {
29 struct wsm_ether_type_filter_hdr hdr;
30 /* Up to 4 filters are allowed. */
31 struct wsm_ether_type_filter filters[WSM_MAX_FILTER_ELEMENTS];
32} __packed;
33
34static struct cw1200_udp_port_filter cw1200_udp_port_filter_on = {
35 .hdr.num = 2,
36 .filters = {
37 [0] = {
38 .action = WSM_FILTER_ACTION_FILTER_OUT,
39 .type = WSM_FILTER_PORT_TYPE_DST,
40 .port = __cpu_to_le16(67), /* DHCP Bootps */
41 },
42 [1] = {
43 .action = WSM_FILTER_ACTION_FILTER_OUT,
44 .type = WSM_FILTER_PORT_TYPE_DST,
45 .port = __cpu_to_le16(68), /* DHCP Bootpc */
46 },
47 }
48};
49
50static struct wsm_udp_port_filter_hdr cw1200_udp_port_filter_off = {
51 .num = 0,
52};
53
54#ifndef ETH_P_WAPI
55#define ETH_P_WAPI 0x88B4
56#endif
57
58static struct cw1200_ether_type_filter cw1200_ether_type_filter_on = {
59 .hdr.num = 4,
60 .filters = {
61 [0] = {
62 .action = WSM_FILTER_ACTION_FILTER_IN,
63 .type = __cpu_to_le16(ETH_P_IP),
64 },
65 [1] = {
66 .action = WSM_FILTER_ACTION_FILTER_IN,
67 .type = __cpu_to_le16(ETH_P_PAE),
68 },
69 [2] = {
70 .action = WSM_FILTER_ACTION_FILTER_IN,
71 .type = __cpu_to_le16(ETH_P_WAPI),
72 },
73 [3] = {
74 .action = WSM_FILTER_ACTION_FILTER_IN,
75 .type = __cpu_to_le16(ETH_P_ARP),
76 },
77 },
78};
79
80static struct wsm_ether_type_filter_hdr cw1200_ether_type_filter_off = {
81 .num = 0,
82};
83
84/* private */
85struct cw1200_suspend_state {
86 unsigned long bss_loss_tmo;
87 unsigned long join_tmo;
88 unsigned long direct_probe;
89 unsigned long link_id_gc;
90 bool beacon_skipping;
91 u8 prev_ps_mode;
92};
93
94static void cw1200_pm_stay_awake_tmo(unsigned long arg)
95{
96 /* XXX what's the point of this ? */
97}
98
99int cw1200_pm_init(struct cw1200_pm_state *pm,
100 struct cw1200_common *priv)
101{
102 spin_lock_init(&pm->lock);
103
104 init_timer(&pm->stay_awake);
105 pm->stay_awake.data = (unsigned long)pm;
106 pm->stay_awake.function = cw1200_pm_stay_awake_tmo;
107
108 return 0;
109}
110
111void cw1200_pm_deinit(struct cw1200_pm_state *pm)
112{
113 del_timer_sync(&pm->stay_awake);
114}
115
116void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
117 unsigned long tmo)
118{
119 long cur_tmo;
120 spin_lock_bh(&pm->lock);
121 cur_tmo = pm->stay_awake.expires - jiffies;
122 if (!timer_pending(&pm->stay_awake) || cur_tmo < (long)tmo)
123 mod_timer(&pm->stay_awake, jiffies + tmo);
124 spin_unlock_bh(&pm->lock);
125}
126
127static long cw1200_suspend_work(struct delayed_work *work)
128{
129 int ret = cancel_delayed_work(work);
130 long tmo;
131 if (ret > 0) {
132 /* Timer is pending */
133 tmo = work->timer.expires - jiffies;
134 if (tmo < 0)
135 tmo = 0;
136 } else {
137 tmo = -1;
138 }
139 return tmo;
140}
141
142static int cw1200_resume_work(struct cw1200_common *priv,
143 struct delayed_work *work,
144 unsigned long tmo)
145{
146 if ((long)tmo < 0)
147 return 1;
148
149 return queue_delayed_work(priv->workqueue, work, tmo);
150}
151
152int cw1200_can_suspend(struct cw1200_common *priv)
153{
154 if (atomic_read(&priv->bh_rx)) {
155 wiphy_dbg(priv->hw->wiphy, "Suspend interrupted.\n");
156 return 0;
157 }
158 return 1;
159}
160EXPORT_SYMBOL_GPL(cw1200_can_suspend);
161
162int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
163{
164 struct cw1200_common *priv = hw->priv;
165 struct cw1200_pm_state *pm_state = &priv->pm_state;
166 struct cw1200_suspend_state *state;
167 int ret;
168
169 spin_lock_bh(&pm_state->lock);
170 ret = timer_pending(&pm_state->stay_awake);
171 spin_unlock_bh(&pm_state->lock);
172 if (ret)
173 return -EAGAIN;
174
175 /* Do not suspend when datapath is not idle */
176 if (priv->tx_queue_stats.num_queued)
177 return -EBUSY;
178
179 /* Make sure there is no configuration requests in progress. */
180 if (!mutex_trylock(&priv->conf_mutex))
181 return -EBUSY;
182
183 /* Ensure pending operations are done.
184 * Note also that wow_suspend must return in ~2.5sec, before
185 * watchdog is triggered.
186 */
187 if (priv->channel_switch_in_progress)
188 goto revert1;
189
190 /* Do not suspend when join is pending */
191 if (priv->join_pending)
192 goto revert1;
193
194 /* Do not suspend when scanning */
195 if (down_trylock(&priv->scan.lock))
196 goto revert1;
197
198 /* Lock TX. */
199 wsm_lock_tx_async(priv);
200
201 /* Wait to avoid possible race with bh code.
202 * But do not wait too long...
203 */
204 if (wait_event_timeout(priv->bh_evt_wq,
205 !priv->hw_bufs_used, HZ / 10) <= 0)
206 goto revert2;
207
208 /* Set UDP filter */
209 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_on.hdr);
210
211 /* Set ethernet frame type filter */
212 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_on.hdr);
213
214 /* Allocate state */
215 state = kzalloc(sizeof(struct cw1200_suspend_state), GFP_KERNEL);
216 if (!state)
217 goto revert3;
218
219 /* Change to legacy PS while going to suspend */
220 if (!priv->vif->p2p &&
221 priv->join_status == CW1200_JOIN_STATUS_STA &&
222 priv->powersave_mode.mode != WSM_PSM_PS) {
223 state->prev_ps_mode = priv->powersave_mode.mode;
224 priv->powersave_mode.mode = WSM_PSM_PS;
225 cw1200_set_pm(priv, &priv->powersave_mode);
226 if (wait_event_interruptible_timeout(priv->ps_mode_switch_done,
227 !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) {
228 goto revert3;
229 }
230 }
231
232 /* Store delayed work states. */
233 state->bss_loss_tmo =
234 cw1200_suspend_work(&priv->bss_loss_work);
235 state->join_tmo =
236 cw1200_suspend_work(&priv->join_timeout);
237 state->direct_probe =
238 cw1200_suspend_work(&priv->scan.probe_work);
239 state->link_id_gc =
240 cw1200_suspend_work(&priv->link_id_gc_work);
241
242 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
243 atomic_set(&priv->recent_scan, 0);
244
245 /* Enable beacon skipping */
246 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
247 priv->join_dtim_period &&
248 !priv->has_multicast_subscription) {
249 state->beacon_skipping = true;
250 wsm_set_beacon_wakeup_period(priv,
251 priv->join_dtim_period,
252 CW1200_BEACON_SKIPPING_MULTIPLIER * priv->join_dtim_period);
253 }
254
255 /* Stop serving thread */
256 if (cw1200_bh_suspend(priv))
257 goto revert4;
258
259 ret = timer_pending(&priv->mcast_timeout);
260 if (ret)
261 goto revert5;
262
263 /* Store suspend state */
264 pm_state->suspend_state = state;
265
266 /* Enable IRQ wake */
267 ret = priv->sbus_ops->power_mgmt(priv->sbus_priv, true);
268 if (ret) {
269 wiphy_err(priv->hw->wiphy,
270 "PM request failed: %d. WoW is disabled.\n", ret);
271 cw1200_wow_resume(hw);
272 return -EBUSY;
273 }
274
275 /* Force resume if event is coming from the device. */
276 if (atomic_read(&priv->bh_rx)) {
277 cw1200_wow_resume(hw);
278 return -EAGAIN;
279 }
280
281 return 0;
282
283revert5:
284 WARN_ON(cw1200_bh_resume(priv));
285revert4:
286 cw1200_resume_work(priv, &priv->bss_loss_work,
287 state->bss_loss_tmo);
288 cw1200_resume_work(priv, &priv->join_timeout,
289 state->join_tmo);
290 cw1200_resume_work(priv, &priv->scan.probe_work,
291 state->direct_probe);
292 cw1200_resume_work(priv, &priv->link_id_gc_work,
293 state->link_id_gc);
294 kfree(state);
295revert3:
296 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
297 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
298revert2:
299 wsm_unlock_tx(priv);
300 up(&priv->scan.lock);
301revert1:
302 mutex_unlock(&priv->conf_mutex);
303 return -EBUSY;
304}
305
306int cw1200_wow_resume(struct ieee80211_hw *hw)
307{
308 struct cw1200_common *priv = hw->priv;
309 struct cw1200_pm_state *pm_state = &priv->pm_state;
310 struct cw1200_suspend_state *state;
311
312 state = pm_state->suspend_state;
313 pm_state->suspend_state = NULL;
314
315 /* Disable IRQ wake */
316 priv->sbus_ops->power_mgmt(priv->sbus_priv, false);
317
318 /* Scan.lock must be released before BH is resumed other way
319 * in case when BSS_LOST command arrived the processing of the
320 * command will be delayed.
321 */
322 up(&priv->scan.lock);
323
324 /* Resume BH thread */
325 WARN_ON(cw1200_bh_resume(priv));
326
327 /* Restores previous PS mode */
328 if (!priv->vif->p2p && priv->join_status == CW1200_JOIN_STATUS_STA) {
329 priv->powersave_mode.mode = state->prev_ps_mode;
330 cw1200_set_pm(priv, &priv->powersave_mode);
331 }
332
333 if (state->beacon_skipping) {
334 wsm_set_beacon_wakeup_period(priv, priv->beacon_int *
335 priv->join_dtim_period >
336 MAX_BEACON_SKIP_TIME_MS ? 1 :
337 priv->join_dtim_period, 0);
338 state->beacon_skipping = false;
339 }
340
341 /* Resume delayed work */
342 cw1200_resume_work(priv, &priv->bss_loss_work,
343 state->bss_loss_tmo);
344 cw1200_resume_work(priv, &priv->join_timeout,
345 state->join_tmo);
346 cw1200_resume_work(priv, &priv->scan.probe_work,
347 state->direct_probe);
348 cw1200_resume_work(priv, &priv->link_id_gc_work,
349 state->link_id_gc);
350
351 /* Remove UDP port filter */
352 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
353
354 /* Remove ethernet frame type filter */
355 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
356
357 /* Unlock datapath */
358 wsm_unlock_tx(priv);
359
360 /* Unlock configuration mutex */
361 mutex_unlock(&priv->conf_mutex);
362
363 /* Free memory */
364 kfree(state);
365
366 return 0;
367}
diff --git a/drivers/net/wireless/cw1200/pm.h b/drivers/net/wireless/cw1200/pm.h
new file mode 100644
index 000000000000..516d9671dd1e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/pm.h
@@ -0,0 +1,38 @@
1/*
2 * Mac80211 power management interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef PM_H_INCLUDED
13#define PM_H_INCLUDED
14
15/* ******************************************************************** */
16/* mac80211 API */
17
18/* extern */ struct cw1200_common;
19/* private */ struct cw1200_suspend_state;
20
21struct cw1200_pm_state {
22 struct cw1200_suspend_state *suspend_state;
23 struct timer_list stay_awake;
24 struct platform_device *pm_dev;
25 spinlock_t lock; /* Protect access */
26};
27
28int cw1200_pm_init(struct cw1200_pm_state *pm,
29 struct cw1200_common *priv);
30void cw1200_pm_deinit(struct cw1200_pm_state *pm);
31void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
32 unsigned long tmo);
33int cw1200_wow_suspend(struct ieee80211_hw *hw,
34 struct cfg80211_wowlan *wowlan);
35int cw1200_wow_resume(struct ieee80211_hw *hw);
36int cw1200_can_suspend(struct cw1200_common *priv);
37
38#endif
diff --git a/drivers/net/wireless/cw1200/queue.c b/drivers/net/wireless/cw1200/queue.c
new file mode 100644
index 000000000000..8510454d5db1
--- /dev/null
+++ b/drivers/net/wireless/cw1200/queue.c
@@ -0,0 +1,583 @@
1/*
2 * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <net/mac80211.h>
13#include <linux/sched.h>
14#include "queue.h"
15#include "cw1200.h"
16#include "debug.h"
17
18/* private */ struct cw1200_queue_item
19{
20 struct list_head head;
21 struct sk_buff *skb;
22 u32 packet_id;
23 unsigned long queue_timestamp;
24 unsigned long xmit_timestamp;
25 struct cw1200_txpriv txpriv;
26 u8 generation;
27};
28
29static inline void __cw1200_queue_lock(struct cw1200_queue *queue)
30{
31 struct cw1200_queue_stats *stats = queue->stats;
32 if (queue->tx_locked_cnt++ == 0) {
33 pr_debug("[TX] Queue %d is locked.\n",
34 queue->queue_id);
35 ieee80211_stop_queue(stats->priv->hw, queue->queue_id);
36 }
37}
38
39static inline void __cw1200_queue_unlock(struct cw1200_queue *queue)
40{
41 struct cw1200_queue_stats *stats = queue->stats;
42 BUG_ON(!queue->tx_locked_cnt);
43 if (--queue->tx_locked_cnt == 0) {
44 pr_debug("[TX] Queue %d is unlocked.\n",
45 queue->queue_id);
46 ieee80211_wake_queue(stats->priv->hw, queue->queue_id);
47 }
48}
49
50static inline void cw1200_queue_parse_id(u32 packet_id, u8 *queue_generation,
51 u8 *queue_id, u8 *item_generation,
52 u8 *item_id)
53{
54 *item_id = (packet_id >> 0) & 0xFF;
55 *item_generation = (packet_id >> 8) & 0xFF;
56 *queue_id = (packet_id >> 16) & 0xFF;
57 *queue_generation = (packet_id >> 24) & 0xFF;
58}
59
60static inline u32 cw1200_queue_mk_packet_id(u8 queue_generation, u8 queue_id,
61 u8 item_generation, u8 item_id)
62{
63 return ((u32)item_id << 0) |
64 ((u32)item_generation << 8) |
65 ((u32)queue_id << 16) |
66 ((u32)queue_generation << 24);
67}
68
69static void cw1200_queue_post_gc(struct cw1200_queue_stats *stats,
70 struct list_head *gc_list)
71{
72 struct cw1200_queue_item *item, *tmp;
73
74 list_for_each_entry_safe(item, tmp, gc_list, head) {
75 list_del(&item->head);
76 stats->skb_dtor(stats->priv, item->skb, &item->txpriv);
77 kfree(item);
78 }
79}
80
81static void cw1200_queue_register_post_gc(struct list_head *gc_list,
82 struct cw1200_queue_item *item)
83{
84 struct cw1200_queue_item *gc_item;
85 gc_item = kmalloc(sizeof(struct cw1200_queue_item),
86 GFP_ATOMIC);
87 BUG_ON(!gc_item);
88 memcpy(gc_item, item, sizeof(struct cw1200_queue_item));
89 list_add_tail(&gc_item->head, gc_list);
90}
91
92static void __cw1200_queue_gc(struct cw1200_queue *queue,
93 struct list_head *head,
94 bool unlock)
95{
96 struct cw1200_queue_stats *stats = queue->stats;
97 struct cw1200_queue_item *item = NULL, *tmp;
98 bool wakeup_stats = false;
99
100 list_for_each_entry_safe(item, tmp, &queue->queue, head) {
101 if (jiffies - item->queue_timestamp < queue->ttl)
102 break;
103 --queue->num_queued;
104 --queue->link_map_cache[item->txpriv.link_id];
105 spin_lock_bh(&stats->lock);
106 --stats->num_queued;
107 if (!--stats->link_map_cache[item->txpriv.link_id])
108 wakeup_stats = true;
109 spin_unlock_bh(&stats->lock);
110 cw1200_debug_tx_ttl(stats->priv);
111 cw1200_queue_register_post_gc(head, item);
112 item->skb = NULL;
113 list_move_tail(&item->head, &queue->free_pool);
114 }
115
116 if (wakeup_stats)
117 wake_up(&stats->wait_link_id_empty);
118
119 if (queue->overfull) {
120 if (queue->num_queued <= (queue->capacity >> 1)) {
121 queue->overfull = false;
122 if (unlock)
123 __cw1200_queue_unlock(queue);
124 } else if (item) {
125 unsigned long tmo = item->queue_timestamp + queue->ttl;
126 mod_timer(&queue->gc, tmo);
127 cw1200_pm_stay_awake(&stats->priv->pm_state,
128 tmo - jiffies);
129 }
130 }
131}
132
133static void cw1200_queue_gc(unsigned long arg)
134{
135 LIST_HEAD(list);
136 struct cw1200_queue *queue =
137 (struct cw1200_queue *)arg;
138
139 spin_lock_bh(&queue->lock);
140 __cw1200_queue_gc(queue, &list, true);
141 spin_unlock_bh(&queue->lock);
142 cw1200_queue_post_gc(queue->stats, &list);
143}
144
145int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
146 size_t map_capacity,
147 cw1200_queue_skb_dtor_t skb_dtor,
148 struct cw1200_common *priv)
149{
150 memset(stats, 0, sizeof(*stats));
151 stats->map_capacity = map_capacity;
152 stats->skb_dtor = skb_dtor;
153 stats->priv = priv;
154 spin_lock_init(&stats->lock);
155 init_waitqueue_head(&stats->wait_link_id_empty);
156
157 stats->link_map_cache = kzalloc(sizeof(int) * map_capacity,
158 GFP_KERNEL);
159 if (!stats->link_map_cache)
160 return -ENOMEM;
161
162 return 0;
163}
164
165int cw1200_queue_init(struct cw1200_queue *queue,
166 struct cw1200_queue_stats *stats,
167 u8 queue_id,
168 size_t capacity,
169 unsigned long ttl)
170{
171 size_t i;
172
173 memset(queue, 0, sizeof(*queue));
174 queue->stats = stats;
175 queue->capacity = capacity;
176 queue->queue_id = queue_id;
177 queue->ttl = ttl;
178 INIT_LIST_HEAD(&queue->queue);
179 INIT_LIST_HEAD(&queue->pending);
180 INIT_LIST_HEAD(&queue->free_pool);
181 spin_lock_init(&queue->lock);
182 init_timer(&queue->gc);
183 queue->gc.data = (unsigned long)queue;
184 queue->gc.function = cw1200_queue_gc;
185
186 queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity,
187 GFP_KERNEL);
188 if (!queue->pool)
189 return -ENOMEM;
190
191 queue->link_map_cache = kzalloc(sizeof(int) * stats->map_capacity,
192 GFP_KERNEL);
193 if (!queue->link_map_cache) {
194 kfree(queue->pool);
195 queue->pool = NULL;
196 return -ENOMEM;
197 }
198
199 for (i = 0; i < capacity; ++i)
200 list_add_tail(&queue->pool[i].head, &queue->free_pool);
201
202 return 0;
203}
204
205int cw1200_queue_clear(struct cw1200_queue *queue)
206{
207 int i;
208 LIST_HEAD(gc_list);
209 struct cw1200_queue_stats *stats = queue->stats;
210 struct cw1200_queue_item *item, *tmp;
211
212 spin_lock_bh(&queue->lock);
213 queue->generation++;
214 list_splice_tail_init(&queue->queue, &queue->pending);
215 list_for_each_entry_safe(item, tmp, &queue->pending, head) {
216 WARN_ON(!item->skb);
217 cw1200_queue_register_post_gc(&gc_list, item);
218 item->skb = NULL;
219 list_move_tail(&item->head, &queue->free_pool);
220 }
221 queue->num_queued = 0;
222 queue->num_pending = 0;
223
224 spin_lock_bh(&stats->lock);
225 for (i = 0; i < stats->map_capacity; ++i) {
226 stats->num_queued -= queue->link_map_cache[i];
227 stats->link_map_cache[i] -= queue->link_map_cache[i];
228 queue->link_map_cache[i] = 0;
229 }
230 spin_unlock_bh(&stats->lock);
231 if (queue->overfull) {
232 queue->overfull = false;
233 __cw1200_queue_unlock(queue);
234 }
235 spin_unlock_bh(&queue->lock);
236 wake_up(&stats->wait_link_id_empty);
237 cw1200_queue_post_gc(stats, &gc_list);
238 return 0;
239}
240
241void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats)
242{
243 kfree(stats->link_map_cache);
244 stats->link_map_cache = NULL;
245}
246
247void cw1200_queue_deinit(struct cw1200_queue *queue)
248{
249 cw1200_queue_clear(queue);
250 del_timer_sync(&queue->gc);
251 INIT_LIST_HEAD(&queue->free_pool);
252 kfree(queue->pool);
253 kfree(queue->link_map_cache);
254 queue->pool = NULL;
255 queue->link_map_cache = NULL;
256 queue->capacity = 0;
257}
258
259size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
260 u32 link_id_map)
261{
262 size_t ret;
263 int i, bit;
264 size_t map_capacity = queue->stats->map_capacity;
265
266 if (!link_id_map)
267 return 0;
268
269 spin_lock_bh(&queue->lock);
270 if (link_id_map == (u32)-1) {
271 ret = queue->num_queued - queue->num_pending;
272 } else {
273 ret = 0;
274 for (i = 0, bit = 1; i < map_capacity; ++i, bit <<= 1) {
275 if (link_id_map & bit)
276 ret += queue->link_map_cache[i];
277 }
278 }
279 spin_unlock_bh(&queue->lock);
280 return ret;
281}
282
283int cw1200_queue_put(struct cw1200_queue *queue,
284 struct sk_buff *skb,
285 struct cw1200_txpriv *txpriv)
286{
287 int ret = 0;
288 LIST_HEAD(gc_list);
289 struct cw1200_queue_stats *stats = queue->stats;
290
291 if (txpriv->link_id >= queue->stats->map_capacity)
292 return -EINVAL;
293
294 spin_lock_bh(&queue->lock);
295 if (!WARN_ON(list_empty(&queue->free_pool))) {
296 struct cw1200_queue_item *item = list_first_entry(
297 &queue->free_pool, struct cw1200_queue_item, head);
298 BUG_ON(item->skb);
299
300 list_move_tail(&item->head, &queue->queue);
301 item->skb = skb;
302 item->txpriv = *txpriv;
303 item->generation = 0;
304 item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
305 queue->queue_id,
306 item->generation,
307 item - queue->pool);
308 item->queue_timestamp = jiffies;
309
310 ++queue->num_queued;
311 ++queue->link_map_cache[txpriv->link_id];
312
313 spin_lock_bh(&stats->lock);
314 ++stats->num_queued;
315 ++stats->link_map_cache[txpriv->link_id];
316 spin_unlock_bh(&stats->lock);
317
318 /* TX may happen in parallel sometimes.
319 * Leave extra queue slots so we don't overflow.
320 */
321 if (queue->overfull == false &&
322 queue->num_queued >=
323 (queue->capacity - (num_present_cpus() - 1))) {
324 queue->overfull = true;
325 __cw1200_queue_lock(queue);
326 mod_timer(&queue->gc, jiffies);
327 }
328 } else {
329 ret = -ENOENT;
330 }
331 spin_unlock_bh(&queue->lock);
332 return ret;
333}
334
335int cw1200_queue_get(struct cw1200_queue *queue,
336 u32 link_id_map,
337 struct wsm_tx **tx,
338 struct ieee80211_tx_info **tx_info,
339 const struct cw1200_txpriv **txpriv)
340{
341 int ret = -ENOENT;
342 struct cw1200_queue_item *item;
343 struct cw1200_queue_stats *stats = queue->stats;
344 bool wakeup_stats = false;
345
346 spin_lock_bh(&queue->lock);
347 list_for_each_entry(item, &queue->queue, head) {
348 if (link_id_map & BIT(item->txpriv.link_id)) {
349 ret = 0;
350 break;
351 }
352 }
353
354 if (!WARN_ON(ret)) {
355 *tx = (struct wsm_tx *)item->skb->data;
356 *tx_info = IEEE80211_SKB_CB(item->skb);
357 *txpriv = &item->txpriv;
358 (*tx)->packet_id = __cpu_to_le32(item->packet_id);
359 list_move_tail(&item->head, &queue->pending);
360 ++queue->num_pending;
361 --queue->link_map_cache[item->txpriv.link_id];
362 item->xmit_timestamp = jiffies;
363
364 spin_lock_bh(&stats->lock);
365 --stats->num_queued;
366 if (!--stats->link_map_cache[item->txpriv.link_id])
367 wakeup_stats = true;
368 spin_unlock_bh(&stats->lock);
369 }
370 spin_unlock_bh(&queue->lock);
371 if (wakeup_stats)
372 wake_up(&stats->wait_link_id_empty);
373 return ret;
374}
375
376int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id)
377{
378 int ret = 0;
379 u8 queue_generation, queue_id, item_generation, item_id;
380 struct cw1200_queue_item *item;
381 struct cw1200_queue_stats *stats = queue->stats;
382
383 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
384 &item_generation, &item_id);
385
386 item = &queue->pool[item_id];
387
388 spin_lock_bh(&queue->lock);
389 BUG_ON(queue_id != queue->queue_id);
390 if (queue_generation != queue->generation) {
391 ret = -ENOENT;
392 } else if (item_id >= (unsigned) queue->capacity) {
393 WARN_ON(1);
394 ret = -EINVAL;
395 } else if (item->generation != item_generation) {
396 WARN_ON(1);
397 ret = -ENOENT;
398 } else {
399 --queue->num_pending;
400 ++queue->link_map_cache[item->txpriv.link_id];
401
402 spin_lock_bh(&stats->lock);
403 ++stats->num_queued;
404 ++stats->link_map_cache[item->txpriv.link_id];
405 spin_unlock_bh(&stats->lock);
406
407 item->generation = ++item_generation;
408 item->packet_id = cw1200_queue_mk_packet_id(queue_generation,
409 queue_id,
410 item_generation,
411 item_id);
412 list_move(&item->head, &queue->queue);
413 }
414 spin_unlock_bh(&queue->lock);
415 return ret;
416}
417
418int cw1200_queue_requeue_all(struct cw1200_queue *queue)
419{
420 struct cw1200_queue_item *item, *tmp;
421 struct cw1200_queue_stats *stats = queue->stats;
422 spin_lock_bh(&queue->lock);
423
424 list_for_each_entry_safe_reverse(item, tmp, &queue->pending, head) {
425 --queue->num_pending;
426 ++queue->link_map_cache[item->txpriv.link_id];
427
428 spin_lock_bh(&stats->lock);
429 ++stats->num_queued;
430 ++stats->link_map_cache[item->txpriv.link_id];
431 spin_unlock_bh(&stats->lock);
432
433 ++item->generation;
434 item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
435 queue->queue_id,
436 item->generation,
437 item - queue->pool);
438 list_move(&item->head, &queue->queue);
439 }
440 spin_unlock_bh(&queue->lock);
441
442 return 0;
443}
444
445int cw1200_queue_remove(struct cw1200_queue *queue, u32 packet_id)
446{
447 int ret = 0;
448 u8 queue_generation, queue_id, item_generation, item_id;
449 struct cw1200_queue_item *item;
450 struct cw1200_queue_stats *stats = queue->stats;
451 struct sk_buff *gc_skb = NULL;
452 struct cw1200_txpriv gc_txpriv;
453
454 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
455 &item_generation, &item_id);
456
457 item = &queue->pool[item_id];
458
459 spin_lock_bh(&queue->lock);
460 BUG_ON(queue_id != queue->queue_id);
461 if (queue_generation != queue->generation) {
462 ret = -ENOENT;
463 } else if (item_id >= (unsigned) queue->capacity) {
464 WARN_ON(1);
465 ret = -EINVAL;
466 } else if (item->generation != item_generation) {
467 WARN_ON(1);
468 ret = -ENOENT;
469 } else {
470 gc_txpriv = item->txpriv;
471 gc_skb = item->skb;
472 item->skb = NULL;
473 --queue->num_pending;
474 --queue->num_queued;
475 ++queue->num_sent;
476 ++item->generation;
477 /* Do not use list_move_tail here, but list_move:
478 * try to utilize cache row.
479 */
480 list_move(&item->head, &queue->free_pool);
481
482 if (queue->overfull &&
483 (queue->num_queued <= (queue->capacity >> 1))) {
484 queue->overfull = false;
485 __cw1200_queue_unlock(queue);
486 }
487 }
488 spin_unlock_bh(&queue->lock);
489
490 if (gc_skb)
491 stats->skb_dtor(stats->priv, gc_skb, &gc_txpriv);
492
493 return ret;
494}
495
496int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
497 struct sk_buff **skb,
498 const struct cw1200_txpriv **txpriv)
499{
500 int ret = 0;
501 u8 queue_generation, queue_id, item_generation, item_id;
502 struct cw1200_queue_item *item;
503 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
504 &item_generation, &item_id);
505
506 item = &queue->pool[item_id];
507
508 spin_lock_bh(&queue->lock);
509 BUG_ON(queue_id != queue->queue_id);
510 if (queue_generation != queue->generation) {
511 ret = -ENOENT;
512 } else if (item_id >= (unsigned) queue->capacity) {
513 WARN_ON(1);
514 ret = -EINVAL;
515 } else if (item->generation != item_generation) {
516 WARN_ON(1);
517 ret = -ENOENT;
518 } else {
519 *skb = item->skb;
520 *txpriv = &item->txpriv;
521 }
522 spin_unlock_bh(&queue->lock);
523 return ret;
524}
525
526void cw1200_queue_lock(struct cw1200_queue *queue)
527{
528 spin_lock_bh(&queue->lock);
529 __cw1200_queue_lock(queue);
530 spin_unlock_bh(&queue->lock);
531}
532
533void cw1200_queue_unlock(struct cw1200_queue *queue)
534{
535 spin_lock_bh(&queue->lock);
536 __cw1200_queue_unlock(queue);
537 spin_unlock_bh(&queue->lock);
538}
539
540bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
541 unsigned long *timestamp,
542 u32 pending_frame_id)
543{
544 struct cw1200_queue_item *item;
545 bool ret;
546
547 spin_lock_bh(&queue->lock);
548 ret = !list_empty(&queue->pending);
549 if (ret) {
550 list_for_each_entry(item, &queue->pending, head) {
551 if (item->packet_id != pending_frame_id)
552 if (time_before(item->xmit_timestamp,
553 *timestamp))
554 *timestamp = item->xmit_timestamp;
555 }
556 }
557 spin_unlock_bh(&queue->lock);
558 return ret;
559}
560
561bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
562 u32 link_id_map)
563{
564 bool empty = true;
565
566 spin_lock_bh(&stats->lock);
567 if (link_id_map == (u32)-1) {
568 empty = stats->num_queued == 0;
569 } else {
570 int i;
571 for (i = 0; i < stats->map_capacity; ++i) {
572 if (link_id_map & BIT(i)) {
573 if (stats->link_map_cache[i]) {
574 empty = false;
575 break;
576 }
577 }
578 }
579 }
580 spin_unlock_bh(&stats->lock);
581
582 return empty;
583}
diff --git a/drivers/net/wireless/cw1200/queue.h b/drivers/net/wireless/cw1200/queue.h
new file mode 100644
index 000000000000..119f9c79c14e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/queue.h
@@ -0,0 +1,116 @@
1/*
2 * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_QUEUE_H_INCLUDED
13#define CW1200_QUEUE_H_INCLUDED
14
15/* private */ struct cw1200_queue_item;
16
17/* extern */ struct sk_buff;
18/* extern */ struct wsm_tx;
19/* extern */ struct cw1200_common;
20/* extern */ struct ieee80211_tx_queue_stats;
21/* extern */ struct cw1200_txpriv;
22
23/* forward */ struct cw1200_queue_stats;
24
25typedef void (*cw1200_queue_skb_dtor_t)(struct cw1200_common *priv,
26 struct sk_buff *skb,
27 const struct cw1200_txpriv *txpriv);
28
29struct cw1200_queue {
30 struct cw1200_queue_stats *stats;
31 size_t capacity;
32 size_t num_queued;
33 size_t num_pending;
34 size_t num_sent;
35 struct cw1200_queue_item *pool;
36 struct list_head queue;
37 struct list_head free_pool;
38 struct list_head pending;
39 int tx_locked_cnt;
40 int *link_map_cache;
41 bool overfull;
42 spinlock_t lock; /* Protect queue entry */
43 u8 queue_id;
44 u8 generation;
45 struct timer_list gc;
46 unsigned long ttl;
47};
48
49struct cw1200_queue_stats {
50 spinlock_t lock; /* Protect stats entry */
51 int *link_map_cache;
52 int num_queued;
53 size_t map_capacity;
54 wait_queue_head_t wait_link_id_empty;
55 cw1200_queue_skb_dtor_t skb_dtor;
56 struct cw1200_common *priv;
57};
58
59struct cw1200_txpriv {
60 u8 link_id;
61 u8 raw_link_id;
62 u8 tid;
63 u8 rate_id;
64 u8 offset;
65};
66
67int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
68 size_t map_capacity,
69 cw1200_queue_skb_dtor_t skb_dtor,
70 struct cw1200_common *priv);
71int cw1200_queue_init(struct cw1200_queue *queue,
72 struct cw1200_queue_stats *stats,
73 u8 queue_id,
74 size_t capacity,
75 unsigned long ttl);
76int cw1200_queue_clear(struct cw1200_queue *queue);
77void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats);
78void cw1200_queue_deinit(struct cw1200_queue *queue);
79
80size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
81 u32 link_id_map);
82int cw1200_queue_put(struct cw1200_queue *queue,
83 struct sk_buff *skb,
84 struct cw1200_txpriv *txpriv);
85int cw1200_queue_get(struct cw1200_queue *queue,
86 u32 link_id_map,
87 struct wsm_tx **tx,
88 struct ieee80211_tx_info **tx_info,
89 const struct cw1200_txpriv **txpriv);
90int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id);
91int cw1200_queue_requeue_all(struct cw1200_queue *queue);
92int cw1200_queue_remove(struct cw1200_queue *queue,
93 u32 packet_id);
94int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
95 struct sk_buff **skb,
96 const struct cw1200_txpriv **txpriv);
97void cw1200_queue_lock(struct cw1200_queue *queue);
98void cw1200_queue_unlock(struct cw1200_queue *queue);
99bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
100 unsigned long *timestamp,
101 u32 pending_frame_id);
102
103bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
104 u32 link_id_map);
105
106static inline u8 cw1200_queue_get_queue_id(u32 packet_id)
107{
108 return (packet_id >> 16) & 0xFF;
109}
110
111static inline u8 cw1200_queue_get_generation(u32 packet_id)
112{
113 return (packet_id >> 8) & 0xFF;
114}
115
116#endif /* CW1200_QUEUE_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/sbus.h b/drivers/net/wireless/cw1200/sbus.h
new file mode 100644
index 000000000000..603fd25eaa4a
--- /dev/null
+++ b/drivers/net/wireless/cw1200/sbus.h
@@ -0,0 +1,37 @@
1/*
2 * Common sbus abstraction layer interface for cw1200 wireless driver
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_SBUS_H
13#define CW1200_SBUS_H
14
15/*
16 * sbus priv forward definition.
17 * Implemented and instantiated in particular modules.
18 */
19struct sbus_priv;
20
21void cw1200_irq_handler(struct cw1200_common *priv);
22
23/* This MUST be wrapped with sbus_ops->lock/unlock! */
24int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
25
26struct sbus_ops {
27 int (*sbus_memcpy_fromio)(struct sbus_priv *self, unsigned int addr,
28 void *dst, int count);
29 int (*sbus_memcpy_toio)(struct sbus_priv *self, unsigned int addr,
30 const void *src, int count);
31 void (*lock)(struct sbus_priv *self);
32 void (*unlock)(struct sbus_priv *self);
33 size_t (*align_size)(struct sbus_priv *self, size_t size);
34 int (*power_mgmt)(struct sbus_priv *self, bool suspend);
35};
36
37#endif /* CW1200_SBUS_H */
diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
new file mode 100644
index 000000000000..ee3c19037aac
--- /dev/null
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -0,0 +1,461 @@
1/*
2 * Scan implementation for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/sched.h>
13#include "cw1200.h"
14#include "scan.h"
15#include "sta.h"
16#include "pm.h"
17
18static void cw1200_scan_restart_delayed(struct cw1200_common *priv);
19
20static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan)
21{
22 int ret, i;
23 int tmo = 2000;
24
25 switch (priv->join_status) {
26 case CW1200_JOIN_STATUS_PRE_STA:
27 case CW1200_JOIN_STATUS_JOINING:
28 return -EBUSY;
29 default:
30 break;
31 }
32
33 wiphy_dbg(priv->hw->wiphy, "[SCAN] hw req, type %d, %d channels, flags: 0x%x.\n",
34 scan->type, scan->num_channels, scan->flags);
35
36 for (i = 0; i < scan->num_channels; ++i)
37 tmo += scan->ch[i].max_chan_time + 10;
38
39 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
40 atomic_set(&priv->scan.in_progress, 1);
41 atomic_set(&priv->recent_scan, 1);
42 cw1200_pm_stay_awake(&priv->pm_state, tmo * HZ / 1000);
43 queue_delayed_work(priv->workqueue, &priv->scan.timeout,
44 tmo * HZ / 1000);
45 ret = wsm_scan(priv, scan);
46 if (ret) {
47 atomic_set(&priv->scan.in_progress, 0);
48 cancel_delayed_work_sync(&priv->scan.timeout);
49 cw1200_scan_restart_delayed(priv);
50 }
51 return ret;
52}
53
54int cw1200_hw_scan(struct ieee80211_hw *hw,
55 struct ieee80211_vif *vif,
56 struct cfg80211_scan_request *req)
57{
58 struct cw1200_common *priv = hw->priv;
59 struct wsm_template_frame frame = {
60 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
61 };
62 int i, ret;
63
64 if (!priv->vif)
65 return -EINVAL;
66
67 /* Scan when P2P_GO corrupt firmware MiniAP mode */
68 if (priv->join_status == CW1200_JOIN_STATUS_AP)
69 return -EOPNOTSUPP;
70
71 if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
72 req->n_ssids = 0;
73
74 wiphy_dbg(hw->wiphy, "[SCAN] Scan request for %d SSIDs.\n",
75 req->n_ssids);
76
77 if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
78 return -EINVAL;
79
80 frame.skb = ieee80211_probereq_get(hw, priv->vif, NULL, 0,
81 req->ie_len);
82 if (!frame.skb)
83 return -ENOMEM;
84
85 if (req->ie_len)
86 memcpy(skb_put(frame.skb, req->ie_len), req->ie, req->ie_len);
87
88 /* will be unlocked in cw1200_scan_work() */
89 down(&priv->scan.lock);
90 mutex_lock(&priv->conf_mutex);
91
92 ret = wsm_set_template_frame(priv, &frame);
93 if (!ret) {
94 /* Host want to be the probe responder. */
95 ret = wsm_set_probe_responder(priv, true);
96 }
97 if (ret) {
98 mutex_unlock(&priv->conf_mutex);
99 up(&priv->scan.lock);
100 dev_kfree_skb(frame.skb);
101 return ret;
102 }
103
104 wsm_lock_tx(priv);
105
106 BUG_ON(priv->scan.req);
107 priv->scan.req = req;
108 priv->scan.n_ssids = 0;
109 priv->scan.status = 0;
110 priv->scan.begin = &req->channels[0];
111 priv->scan.curr = priv->scan.begin;
112 priv->scan.end = &req->channels[req->n_channels];
113 priv->scan.output_power = priv->output_power;
114
115 for (i = 0; i < req->n_ssids; ++i) {
116 struct wsm_ssid *dst = &priv->scan.ssids[priv->scan.n_ssids];
117 memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
118 dst->length = req->ssids[i].ssid_len;
119 ++priv->scan.n_ssids;
120 }
121
122 mutex_unlock(&priv->conf_mutex);
123
124 if (frame.skb)
125 dev_kfree_skb(frame.skb);
126 queue_work(priv->workqueue, &priv->scan.work);
127 return 0;
128}
129
130void cw1200_scan_work(struct work_struct *work)
131{
132 struct cw1200_common *priv = container_of(work, struct cw1200_common,
133 scan.work);
134 struct ieee80211_channel **it;
135 struct wsm_scan scan = {
136 .type = WSM_SCAN_TYPE_FOREGROUND,
137 .flags = WSM_SCAN_FLAG_SPLIT_METHOD,
138 };
139 bool first_run = (priv->scan.begin == priv->scan.curr &&
140 priv->scan.begin != priv->scan.end);
141 int i;
142
143 if (first_run) {
144 /* Firmware gets crazy if scan request is sent
145 * when STA is joined but not yet associated.
146 * Force unjoin in this case.
147 */
148 if (cancel_delayed_work_sync(&priv->join_timeout) > 0)
149 cw1200_join_timeout(&priv->join_timeout.work);
150 }
151
152 mutex_lock(&priv->conf_mutex);
153
154 if (first_run) {
155 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
156 !(priv->powersave_mode.mode & WSM_PSM_PS)) {
157 struct wsm_set_pm pm = priv->powersave_mode;
158 pm.mode = WSM_PSM_PS;
159 cw1200_set_pm(priv, &pm);
160 } else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
161 /* FW bug: driver has to restart p2p-dev mode
162 * after scan
163 */
164 cw1200_disable_listening(priv);
165 }
166 }
167
168 if (!priv->scan.req || (priv->scan.curr == priv->scan.end)) {
169 if (priv->scan.output_power != priv->output_power)
170 wsm_set_output_power(priv, priv->output_power * 10);
171 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
172 !(priv->powersave_mode.mode & WSM_PSM_PS))
173 cw1200_set_pm(priv, &priv->powersave_mode);
174
175 if (priv->scan.status < 0)
176 wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n",
177 priv->scan.status);
178 else if (priv->scan.req)
179 wiphy_dbg(priv->hw->wiphy,
180 "[SCAN] Scan completed.\n");
181 else
182 wiphy_dbg(priv->hw->wiphy,
183 "[SCAN] Scan canceled.\n");
184
185 priv->scan.req = NULL;
186 cw1200_scan_restart_delayed(priv);
187 wsm_unlock_tx(priv);
188 mutex_unlock(&priv->conf_mutex);
189 ieee80211_scan_completed(priv->hw, priv->scan.status ? 1 : 0);
190 up(&priv->scan.lock);
191 return;
192 } else {
193 struct ieee80211_channel *first = *priv->scan.curr;
194 for (it = priv->scan.curr + 1, i = 1;
195 it != priv->scan.end && i < WSM_SCAN_MAX_NUM_OF_CHANNELS;
196 ++it, ++i) {
197 if ((*it)->band != first->band)
198 break;
199 if (((*it)->flags ^ first->flags) &
200 IEEE80211_CHAN_PASSIVE_SCAN)
201 break;
202 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
203 (*it)->max_power != first->max_power)
204 break;
205 }
206 scan.band = first->band;
207
208 if (priv->scan.req->no_cck)
209 scan.max_tx_rate = WSM_TRANSMIT_RATE_6;
210 else
211 scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
212 scan.num_probes =
213 (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2;
214 scan.num_ssids = priv->scan.n_ssids;
215 scan.ssids = &priv->scan.ssids[0];
216 scan.num_channels = it - priv->scan.curr;
217 /* TODO: Is it optimal? */
218 scan.probe_delay = 100;
219 /* It is not stated in WSM specification, however
220 * FW team says that driver may not use FG scan
221 * when joined.
222 */
223 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
224 scan.type = WSM_SCAN_TYPE_BACKGROUND;
225 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
226 }
227 scan.ch = kzalloc(
228 sizeof(struct wsm_scan_ch) * (it - priv->scan.curr),
229 GFP_KERNEL);
230 if (!scan.ch) {
231 priv->scan.status = -ENOMEM;
232 goto fail;
233 }
234 for (i = 0; i < scan.num_channels; ++i) {
235 scan.ch[i].number = priv->scan.curr[i]->hw_value;
236 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
237 scan.ch[i].min_chan_time = 50;
238 scan.ch[i].max_chan_time = 100;
239 } else {
240 scan.ch[i].min_chan_time = 10;
241 scan.ch[i].max_chan_time = 25;
242 }
243 }
244 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
245 priv->scan.output_power != first->max_power) {
246 priv->scan.output_power = first->max_power;
247 wsm_set_output_power(priv,
248 priv->scan.output_power * 10);
249 }
250 priv->scan.status = cw1200_scan_start(priv, &scan);
251 kfree(scan.ch);
252 if (priv->scan.status)
253 goto fail;
254 priv->scan.curr = it;
255 }
256 mutex_unlock(&priv->conf_mutex);
257 return;
258
259fail:
260 priv->scan.curr = priv->scan.end;
261 mutex_unlock(&priv->conf_mutex);
262 queue_work(priv->workqueue, &priv->scan.work);
263 return;
264}
265
266static void cw1200_scan_restart_delayed(struct cw1200_common *priv)
267{
268 /* FW bug: driver has to restart p2p-dev mode after scan. */
269 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
270 cw1200_enable_listening(priv);
271 cw1200_update_filtering(priv);
272 }
273
274 if (priv->delayed_unjoin) {
275 priv->delayed_unjoin = false;
276 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
277 wsm_unlock_tx(priv);
278 } else if (priv->delayed_link_loss) {
279 wiphy_dbg(priv->hw->wiphy, "[CQM] Requeue BSS loss.\n");
280 priv->delayed_link_loss = 0;
281 cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
282 }
283}
284
285static void cw1200_scan_complete(struct cw1200_common *priv)
286{
287 queue_delayed_work(priv->workqueue, &priv->clear_recent_scan_work, HZ);
288 if (priv->scan.direct_probe) {
289 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe complete.\n");
290 cw1200_scan_restart_delayed(priv);
291 priv->scan.direct_probe = 0;
292 up(&priv->scan.lock);
293 wsm_unlock_tx(priv);
294 } else {
295 cw1200_scan_work(&priv->scan.work);
296 }
297}
298
299void cw1200_scan_failed_cb(struct cw1200_common *priv)
300{
301 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
302 /* STA is stopped. */
303 return;
304
305 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
306 priv->scan.status = -EIO;
307 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
308 }
309}
310
311
312void cw1200_scan_complete_cb(struct cw1200_common *priv,
313 struct wsm_scan_complete *arg)
314{
315 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
316 /* STA is stopped. */
317 return;
318
319 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
320 priv->scan.status = 1;
321 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
322 }
323}
324
325void cw1200_clear_recent_scan_work(struct work_struct *work)
326{
327 struct cw1200_common *priv =
328 container_of(work, struct cw1200_common,
329 clear_recent_scan_work.work);
330 atomic_xchg(&priv->recent_scan, 0);
331}
332
333void cw1200_scan_timeout(struct work_struct *work)
334{
335 struct cw1200_common *priv =
336 container_of(work, struct cw1200_common, scan.timeout.work);
337 if (atomic_xchg(&priv->scan.in_progress, 0)) {
338 if (priv->scan.status > 0) {
339 priv->scan.status = 0;
340 } else if (!priv->scan.status) {
341 wiphy_warn(priv->hw->wiphy,
342 "Timeout waiting for scan complete notification.\n");
343 priv->scan.status = -ETIMEDOUT;
344 priv->scan.curr = priv->scan.end;
345 wsm_stop_scan(priv);
346 }
347 cw1200_scan_complete(priv);
348 }
349}
350
351void cw1200_probe_work(struct work_struct *work)
352{
353 struct cw1200_common *priv =
354 container_of(work, struct cw1200_common, scan.probe_work.work);
355 u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
356 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
357 const struct cw1200_txpriv *txpriv;
358 struct wsm_tx *wsm;
359 struct wsm_template_frame frame = {
360 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
361 };
362 struct wsm_ssid ssids[1] = {{
363 .length = 0,
364 } };
365 struct wsm_scan_ch ch[1] = {{
366 .min_chan_time = 0,
367 .max_chan_time = 10,
368 } };
369 struct wsm_scan scan = {
370 .type = WSM_SCAN_TYPE_FOREGROUND,
371 .num_probes = 1,
372 .probe_delay = 0,
373 .num_channels = 1,
374 .ssids = ssids,
375 .ch = ch,
376 };
377 u8 *ies;
378 size_t ies_len;
379 int ret;
380
381 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe work.\n");
382
383 mutex_lock(&priv->conf_mutex);
384 if (down_trylock(&priv->scan.lock)) {
385 /* Scan is already in progress. Requeue self. */
386 schedule();
387 queue_delayed_work(priv->workqueue,
388 &priv->scan.probe_work, HZ / 10);
389 mutex_unlock(&priv->conf_mutex);
390 return;
391 }
392
393 /* Make sure we still have a pending probe req */
394 if (cw1200_queue_get_skb(queue, priv->pending_frame_id,
395 &frame.skb, &txpriv)) {
396 up(&priv->scan.lock);
397 mutex_unlock(&priv->conf_mutex);
398 wsm_unlock_tx(priv);
399 return;
400 }
401 wsm = (struct wsm_tx *)frame.skb->data;
402 scan.max_tx_rate = wsm->max_tx_rate;
403 scan.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
404 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
405 if (priv->join_status == CW1200_JOIN_STATUS_STA ||
406 priv->join_status == CW1200_JOIN_STATUS_IBSS) {
407 scan.type = WSM_SCAN_TYPE_BACKGROUND;
408 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
409 }
410 ch[0].number = priv->channel->hw_value;
411
412 skb_pull(frame.skb, txpriv->offset);
413
414 ies = &frame.skb->data[sizeof(struct ieee80211_hdr_3addr)];
415 ies_len = frame.skb->len - sizeof(struct ieee80211_hdr_3addr);
416
417 if (ies_len) {
418 u8 *ssidie =
419 (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len);
420 if (ssidie && ssidie[1] && ssidie[1] <= sizeof(ssids[0].ssid)) {
421 u8 *nextie = &ssidie[2 + ssidie[1]];
422 /* Remove SSID from the IE list. It has to be provided
423 * as a separate argument in cw1200_scan_start call
424 */
425
426 /* Store SSID localy */
427 ssids[0].length = ssidie[1];
428 memcpy(ssids[0].ssid, &ssidie[2], ssids[0].length);
429 scan.num_ssids = 1;
430
431 /* Remove SSID from IE list */
432 ssidie[1] = 0;
433 memmove(&ssidie[2], nextie, &ies[ies_len] - nextie);
434 skb_trim(frame.skb, frame.skb->len - ssids[0].length);
435 }
436 }
437
438 /* FW bug: driver has to restart p2p-dev mode after scan */
439 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
440 cw1200_disable_listening(priv);
441 ret = wsm_set_template_frame(priv, &frame);
442 priv->scan.direct_probe = 1;
443 if (!ret) {
444 wsm_flush_tx(priv);
445 ret = cw1200_scan_start(priv, &scan);
446 }
447 mutex_unlock(&priv->conf_mutex);
448
449 skb_push(frame.skb, txpriv->offset);
450 if (!ret)
451 IEEE80211_SKB_CB(frame.skb)->flags |= IEEE80211_TX_STAT_ACK;
452 BUG_ON(cw1200_queue_remove(queue, priv->pending_frame_id));
453
454 if (ret) {
455 priv->scan.direct_probe = 0;
456 up(&priv->scan.lock);
457 wsm_unlock_tx(priv);
458 }
459
460 return;
461}
diff --git a/drivers/net/wireless/cw1200/scan.h b/drivers/net/wireless/cw1200/scan.h
new file mode 100644
index 000000000000..5a8296ccfa82
--- /dev/null
+++ b/drivers/net/wireless/cw1200/scan.h
@@ -0,0 +1,56 @@
1/*
2 * Scan interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef SCAN_H_INCLUDED
13#define SCAN_H_INCLUDED
14
15#include <linux/semaphore.h>
16#include "wsm.h"
17
18/* external */ struct sk_buff;
19/* external */ struct cfg80211_scan_request;
20/* external */ struct ieee80211_channel;
21/* external */ struct ieee80211_hw;
22/* external */ struct work_struct;
23
24struct cw1200_scan {
25 struct semaphore lock;
26 struct work_struct work;
27 struct delayed_work timeout;
28 struct cfg80211_scan_request *req;
29 struct ieee80211_channel **begin;
30 struct ieee80211_channel **curr;
31 struct ieee80211_channel **end;
32 struct wsm_ssid ssids[WSM_SCAN_MAX_NUM_OF_SSIDS];
33 int output_power;
34 int n_ssids;
35 int status;
36 atomic_t in_progress;
37 /* Direct probe requests workaround */
38 struct delayed_work probe_work;
39 int direct_probe;
40};
41
42int cw1200_hw_scan(struct ieee80211_hw *hw,
43 struct ieee80211_vif *vif,
44 struct cfg80211_scan_request *req);
45void cw1200_scan_work(struct work_struct *work);
46void cw1200_scan_timeout(struct work_struct *work);
47void cw1200_clear_recent_scan_work(struct work_struct *work);
48void cw1200_scan_complete_cb(struct cw1200_common *priv,
49 struct wsm_scan_complete *arg);
50void cw1200_scan_failed_cb(struct cw1200_common *priv);
51
52/* ******************************************************************** */
53/* Raw probe requests TX workaround */
54void cw1200_probe_work(struct work_struct *work);
55
56#endif
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
new file mode 100644
index 000000000000..679c55f15c67
--- /dev/null
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -0,0 +1,2406 @@
1/*
2 * Mac80211 STA API for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/vmalloc.h>
13#include <linux/sched.h>
14#include <linux/firmware.h>
15#include <linux/module.h>
16
17#include "cw1200.h"
18#include "sta.h"
19#include "fwio.h"
20#include "bh.h"
21#include "debug.h"
22
23#ifndef ERP_INFO_BYTE_OFFSET
24#define ERP_INFO_BYTE_OFFSET 2
25#endif
26
27static void cw1200_do_join(struct cw1200_common *priv);
28static void cw1200_do_unjoin(struct cw1200_common *priv);
29
30static int cw1200_upload_beacon(struct cw1200_common *priv);
31static int cw1200_upload_pspoll(struct cw1200_common *priv);
32static int cw1200_upload_null(struct cw1200_common *priv);
33static int cw1200_upload_qosnull(struct cw1200_common *priv);
34static int cw1200_start_ap(struct cw1200_common *priv);
35static int cw1200_update_beaconing(struct cw1200_common *priv);
36static int cw1200_enable_beaconing(struct cw1200_common *priv,
37 bool enable);
38static void __cw1200_sta_notify(struct ieee80211_hw *dev,
39 struct ieee80211_vif *vif,
40 enum sta_notify_cmd notify_cmd,
41 int link_id);
42static int __cw1200_flush(struct cw1200_common *priv, bool drop);
43
44static inline void __cw1200_free_event_queue(struct list_head *list)
45{
46 struct cw1200_wsm_event *event, *tmp;
47 list_for_each_entry_safe(event, tmp, list, link) {
48 list_del(&event->link);
49 kfree(event);
50 }
51}
52
53/* ******************************************************************** */
54/* STA API */
55
56int cw1200_start(struct ieee80211_hw *dev)
57{
58 struct cw1200_common *priv = dev->priv;
59 int ret = 0;
60
61 cw1200_pm_stay_awake(&priv->pm_state, HZ);
62
63 mutex_lock(&priv->conf_mutex);
64
65 /* default EDCA */
66 WSM_EDCA_SET(&priv->edca, 0, 0x0002, 0x0003, 0x0007, 47, 0xc8, false);
67 WSM_EDCA_SET(&priv->edca, 1, 0x0002, 0x0007, 0x000f, 94, 0xc8, false);
68 WSM_EDCA_SET(&priv->edca, 2, 0x0003, 0x000f, 0x03ff, 0, 0xc8, false);
69 WSM_EDCA_SET(&priv->edca, 3, 0x0007, 0x000f, 0x03ff, 0, 0xc8, false);
70 ret = wsm_set_edca_params(priv, &priv->edca);
71 if (ret)
72 goto out;
73
74 ret = cw1200_set_uapsd_param(priv, &priv->edca);
75 if (ret)
76 goto out;
77
78 priv->setbssparams_done = false;
79
80 memcpy(priv->mac_addr, dev->wiphy->perm_addr, ETH_ALEN);
81 priv->mode = NL80211_IFTYPE_MONITOR;
82 priv->wep_default_key_id = -1;
83
84 priv->cqm_beacon_loss_count = 10;
85
86 ret = cw1200_setup_mac(priv);
87 if (ret)
88 goto out;
89
90out:
91 mutex_unlock(&priv->conf_mutex);
92 return ret;
93}
94
95void cw1200_stop(struct ieee80211_hw *dev)
96{
97 struct cw1200_common *priv = dev->priv;
98 LIST_HEAD(list);
99 int i;
100
101 wsm_lock_tx(priv);
102
103 while (down_trylock(&priv->scan.lock)) {
104 /* Scan is in progress. Force it to stop. */
105 priv->scan.req = NULL;
106 schedule();
107 }
108 up(&priv->scan.lock);
109
110 cancel_delayed_work_sync(&priv->scan.probe_work);
111 cancel_delayed_work_sync(&priv->scan.timeout);
112 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
113 cancel_delayed_work_sync(&priv->join_timeout);
114 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
115 cancel_work_sync(&priv->unjoin_work);
116 cancel_delayed_work_sync(&priv->link_id_gc_work);
117 flush_workqueue(priv->workqueue);
118 del_timer_sync(&priv->mcast_timeout);
119 mutex_lock(&priv->conf_mutex);
120 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
121 priv->listening = false;
122
123 spin_lock(&priv->event_queue_lock);
124 list_splice_init(&priv->event_queue, &list);
125 spin_unlock(&priv->event_queue_lock);
126 __cw1200_free_event_queue(&list);
127
128
129 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
130 priv->join_pending = false;
131
132 for (i = 0; i < 4; i++)
133 cw1200_queue_clear(&priv->tx_queue[i]);
134 mutex_unlock(&priv->conf_mutex);
135 tx_policy_clean(priv);
136
137 /* HACK! */
138 if (atomic_xchg(&priv->tx_lock, 1) != 1)
139 pr_debug("[STA] TX is force-unlocked due to stop request.\n");
140
141 wsm_unlock_tx(priv);
142 atomic_xchg(&priv->tx_lock, 0); /* for recovery to work */
143}
144
145static int cw1200_bssloss_mitigation = 1;
146module_param(cw1200_bssloss_mitigation, int, 0644);
147MODULE_PARM_DESC(cw1200_bssloss_mitigation, "BSS Loss mitigation. 0 == disabled, 1 == enabled (default)");
148
149
150void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
151 int init, int good, int bad)
152{
153 int tx = 0;
154
155 priv->delayed_link_loss = 0;
156 cancel_work_sync(&priv->bss_params_work);
157
158 pr_debug("[STA] CQM BSSLOSS_SM: state: %d init %d good %d bad: %d txlock: %d uj: %d\n",
159 priv->bss_loss_state,
160 init, good, bad,
161 atomic_read(&priv->tx_lock),
162 priv->delayed_unjoin);
163
164 /* If we have a pending unjoin */
165 if (priv->delayed_unjoin)
166 return;
167
168 if (init) {
169 queue_delayed_work(priv->workqueue,
170 &priv->bss_loss_work,
171 HZ);
172 priv->bss_loss_state = 0;
173
174 /* Skip the confimration procedure in P2P case */
175 if (!priv->vif->p2p && !atomic_read(&priv->tx_lock))
176 tx = 1;
177 } else if (good) {
178 cancel_delayed_work_sync(&priv->bss_loss_work);
179 priv->bss_loss_state = 0;
180 queue_work(priv->workqueue, &priv->bss_params_work);
181 } else if (bad) {
182 /* XXX Should we just keep going until we time out? */
183 if (priv->bss_loss_state < 3)
184 tx = 1;
185 } else {
186 cancel_delayed_work_sync(&priv->bss_loss_work);
187 priv->bss_loss_state = 0;
188 }
189
190 /* Bypass mitigation if it's disabled */
191 if (!cw1200_bssloss_mitigation)
192 tx = 0;
193
194 /* Spit out a NULL packet to our AP if necessary */
195 if (tx) {
196 struct sk_buff *skb;
197
198 priv->bss_loss_state++;
199
200 skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
201 WARN_ON(!skb);
202 if (skb)
203 cw1200_tx(priv->hw, NULL, skb);
204 }
205}
206
207int cw1200_add_interface(struct ieee80211_hw *dev,
208 struct ieee80211_vif *vif)
209{
210 int ret;
211 struct cw1200_common *priv = dev->priv;
212 /* __le32 auto_calibration_mode = __cpu_to_le32(1); */
213
214 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
215 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
216
217 mutex_lock(&priv->conf_mutex);
218
219 if (priv->mode != NL80211_IFTYPE_MONITOR) {
220 mutex_unlock(&priv->conf_mutex);
221 return -EOPNOTSUPP;
222 }
223
224 switch (vif->type) {
225 case NL80211_IFTYPE_STATION:
226 case NL80211_IFTYPE_ADHOC:
227 case NL80211_IFTYPE_MESH_POINT:
228 case NL80211_IFTYPE_AP:
229 priv->mode = vif->type;
230 break;
231 default:
232 mutex_unlock(&priv->conf_mutex);
233 return -EOPNOTSUPP;
234 }
235
236 priv->vif = vif;
237 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
238 ret = cw1200_setup_mac(priv);
239 /* Enable auto-calibration */
240 /* Exception in subsequent channel switch; disabled.
241 * wsm_write_mib(priv, WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE,
242 * &auto_calibration_mode, sizeof(auto_calibration_mode));
243 */
244
245 mutex_unlock(&priv->conf_mutex);
246 return ret;
247}
248
249void cw1200_remove_interface(struct ieee80211_hw *dev,
250 struct ieee80211_vif *vif)
251{
252 struct cw1200_common *priv = dev->priv;
253 struct wsm_reset reset = {
254 .reset_statistics = true,
255 };
256 int i;
257
258 mutex_lock(&priv->conf_mutex);
259 switch (priv->join_status) {
260 case CW1200_JOIN_STATUS_JOINING:
261 case CW1200_JOIN_STATUS_PRE_STA:
262 case CW1200_JOIN_STATUS_STA:
263 case CW1200_JOIN_STATUS_IBSS:
264 wsm_lock_tx(priv);
265 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
266 wsm_unlock_tx(priv);
267 break;
268 case CW1200_JOIN_STATUS_AP:
269 for (i = 0; priv->link_id_map; ++i) {
270 if (priv->link_id_map & BIT(i)) {
271 reset.link_id = i;
272 wsm_reset(priv, &reset);
273 priv->link_id_map &= ~BIT(i);
274 }
275 }
276 memset(priv->link_id_db, 0, sizeof(priv->link_id_db));
277 priv->sta_asleep_mask = 0;
278 priv->enable_beacon = false;
279 priv->tx_multicast = false;
280 priv->aid0_bit_set = false;
281 priv->buffered_multicasts = false;
282 priv->pspoll_mask = 0;
283 reset.link_id = 0;
284 wsm_reset(priv, &reset);
285 break;
286 case CW1200_JOIN_STATUS_MONITOR:
287 cw1200_update_listening(priv, false);
288 break;
289 default:
290 break;
291 }
292 priv->vif = NULL;
293 priv->mode = NL80211_IFTYPE_MONITOR;
294 memset(priv->mac_addr, 0, ETH_ALEN);
295 memset(&priv->p2p_ps_modeinfo, 0, sizeof(priv->p2p_ps_modeinfo));
296 cw1200_free_keys(priv);
297 cw1200_setup_mac(priv);
298 priv->listening = false;
299 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
300 if (!__cw1200_flush(priv, true))
301 wsm_unlock_tx(priv);
302
303 mutex_unlock(&priv->conf_mutex);
304}
305
306int cw1200_change_interface(struct ieee80211_hw *dev,
307 struct ieee80211_vif *vif,
308 enum nl80211_iftype new_type,
309 bool p2p)
310{
311 int ret = 0;
312 pr_debug("change_interface new: %d (%d), old: %d (%d)\n", new_type,
313 p2p, vif->type, vif->p2p);
314
315 if (new_type != vif->type || vif->p2p != p2p) {
316 cw1200_remove_interface(dev, vif);
317 vif->type = new_type;
318 vif->p2p = p2p;
319 ret = cw1200_add_interface(dev, vif);
320 }
321
322 return ret;
323}
324
325int cw1200_config(struct ieee80211_hw *dev, u32 changed)
326{
327 int ret = 0;
328 struct cw1200_common *priv = dev->priv;
329 struct ieee80211_conf *conf = &dev->conf;
330
331 pr_debug("CONFIG CHANGED: %08x\n", changed);
332
333 down(&priv->scan.lock);
334 mutex_lock(&priv->conf_mutex);
335 /* TODO: IEEE80211_CONF_CHANGE_QOS */
336 /* TODO: IEEE80211_CONF_CHANGE_LISTEN_INTERVAL */
337
338 if (changed & IEEE80211_CONF_CHANGE_POWER) {
339 priv->output_power = conf->power_level;
340 pr_debug("[STA] TX power: %d\n", priv->output_power);
341 wsm_set_output_power(priv, priv->output_power * 10);
342 }
343
344 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) &&
345 (priv->channel != conf->chandef.chan)) {
346 struct ieee80211_channel *ch = conf->chandef.chan;
347 struct wsm_switch_channel channel = {
348 .channel_number = ch->hw_value,
349 };
350 pr_debug("[STA] Freq %d (wsm ch: %d).\n",
351 ch->center_freq, ch->hw_value);
352
353 /* __cw1200_flush() implicitly locks tx, if successful */
354 if (!__cw1200_flush(priv, false)) {
355 if (!wsm_switch_channel(priv, &channel)) {
356 ret = wait_event_timeout(priv->channel_switch_done,
357 !priv->channel_switch_in_progress,
358 3 * HZ);
359 if (ret) {
360 /* Already unlocks if successful */
361 priv->channel = ch;
362 ret = 0;
363 } else {
364 ret = -ETIMEDOUT;
365 }
366 } else {
367 /* Unlock if switch channel fails */
368 wsm_unlock_tx(priv);
369 }
370 }
371 }
372
373 if (changed & IEEE80211_CONF_CHANGE_PS) {
374 if (!(conf->flags & IEEE80211_CONF_PS))
375 priv->powersave_mode.mode = WSM_PSM_ACTIVE;
376 else if (conf->dynamic_ps_timeout <= 0)
377 priv->powersave_mode.mode = WSM_PSM_PS;
378 else
379 priv->powersave_mode.mode = WSM_PSM_FAST_PS;
380
381 /* Firmware requires that value for this 1-byte field must
382 * be specified in units of 500us. Values above the 128ms
383 * threshold are not supported.
384 */
385 if (conf->dynamic_ps_timeout >= 0x80)
386 priv->powersave_mode.fast_psm_idle_period = 0xFF;
387 else
388 priv->powersave_mode.fast_psm_idle_period =
389 conf->dynamic_ps_timeout << 1;
390
391 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
392 priv->bss_params.aid)
393 cw1200_set_pm(priv, &priv->powersave_mode);
394 }
395
396 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
397 /* TBD: It looks like it's transparent
398 * there's a monitor interface present -- use this
399 * to determine for example whether to calculate
400 * timestamps for packets or not, do not use instead
401 * of filter flags!
402 */
403 }
404
405 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
406 struct wsm_operational_mode mode = {
407 .power_mode = cw1200_power_mode,
408 .disable_more_flag_usage = true,
409 };
410
411 wsm_lock_tx(priv);
412 /* Disable p2p-dev mode forced by TX request */
413 if ((priv->join_status == CW1200_JOIN_STATUS_MONITOR) &&
414 (conf->flags & IEEE80211_CONF_IDLE) &&
415 !priv->listening) {
416 cw1200_disable_listening(priv);
417 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
418 }
419 wsm_set_operational_mode(priv, &mode);
420 wsm_unlock_tx(priv);
421 }
422
423 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
424 pr_debug("[STA] Retry limits: %d (long), %d (short).\n",
425 conf->long_frame_max_tx_count,
426 conf->short_frame_max_tx_count);
427 spin_lock_bh(&priv->tx_policy_cache.lock);
428 priv->long_frame_max_tx_count = conf->long_frame_max_tx_count;
429 priv->short_frame_max_tx_count =
430 (conf->short_frame_max_tx_count < 0x0F) ?
431 conf->short_frame_max_tx_count : 0x0F;
432 priv->hw->max_rate_tries = priv->short_frame_max_tx_count;
433 spin_unlock_bh(&priv->tx_policy_cache.lock);
434 }
435 mutex_unlock(&priv->conf_mutex);
436 up(&priv->scan.lock);
437 return ret;
438}
439
440void cw1200_update_filtering(struct cw1200_common *priv)
441{
442 int ret;
443 bool bssid_filtering = !priv->rx_filter.bssid;
444 bool is_p2p = priv->vif && priv->vif->p2p;
445 bool is_sta = priv->vif && NL80211_IFTYPE_STATION == priv->vif->type;
446
447 static struct wsm_beacon_filter_control bf_ctrl;
448 static struct wsm_mib_beacon_filter_table bf_tbl = {
449 .entry[0].ie_id = WLAN_EID_VENDOR_SPECIFIC,
450 .entry[0].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
451 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
452 WSM_BEACON_FILTER_IE_HAS_APPEARED,
453 .entry[0].oui[0] = 0x50,
454 .entry[0].oui[1] = 0x6F,
455 .entry[0].oui[2] = 0x9A,
456 .entry[1].ie_id = WLAN_EID_HT_OPERATION,
457 .entry[1].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
458 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
459 WSM_BEACON_FILTER_IE_HAS_APPEARED,
460 .entry[2].ie_id = WLAN_EID_ERP_INFO,
461 .entry[2].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
462 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
463 WSM_BEACON_FILTER_IE_HAS_APPEARED,
464 };
465
466 if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE)
467 return;
468 else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
469 bssid_filtering = false;
470
471 if (priv->disable_beacon_filter) {
472 bf_ctrl.enabled = 0;
473 bf_ctrl.bcn_count = 1;
474 bf_tbl.num = __cpu_to_le32(0);
475 } else if (is_p2p || !is_sta) {
476 bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE |
477 WSM_BEACON_FILTER_AUTO_ERP;
478 bf_ctrl.bcn_count = 0;
479 bf_tbl.num = __cpu_to_le32(2);
480 } else {
481 bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE;
482 bf_ctrl.bcn_count = 0;
483 bf_tbl.num = __cpu_to_le32(3);
484 }
485
486 /*
487 * When acting as p2p client being connected to p2p GO, in order to
488 * receive frames from a different p2p device, turn off bssid filter.
489 *
490 * WARNING: FW dependency!
491 * This can only be used with FW WSM371 and its successors.
492 * In that FW version even with bssid filter turned off,
493 * device will block most of the unwanted frames.
494 */
495 if (is_p2p)
496 bssid_filtering = false;
497
498 ret = wsm_set_rx_filter(priv, &priv->rx_filter);
499 if (!ret)
500 ret = wsm_set_beacon_filter_table(priv, &bf_tbl);
501 if (!ret)
502 ret = wsm_beacon_filter_control(priv, &bf_ctrl);
503 if (!ret)
504 ret = wsm_set_bssid_filtering(priv, bssid_filtering);
505 if (!ret)
506 ret = wsm_set_multicast_filter(priv, &priv->multicast_filter);
507 if (ret)
508 wiphy_err(priv->hw->wiphy,
509 "Update filtering failed: %d.\n", ret);
510 return;
511}
512
513void cw1200_update_filtering_work(struct work_struct *work)
514{
515 struct cw1200_common *priv =
516 container_of(work, struct cw1200_common,
517 update_filtering_work);
518
519 cw1200_update_filtering(priv);
520}
521
522void cw1200_set_beacon_wakeup_period_work(struct work_struct *work)
523{
524 struct cw1200_common *priv =
525 container_of(work, struct cw1200_common,
526 set_beacon_wakeup_period_work);
527
528 wsm_set_beacon_wakeup_period(priv,
529 priv->beacon_int * priv->join_dtim_period >
530 MAX_BEACON_SKIP_TIME_MS ? 1 :
531 priv->join_dtim_period, 0);
532}
533
534u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
535 struct netdev_hw_addr_list *mc_list)
536{
537 static u8 broadcast_ipv6[ETH_ALEN] = {
538 0x33, 0x33, 0x00, 0x00, 0x00, 0x01
539 };
540 static u8 broadcast_ipv4[ETH_ALEN] = {
541 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01
542 };
543 struct cw1200_common *priv = hw->priv;
544 struct netdev_hw_addr *ha;
545 int count = 0;
546
547 /* Disable multicast filtering */
548 priv->has_multicast_subscription = false;
549 memset(&priv->multicast_filter, 0x00, sizeof(priv->multicast_filter));
550
551 if (netdev_hw_addr_list_count(mc_list) > WSM_MAX_GRP_ADDRTABLE_ENTRIES)
552 return 0;
553
554 /* Enable if requested */
555 netdev_hw_addr_list_for_each(ha, mc_list) {
556 pr_debug("[STA] multicast: %pM\n", ha->addr);
557 memcpy(&priv->multicast_filter.macaddrs[count],
558 ha->addr, ETH_ALEN);
559 if (memcmp(ha->addr, broadcast_ipv4, ETH_ALEN) &&
560 memcmp(ha->addr, broadcast_ipv6, ETH_ALEN))
561 priv->has_multicast_subscription = true;
562 count++;
563 }
564
565 if (count) {
566 priv->multicast_filter.enable = __cpu_to_le32(1);
567 priv->multicast_filter.num_addrs = __cpu_to_le32(count);
568 }
569
570 return netdev_hw_addr_list_count(mc_list);
571}
572
573void cw1200_configure_filter(struct ieee80211_hw *dev,
574 unsigned int changed_flags,
575 unsigned int *total_flags,
576 u64 multicast)
577{
578 struct cw1200_common *priv = dev->priv;
579 bool listening = !!(*total_flags &
580 (FIF_PROMISC_IN_BSS |
581 FIF_OTHER_BSS |
582 FIF_BCN_PRBRESP_PROMISC |
583 FIF_PROBE_REQ));
584
585 *total_flags &= FIF_PROMISC_IN_BSS |
586 FIF_OTHER_BSS |
587 FIF_FCSFAIL |
588 FIF_BCN_PRBRESP_PROMISC |
589 FIF_PROBE_REQ;
590
591 down(&priv->scan.lock);
592 mutex_lock(&priv->conf_mutex);
593
594 priv->rx_filter.promiscuous = (*total_flags & FIF_PROMISC_IN_BSS)
595 ? 1 : 0;
596 priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS |
597 FIF_PROBE_REQ)) ? 1 : 0;
598 priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0;
599 priv->disable_beacon_filter = !(*total_flags &
600 (FIF_BCN_PRBRESP_PROMISC |
601 FIF_PROMISC_IN_BSS |
602 FIF_PROBE_REQ));
603 if (priv->listening != listening) {
604 priv->listening = listening;
605 wsm_lock_tx(priv);
606 cw1200_update_listening(priv, listening);
607 wsm_unlock_tx(priv);
608 }
609 cw1200_update_filtering(priv);
610 mutex_unlock(&priv->conf_mutex);
611 up(&priv->scan.lock);
612}
613
614int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
615 u16 queue, const struct ieee80211_tx_queue_params *params)
616{
617 struct cw1200_common *priv = dev->priv;
618 int ret = 0;
619 /* To prevent re-applying PM request OID again and again*/
620 bool old_uapsd_flags;
621
622 mutex_lock(&priv->conf_mutex);
623
624 if (queue < dev->queues) {
625 old_uapsd_flags = priv->uapsd_info.uapsd_flags;
626
627 WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
628 ret = wsm_set_tx_queue_params(priv,
629 &priv->tx_queue_params.params[queue], queue);
630 if (ret) {
631 ret = -EINVAL;
632 goto out;
633 }
634
635 WSM_EDCA_SET(&priv->edca, queue, params->aifs,
636 params->cw_min, params->cw_max,
637 params->txop, 0xc8,
638 params->uapsd);
639 ret = wsm_set_edca_params(priv, &priv->edca);
640 if (ret) {
641 ret = -EINVAL;
642 goto out;
643 }
644
645 if (priv->mode == NL80211_IFTYPE_STATION) {
646 ret = cw1200_set_uapsd_param(priv, &priv->edca);
647 if (!ret && priv->setbssparams_done &&
648 (priv->join_status == CW1200_JOIN_STATUS_STA) &&
649 (old_uapsd_flags != priv->uapsd_info.uapsd_flags))
650 ret = cw1200_set_pm(priv, &priv->powersave_mode);
651 }
652 } else {
653 ret = -EINVAL;
654 }
655
656out:
657 mutex_unlock(&priv->conf_mutex);
658 return ret;
659}
660
661int cw1200_get_stats(struct ieee80211_hw *dev,
662 struct ieee80211_low_level_stats *stats)
663{
664 struct cw1200_common *priv = dev->priv;
665
666 memcpy(stats, &priv->stats, sizeof(*stats));
667 return 0;
668}
669
670int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
671{
672 struct wsm_set_pm pm = *arg;
673
674 if (priv->uapsd_info.uapsd_flags != 0)
675 pm.mode &= ~WSM_PSM_FAST_PS_FLAG;
676
677 if (memcmp(&pm, &priv->firmware_ps_mode,
678 sizeof(struct wsm_set_pm))) {
679 priv->firmware_ps_mode = pm;
680 return wsm_set_pm(priv, &pm);
681 } else {
682 return 0;
683 }
684}
685
686int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
687 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
688 struct ieee80211_key_conf *key)
689{
690 int ret = -EOPNOTSUPP;
691 struct cw1200_common *priv = dev->priv;
692 struct ieee80211_key_seq seq;
693
694 mutex_lock(&priv->conf_mutex);
695
696 if (cmd == SET_KEY) {
697 u8 *peer_addr = NULL;
698 int pairwise = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
699 1 : 0;
700 int idx = cw1200_alloc_key(priv);
701 struct wsm_add_key *wsm_key = &priv->keys[idx];
702
703 if (idx < 0) {
704 ret = -EINVAL;
705 goto finally;
706 }
707
708 if (sta)
709 peer_addr = sta->addr;
710
711 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
712
713 switch (key->cipher) {
714 case WLAN_CIPHER_SUITE_WEP40:
715 case WLAN_CIPHER_SUITE_WEP104:
716 if (key->keylen > 16) {
717 cw1200_free_key(priv, idx);
718 ret = -EINVAL;
719 goto finally;
720 }
721
722 if (pairwise) {
723 wsm_key->type = WSM_KEY_TYPE_WEP_PAIRWISE;
724 memcpy(wsm_key->wep_pairwise.peer,
725 peer_addr, ETH_ALEN);
726 memcpy(wsm_key->wep_pairwise.keydata,
727 &key->key[0], key->keylen);
728 wsm_key->wep_pairwise.keylen = key->keylen;
729 } else {
730 wsm_key->type = WSM_KEY_TYPE_WEP_DEFAULT;
731 memcpy(wsm_key->wep_group.keydata,
732 &key->key[0], key->keylen);
733 wsm_key->wep_group.keylen = key->keylen;
734 wsm_key->wep_group.keyid = key->keyidx;
735 }
736 break;
737 case WLAN_CIPHER_SUITE_TKIP:
738 ieee80211_get_key_rx_seq(key, 0, &seq);
739 if (pairwise) {
740 wsm_key->type = WSM_KEY_TYPE_TKIP_PAIRWISE;
741 memcpy(wsm_key->tkip_pairwise.peer,
742 peer_addr, ETH_ALEN);
743 memcpy(wsm_key->tkip_pairwise.keydata,
744 &key->key[0], 16);
745 memcpy(wsm_key->tkip_pairwise.tx_mic_key,
746 &key->key[16], 8);
747 memcpy(wsm_key->tkip_pairwise.rx_mic_key,
748 &key->key[24], 8);
749 } else {
750 size_t mic_offset =
751 (priv->mode == NL80211_IFTYPE_AP) ?
752 16 : 24;
753 wsm_key->type = WSM_KEY_TYPE_TKIP_GROUP;
754 memcpy(wsm_key->tkip_group.keydata,
755 &key->key[0], 16);
756 memcpy(wsm_key->tkip_group.rx_mic_key,
757 &key->key[mic_offset], 8);
758
759 wsm_key->tkip_group.rx_seqnum[0] = seq.tkip.iv16 & 0xff;
760 wsm_key->tkip_group.rx_seqnum[1] = (seq.tkip.iv16 >> 8) & 0xff;
761 wsm_key->tkip_group.rx_seqnum[2] = seq.tkip.iv32 & 0xff;
762 wsm_key->tkip_group.rx_seqnum[3] = (seq.tkip.iv32 >> 8) & 0xff;
763 wsm_key->tkip_group.rx_seqnum[4] = (seq.tkip.iv32 >> 16) & 0xff;
764 wsm_key->tkip_group.rx_seqnum[5] = (seq.tkip.iv32 >> 24) & 0xff;
765 wsm_key->tkip_group.rx_seqnum[6] = 0;
766 wsm_key->tkip_group.rx_seqnum[7] = 0;
767
768 wsm_key->tkip_group.keyid = key->keyidx;
769 }
770 break;
771 case WLAN_CIPHER_SUITE_CCMP:
772 ieee80211_get_key_rx_seq(key, 0, &seq);
773 if (pairwise) {
774 wsm_key->type = WSM_KEY_TYPE_AES_PAIRWISE;
775 memcpy(wsm_key->aes_pairwise.peer,
776 peer_addr, ETH_ALEN);
777 memcpy(wsm_key->aes_pairwise.keydata,
778 &key->key[0], 16);
779 } else {
780 wsm_key->type = WSM_KEY_TYPE_AES_GROUP;
781 memcpy(wsm_key->aes_group.keydata,
782 &key->key[0], 16);
783
784 wsm_key->aes_group.rx_seqnum[0] = seq.ccmp.pn[5];
785 wsm_key->aes_group.rx_seqnum[1] = seq.ccmp.pn[4];
786 wsm_key->aes_group.rx_seqnum[2] = seq.ccmp.pn[3];
787 wsm_key->aes_group.rx_seqnum[3] = seq.ccmp.pn[2];
788 wsm_key->aes_group.rx_seqnum[4] = seq.ccmp.pn[1];
789 wsm_key->aes_group.rx_seqnum[5] = seq.ccmp.pn[0];
790 wsm_key->aes_group.rx_seqnum[6] = 0;
791 wsm_key->aes_group.rx_seqnum[7] = 0;
792 wsm_key->aes_group.keyid = key->keyidx;
793 }
794 break;
795 case WLAN_CIPHER_SUITE_SMS4:
796 if (pairwise) {
797 wsm_key->type = WSM_KEY_TYPE_WAPI_PAIRWISE;
798 memcpy(wsm_key->wapi_pairwise.peer,
799 peer_addr, ETH_ALEN);
800 memcpy(wsm_key->wapi_pairwise.keydata,
801 &key->key[0], 16);
802 memcpy(wsm_key->wapi_pairwise.mic_key,
803 &key->key[16], 16);
804 wsm_key->wapi_pairwise.keyid = key->keyidx;
805 } else {
806 wsm_key->type = WSM_KEY_TYPE_WAPI_GROUP;
807 memcpy(wsm_key->wapi_group.keydata,
808 &key->key[0], 16);
809 memcpy(wsm_key->wapi_group.mic_key,
810 &key->key[16], 16);
811 wsm_key->wapi_group.keyid = key->keyidx;
812 }
813 break;
814 default:
815 pr_warn("Unhandled key type %d\n", key->cipher);
816 cw1200_free_key(priv, idx);
817 ret = -EOPNOTSUPP;
818 goto finally;
819 }
820 ret = wsm_add_key(priv, wsm_key);
821 if (!ret)
822 key->hw_key_idx = idx;
823 else
824 cw1200_free_key(priv, idx);
825 } else if (cmd == DISABLE_KEY) {
826 struct wsm_remove_key wsm_key = {
827 .index = key->hw_key_idx,
828 };
829
830 if (wsm_key.index > WSM_KEY_MAX_INDEX) {
831 ret = -EINVAL;
832 goto finally;
833 }
834
835 cw1200_free_key(priv, wsm_key.index);
836 ret = wsm_remove_key(priv, &wsm_key);
837 } else {
838 pr_warn("Unhandled key command %d\n", cmd);
839 }
840
841finally:
842 mutex_unlock(&priv->conf_mutex);
843 return ret;
844}
845
846void cw1200_wep_key_work(struct work_struct *work)
847{
848 struct cw1200_common *priv =
849 container_of(work, struct cw1200_common, wep_key_work);
850 u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
851 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
852 __le32 wep_default_key_id = __cpu_to_le32(
853 priv->wep_default_key_id);
854
855 pr_debug("[STA] Setting default WEP key: %d\n",
856 priv->wep_default_key_id);
857 wsm_flush_tx(priv);
858 wsm_write_mib(priv, WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
859 &wep_default_key_id, sizeof(wep_default_key_id));
860 cw1200_queue_requeue(queue, priv->pending_frame_id);
861 wsm_unlock_tx(priv);
862}
863
864int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
865{
866 int ret = 0;
867 __le32 val32;
868 struct cw1200_common *priv = hw->priv;
869
870 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
871 return 0;
872
873 if (value != (u32) -1)
874 val32 = __cpu_to_le32(value);
875 else
876 val32 = 0; /* disabled */
877
878 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
879 /* device is down, can _not_ set threshold */
880 ret = -ENODEV;
881 goto out;
882 }
883
884 if (priv->rts_threshold == value)
885 goto out;
886
887 pr_debug("[STA] Setting RTS threshold: %d\n",
888 priv->rts_threshold);
889
890 /* mutex_lock(&priv->conf_mutex); */
891 ret = wsm_write_mib(priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
892 &val32, sizeof(val32));
893 if (!ret)
894 priv->rts_threshold = value;
895 /* mutex_unlock(&priv->conf_mutex); */
896
897out:
898 return ret;
899}
900
901/* If successful, LOCKS the TX queue! */
902static int __cw1200_flush(struct cw1200_common *priv, bool drop)
903{
904 int i, ret;
905
906 for (;;) {
907 /* TODO: correct flush handling is required when dev_stop.
908 * Temporary workaround: 2s
909 */
910 if (drop) {
911 for (i = 0; i < 4; ++i)
912 cw1200_queue_clear(&priv->tx_queue[i]);
913 } else {
914 ret = wait_event_timeout(
915 priv->tx_queue_stats.wait_link_id_empty,
916 cw1200_queue_stats_is_empty(
917 &priv->tx_queue_stats, -1),
918 2 * HZ);
919 }
920
921 if (!drop && ret <= 0) {
922 ret = -ETIMEDOUT;
923 break;
924 } else {
925 ret = 0;
926 }
927
928 wsm_lock_tx(priv);
929 if (!cw1200_queue_stats_is_empty(&priv->tx_queue_stats, -1)) {
930 /* Highly unlikely: WSM requeued frames. */
931 wsm_unlock_tx(priv);
932 continue;
933 }
934 break;
935 }
936 return ret;
937}
938
939void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
940{
941 struct cw1200_common *priv = hw->priv;
942
943 switch (priv->mode) {
944 case NL80211_IFTYPE_MONITOR:
945 drop = true;
946 break;
947 case NL80211_IFTYPE_AP:
948 if (!priv->enable_beacon)
949 drop = true;
950 break;
951 }
952
953 if (!__cw1200_flush(priv, drop))
954 wsm_unlock_tx(priv);
955
956 return;
957}
958
959/* ******************************************************************** */
960/* WSM callbacks */
961
962void cw1200_free_event_queue(struct cw1200_common *priv)
963{
964 LIST_HEAD(list);
965
966 spin_lock(&priv->event_queue_lock);
967 list_splice_init(&priv->event_queue, &list);
968 spin_unlock(&priv->event_queue_lock);
969
970 __cw1200_free_event_queue(&list);
971}
972
973void cw1200_event_handler(struct work_struct *work)
974{
975 struct cw1200_common *priv =
976 container_of(work, struct cw1200_common, event_handler);
977 struct cw1200_wsm_event *event;
978 LIST_HEAD(list);
979
980 spin_lock(&priv->event_queue_lock);
981 list_splice_init(&priv->event_queue, &list);
982 spin_unlock(&priv->event_queue_lock);
983
984 list_for_each_entry(event, &list, link) {
985 switch (event->evt.id) {
986 case WSM_EVENT_ERROR:
987 pr_err("Unhandled WSM Error from LMAC\n");
988 break;
989 case WSM_EVENT_BSS_LOST:
990 pr_debug("[CQM] BSS lost.\n");
991 cancel_work_sync(&priv->unjoin_work);
992 if (!down_trylock(&priv->scan.lock)) {
993 cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
994 up(&priv->scan.lock);
995 } else {
996 /* Scan is in progress. Delay reporting.
997 * Scan complete will trigger bss_loss_work
998 */
999 priv->delayed_link_loss = 1;
1000 /* Also start a watchdog. */
1001 queue_delayed_work(priv->workqueue,
1002 &priv->bss_loss_work, 5*HZ);
1003 }
1004 break;
1005 case WSM_EVENT_BSS_REGAINED:
1006 pr_debug("[CQM] BSS regained.\n");
1007 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1008 cancel_work_sync(&priv->unjoin_work);
1009 break;
1010 case WSM_EVENT_RADAR_DETECTED:
1011 wiphy_info(priv->hw->wiphy, "radar pulse detected\n");
1012 break;
1013 case WSM_EVENT_RCPI_RSSI:
1014 {
1015 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
1016 * RSSI = RCPI / 2 - 110
1017 */
1018 int rcpiRssi = (int)(event->evt.data & 0xFF);
1019 int cqm_evt;
1020 if (priv->cqm_use_rssi)
1021 rcpiRssi = (s8)rcpiRssi;
1022 else
1023 rcpiRssi = rcpiRssi / 2 - 110;
1024
1025 cqm_evt = (rcpiRssi <= priv->cqm_rssi_thold) ?
1026 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
1027 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
1028 pr_debug("[CQM] RSSI event: %d.\n", rcpiRssi);
1029 ieee80211_cqm_rssi_notify(priv->vif, cqm_evt,
1030 GFP_KERNEL);
1031 break;
1032 }
1033 case WSM_EVENT_BT_INACTIVE:
1034 pr_warn("Unhandled BT INACTIVE from LMAC\n");
1035 break;
1036 case WSM_EVENT_BT_ACTIVE:
1037 pr_warn("Unhandled BT ACTIVE from LMAC\n");
1038 break;
1039 }
1040 }
1041 __cw1200_free_event_queue(&list);
1042}
1043
1044void cw1200_bss_loss_work(struct work_struct *work)
1045{
1046 struct cw1200_common *priv =
1047 container_of(work, struct cw1200_common, bss_loss_work.work);
1048
1049 pr_debug("[CQM] Reporting connection loss.\n");
1050 wsm_lock_tx(priv);
1051 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1052 wsm_unlock_tx(priv);
1053}
1054
1055void cw1200_bss_params_work(struct work_struct *work)
1056{
1057 struct cw1200_common *priv =
1058 container_of(work, struct cw1200_common, bss_params_work);
1059 mutex_lock(&priv->conf_mutex);
1060
1061 priv->bss_params.reset_beacon_loss = 1;
1062 wsm_set_bss_params(priv, &priv->bss_params);
1063 priv->bss_params.reset_beacon_loss = 0;
1064
1065 mutex_unlock(&priv->conf_mutex);
1066}
1067
1068/* ******************************************************************** */
1069/* Internal API */
1070
1071/*
1072 * This function is called to Parse the SDD file
1073 * to extract listen_interval and PTA related information
1074 * sdd is a TLV: u8 id, u8 len, u8 data[]
1075 */
1076static int cw1200_parse_sdd_file(struct cw1200_common *priv)
1077{
1078 const u8 *p = priv->sdd->data;
1079 int ret = 0;
1080
1081 while (p + 2 <= priv->sdd->data + priv->sdd->size) {
1082 if (p + p[1] + 2 > priv->sdd->data + priv->sdd->size) {
1083 pr_warn("Malformed sdd structure\n");
1084 return -1;
1085 }
1086 switch (p[0]) {
1087 case SDD_PTA_CFG_ELT_ID: {
1088 u16 v;
1089 if (p[1] < 4) {
1090 pr_warn("SDD_PTA_CFG_ELT_ID malformed\n");
1091 ret = -1;
1092 break;
1093 }
1094 v = le16_to_cpu(*((u16 *)(p + 2)));
1095 if (!v) /* non-zero means this is enabled */
1096 break;
1097
1098 v = le16_to_cpu(*((u16 *)(p + 4)));
1099 priv->conf_listen_interval = (v >> 7) & 0x1F;
1100 pr_debug("PTA found; Listen Interval %d\n",
1101 priv->conf_listen_interval);
1102 break;
1103 }
1104 case SDD_REFERENCE_FREQUENCY_ELT_ID: {
1105 u16 clk = le16_to_cpu(*((u16 *)(p + 2)));
1106 if (clk != priv->hw_refclk)
1107 pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n",
1108 clk, priv->hw_refclk);
1109 break;
1110 }
1111 default:
1112 break;
1113 }
1114 p += p[1] + 2;
1115 }
1116
1117 if (!priv->bt_present) {
1118 pr_debug("PTA element NOT found.\n");
1119 priv->conf_listen_interval = 0;
1120 }
1121 return ret;
1122}
1123
1124int cw1200_setup_mac(struct cw1200_common *priv)
1125{
1126 int ret = 0;
1127
1128 /* NOTE: There is a bug in FW: it reports signal
1129 * as RSSI if RSSI subscription is enabled.
1130 * It's not enough to set WSM_RCPI_RSSI_USE_RSSI.
1131 *
1132 * NOTE2: RSSI based reports have been switched to RCPI, since
1133 * FW has a bug and RSSI reported values are not stable,
1134 * what can leads to signal level oscilations in user-end applications
1135 */
1136 struct wsm_rcpi_rssi_threshold threshold = {
1137 .rssiRcpiMode = WSM_RCPI_RSSI_THRESHOLD_ENABLE |
1138 WSM_RCPI_RSSI_DONT_USE_UPPER |
1139 WSM_RCPI_RSSI_DONT_USE_LOWER,
1140 .rollingAverageCount = 16,
1141 };
1142
1143 struct wsm_configuration cfg = {
1144 .dot11StationId = &priv->mac_addr[0],
1145 };
1146
1147 /* Remember the decission here to make sure, we will handle
1148 * the RCPI/RSSI value correctly on WSM_EVENT_RCPI_RSS
1149 */
1150 if (threshold.rssiRcpiMode & WSM_RCPI_RSSI_USE_RSSI)
1151 priv->cqm_use_rssi = true;
1152
1153 if (!priv->sdd) {
1154 ret = request_firmware(&priv->sdd, priv->sdd_path, priv->pdev);
1155 if (ret) {
1156 pr_err("Can't load sdd file %s.\n", priv->sdd_path);
1157 return ret;
1158 }
1159 cw1200_parse_sdd_file(priv);
1160 }
1161
1162 cfg.dpdData = priv->sdd->data;
1163 cfg.dpdData_size = priv->sdd->size;
1164 ret = wsm_configuration(priv, &cfg);
1165 if (ret)
1166 return ret;
1167
1168 /* Configure RSSI/SCPI reporting as RSSI. */
1169 wsm_set_rcpi_rssi_threshold(priv, &threshold);
1170
1171 return 0;
1172}
1173
1174static void cw1200_join_complete(struct cw1200_common *priv)
1175{
1176 pr_debug("[STA] Join complete (%d)\n", priv->join_complete_status);
1177
1178 priv->join_pending = false;
1179 if (priv->join_complete_status) {
1180 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1181 cw1200_update_listening(priv, priv->listening);
1182 cw1200_do_unjoin(priv);
1183 ieee80211_connection_loss(priv->vif);
1184 } else {
1185 if (priv->mode == NL80211_IFTYPE_ADHOC)
1186 priv->join_status = CW1200_JOIN_STATUS_IBSS;
1187 else
1188 priv->join_status = CW1200_JOIN_STATUS_PRE_STA;
1189 }
1190 wsm_unlock_tx(priv); /* Clearing the lock held before do_join() */
1191}
1192
1193void cw1200_join_complete_work(struct work_struct *work)
1194{
1195 struct cw1200_common *priv =
1196 container_of(work, struct cw1200_common, join_complete_work);
1197 mutex_lock(&priv->conf_mutex);
1198 cw1200_join_complete(priv);
1199 mutex_unlock(&priv->conf_mutex);
1200}
1201
1202void cw1200_join_complete_cb(struct cw1200_common *priv,
1203 struct wsm_join_complete *arg)
1204{
1205 pr_debug("[STA] cw1200_join_complete_cb called, status=%d.\n",
1206 arg->status);
1207
1208 if (cancel_delayed_work(&priv->join_timeout)) {
1209 priv->join_complete_status = arg->status;
1210 queue_work(priv->workqueue, &priv->join_complete_work);
1211 }
1212}
1213
1214/* MUST be called with tx_lock held! It will be unlocked for us. */
1215static void cw1200_do_join(struct cw1200_common *priv)
1216{
1217 const u8 *bssid;
1218 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
1219 struct cfg80211_bss *bss = NULL;
1220 struct wsm_protected_mgmt_policy mgmt_policy;
1221 struct wsm_join join = {
1222 .mode = conf->ibss_joined ?
1223 WSM_JOIN_MODE_IBSS : WSM_JOIN_MODE_BSS,
1224 .preamble_type = WSM_JOIN_PREAMBLE_LONG,
1225 .probe_for_join = 1,
1226 .atim_window = 0,
1227 .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
1228 conf->basic_rates),
1229 };
1230 if (delayed_work_pending(&priv->join_timeout)) {
1231 pr_warn("[STA] - Join request already pending, skipping..\n");
1232 wsm_unlock_tx(priv);
1233 return;
1234 }
1235
1236 if (priv->join_status)
1237 cw1200_do_unjoin(priv);
1238
1239 bssid = priv->vif->bss_conf.bssid;
1240
1241 bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel,
1242 bssid, NULL, 0, 0, 0);
1243
1244 if (!bss && !conf->ibss_joined) {
1245 wsm_unlock_tx(priv);
1246 return;
1247 }
1248
1249 mutex_lock(&priv->conf_mutex);
1250
1251 /* Under the conf lock: check scan status and
1252 * bail out if it is in progress.
1253 */
1254 if (atomic_read(&priv->scan.in_progress)) {
1255 wsm_unlock_tx(priv);
1256 goto done_put;
1257 }
1258
1259 priv->join_pending = true;
1260
1261 /* Sanity check basic rates */
1262 if (!join.basic_rate_set)
1263 join.basic_rate_set = 7;
1264
1265 /* Sanity check beacon interval */
1266 if (!priv->beacon_int)
1267 priv->beacon_int = 1;
1268
1269 join.beacon_interval = priv->beacon_int;
1270
1271 /* BT Coex related changes */
1272 if (priv->bt_present) {
1273 if (((priv->conf_listen_interval * 100) %
1274 priv->beacon_int) == 0)
1275 priv->listen_interval =
1276 ((priv->conf_listen_interval * 100) /
1277 priv->beacon_int);
1278 else
1279 priv->listen_interval =
1280 ((priv->conf_listen_interval * 100) /
1281 priv->beacon_int + 1);
1282 }
1283
1284 if (priv->hw->conf.ps_dtim_period)
1285 priv->join_dtim_period = priv->hw->conf.ps_dtim_period;
1286 join.dtim_period = priv->join_dtim_period;
1287
1288 join.channel_number = priv->channel->hw_value;
1289 join.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
1290 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1291
1292 memcpy(join.bssid, bssid, sizeof(join.bssid));
1293
1294 pr_debug("[STA] Join BSSID: %pM DTIM: %d, interval: %d\n",
1295 join.bssid,
1296 join.dtim_period, priv->beacon_int);
1297
1298 if (!conf->ibss_joined) {
1299 const u8 *ssidie;
1300 rcu_read_lock();
1301 ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1302 if (ssidie) {
1303 join.ssid_len = ssidie[1];
1304 memcpy(join.ssid, &ssidie[2], join.ssid_len);
1305 }
1306 rcu_read_unlock();
1307 }
1308
1309 if (priv->vif->p2p) {
1310 join.flags |= WSM_JOIN_FLAGS_P2P_GO;
1311 join.basic_rate_set =
1312 cw1200_rate_mask_to_wsm(priv, 0xFF0);
1313 }
1314
1315 /* Enable asynchronous join calls */
1316 if (!conf->ibss_joined) {
1317 join.flags |= WSM_JOIN_FLAGS_FORCE;
1318 join.flags |= WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND;
1319 }
1320
1321 wsm_flush_tx(priv);
1322
1323 /* Stay Awake for Join and Auth Timeouts and a bit more */
1324 cw1200_pm_stay_awake(&priv->pm_state,
1325 CW1200_JOIN_TIMEOUT + CW1200_AUTH_TIMEOUT);
1326
1327 cw1200_update_listening(priv, false);
1328
1329 /* Turn on Block ACKs */
1330 wsm_set_block_ack_policy(priv, priv->ba_tx_tid_mask,
1331 priv->ba_rx_tid_mask);
1332
1333 /* Set up timeout */
1334 if (join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND) {
1335 priv->join_status = CW1200_JOIN_STATUS_JOINING;
1336 queue_delayed_work(priv->workqueue,
1337 &priv->join_timeout,
1338 CW1200_JOIN_TIMEOUT);
1339 }
1340
1341 /* 802.11w protected mgmt frames */
1342 mgmt_policy.protectedMgmtEnable = 0;
1343 mgmt_policy.unprotectedMgmtFramesAllowed = 1;
1344 mgmt_policy.encryptionForAuthFrame = 1;
1345 wsm_set_protected_mgmt_policy(priv, &mgmt_policy);
1346
1347 /* Perform actual join */
1348 if (wsm_join(priv, &join)) {
1349 pr_err("[STA] cw1200_join_work: wsm_join failed!\n");
1350 cancel_delayed_work_sync(&priv->join_timeout);
1351 cw1200_update_listening(priv, priv->listening);
1352 /* Tx lock still held, unjoin will clear it. */
1353 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1354 wsm_unlock_tx(priv);
1355 } else {
1356 if (!(join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND))
1357 cw1200_join_complete(priv); /* Will clear tx_lock */
1358
1359 /* Upload keys */
1360 cw1200_upload_keys(priv);
1361
1362 /* Due to beacon filtering it is possible that the
1363 * AP's beacon is not known for the mac80211 stack.
1364 * Disable filtering temporary to make sure the stack
1365 * receives at least one
1366 */
1367 priv->disable_beacon_filter = true;
1368 }
1369 cw1200_update_filtering(priv);
1370
1371done_put:
1372 mutex_unlock(&priv->conf_mutex);
1373 if (bss)
1374 cfg80211_put_bss(priv->hw->wiphy, bss);
1375}
1376
1377void cw1200_join_timeout(struct work_struct *work)
1378{
1379 struct cw1200_common *priv =
1380 container_of(work, struct cw1200_common, join_timeout.work);
1381 pr_debug("[WSM] Join timed out.\n");
1382 wsm_lock_tx(priv);
1383 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1384 wsm_unlock_tx(priv);
1385}
1386
1387static void cw1200_do_unjoin(struct cw1200_common *priv)
1388{
1389 struct wsm_reset reset = {
1390 .reset_statistics = true,
1391 };
1392
1393 cancel_delayed_work_sync(&priv->join_timeout);
1394
1395 mutex_lock(&priv->conf_mutex);
1396 priv->join_pending = false;
1397
1398 if (atomic_read(&priv->scan.in_progress)) {
1399 if (priv->delayed_unjoin)
1400 wiphy_dbg(priv->hw->wiphy, "Delayed unjoin is already scheduled.\n");
1401 else
1402 priv->delayed_unjoin = true;
1403 goto done;
1404 }
1405
1406 priv->delayed_link_loss = false;
1407
1408 if (!priv->join_status)
1409 goto done;
1410
1411 if (priv->join_status > CW1200_JOIN_STATUS_IBSS) {
1412 wiphy_err(priv->hw->wiphy, "Unexpected: join status: %d\n",
1413 priv->join_status);
1414 BUG_ON(1);
1415 }
1416
1417 cancel_work_sync(&priv->update_filtering_work);
1418 cancel_work_sync(&priv->set_beacon_wakeup_period_work);
1419 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1420
1421 /* Unjoin is a reset. */
1422 wsm_flush_tx(priv);
1423 wsm_keep_alive_period(priv, 0);
1424 wsm_reset(priv, &reset);
1425 wsm_set_output_power(priv, priv->output_power * 10);
1426 priv->join_dtim_period = 0;
1427 cw1200_setup_mac(priv);
1428 cw1200_free_event_queue(priv);
1429 cancel_work_sync(&priv->event_handler);
1430 cw1200_update_listening(priv, priv->listening);
1431 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1432
1433 /* Disable Block ACKs */
1434 wsm_set_block_ack_policy(priv, 0, 0);
1435
1436 priv->disable_beacon_filter = false;
1437 cw1200_update_filtering(priv);
1438 memset(&priv->association_mode, 0,
1439 sizeof(priv->association_mode));
1440 memset(&priv->bss_params, 0, sizeof(priv->bss_params));
1441 priv->setbssparams_done = false;
1442 memset(&priv->firmware_ps_mode, 0,
1443 sizeof(priv->firmware_ps_mode));
1444
1445 pr_debug("[STA] Unjoin completed.\n");
1446
1447done:
1448 mutex_unlock(&priv->conf_mutex);
1449}
1450
1451void cw1200_unjoin_work(struct work_struct *work)
1452{
1453 struct cw1200_common *priv =
1454 container_of(work, struct cw1200_common, unjoin_work);
1455
1456 cw1200_do_unjoin(priv);
1457
1458 /* Tell the stack we're dead */
1459 ieee80211_connection_loss(priv->vif);
1460
1461 wsm_unlock_tx(priv);
1462}
1463
1464int cw1200_enable_listening(struct cw1200_common *priv)
1465{
1466 struct wsm_start start = {
1467 .mode = WSM_START_MODE_P2P_DEV,
1468 .band = WSM_PHY_BAND_2_4G,
1469 .beacon_interval = 100,
1470 .dtim_period = 1,
1471 .probe_delay = 0,
1472 .basic_rate_set = 0x0F,
1473 };
1474
1475 if (priv->channel) {
1476 start.band = priv->channel->band == IEEE80211_BAND_5GHZ ?
1477 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1478 start.channel_number = priv->channel->hw_value;
1479 } else {
1480 start.band = WSM_PHY_BAND_2_4G;
1481 start.channel_number = 1;
1482 }
1483
1484 return wsm_start(priv, &start);
1485}
1486
1487int cw1200_disable_listening(struct cw1200_common *priv)
1488{
1489 int ret;
1490 struct wsm_reset reset = {
1491 .reset_statistics = true,
1492 };
1493 ret = wsm_reset(priv, &reset);
1494 return ret;
1495}
1496
1497void cw1200_update_listening(struct cw1200_common *priv, bool enabled)
1498{
1499 if (enabled) {
1500 if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE) {
1501 if (!cw1200_enable_listening(priv))
1502 priv->join_status = CW1200_JOIN_STATUS_MONITOR;
1503 wsm_set_probe_responder(priv, true);
1504 }
1505 } else {
1506 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
1507 if (!cw1200_disable_listening(priv))
1508 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1509 wsm_set_probe_responder(priv, false);
1510 }
1511 }
1512}
1513
1514int cw1200_set_uapsd_param(struct cw1200_common *priv,
1515 const struct wsm_edca_params *arg)
1516{
1517 int ret;
1518 u16 uapsd_flags = 0;
1519
1520 /* Here's the mapping AC [queue, bit]
1521 * VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0]
1522 */
1523
1524 if (arg->uapsd_enable[0])
1525 uapsd_flags |= 1 << 3;
1526
1527 if (arg->uapsd_enable[1])
1528 uapsd_flags |= 1 << 2;
1529
1530 if (arg->uapsd_enable[2])
1531 uapsd_flags |= 1 << 1;
1532
1533 if (arg->uapsd_enable[3])
1534 uapsd_flags |= 1;
1535
1536 /* Currently pseudo U-APSD operation is not supported, so setting
1537 * MinAutoTriggerInterval, MaxAutoTriggerInterval and
1538 * AutoTriggerStep to 0
1539 */
1540
1541 priv->uapsd_info.uapsd_flags = cpu_to_le16(uapsd_flags);
1542 priv->uapsd_info.min_auto_trigger_interval = 0;
1543 priv->uapsd_info.max_auto_trigger_interval = 0;
1544 priv->uapsd_info.auto_trigger_step = 0;
1545
1546 ret = wsm_set_uapsd_info(priv, &priv->uapsd_info);
1547 return ret;
1548}
1549
1550/* ******************************************************************** */
1551/* AP API */
1552
1553int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1554 struct ieee80211_sta *sta)
1555{
1556 struct cw1200_common *priv = hw->priv;
1557 struct cw1200_sta_priv *sta_priv =
1558 (struct cw1200_sta_priv *)&sta->drv_priv;
1559 struct cw1200_link_entry *entry;
1560 struct sk_buff *skb;
1561
1562 if (priv->mode != NL80211_IFTYPE_AP)
1563 return 0;
1564
1565 sta_priv->link_id = cw1200_find_link_id(priv, sta->addr);
1566 if (WARN_ON(!sta_priv->link_id)) {
1567 wiphy_info(priv->hw->wiphy,
1568 "[AP] No more link IDs available.\n");
1569 return -ENOENT;
1570 }
1571
1572 entry = &priv->link_id_db[sta_priv->link_id - 1];
1573 spin_lock_bh(&priv->ps_state_lock);
1574 if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
1575 IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
1576 priv->sta_asleep_mask |= BIT(sta_priv->link_id);
1577 entry->status = CW1200_LINK_HARD;
1578 while ((skb = skb_dequeue(&entry->rx_queue)))
1579 ieee80211_rx_irqsafe(priv->hw, skb);
1580 spin_unlock_bh(&priv->ps_state_lock);
1581 return 0;
1582}
1583
1584int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1585 struct ieee80211_sta *sta)
1586{
1587 struct cw1200_common *priv = hw->priv;
1588 struct cw1200_sta_priv *sta_priv =
1589 (struct cw1200_sta_priv *)&sta->drv_priv;
1590 struct cw1200_link_entry *entry;
1591
1592 if (priv->mode != NL80211_IFTYPE_AP || !sta_priv->link_id)
1593 return 0;
1594
1595 entry = &priv->link_id_db[sta_priv->link_id - 1];
1596 spin_lock_bh(&priv->ps_state_lock);
1597 entry->status = CW1200_LINK_RESERVE;
1598 entry->timestamp = jiffies;
1599 wsm_lock_tx_async(priv);
1600 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1601 wsm_unlock_tx(priv);
1602 spin_unlock_bh(&priv->ps_state_lock);
1603 flush_workqueue(priv->workqueue);
1604 return 0;
1605}
1606
1607static void __cw1200_sta_notify(struct ieee80211_hw *dev,
1608 struct ieee80211_vif *vif,
1609 enum sta_notify_cmd notify_cmd,
1610 int link_id)
1611{
1612 struct cw1200_common *priv = dev->priv;
1613 u32 bit, prev;
1614
1615 /* Zero link id means "for all link IDs" */
1616 if (link_id)
1617 bit = BIT(link_id);
1618 else if (WARN_ON_ONCE(notify_cmd != STA_NOTIFY_AWAKE))
1619 bit = 0;
1620 else
1621 bit = priv->link_id_map;
1622 prev = priv->sta_asleep_mask & bit;
1623
1624 switch (notify_cmd) {
1625 case STA_NOTIFY_SLEEP:
1626 if (!prev) {
1627 if (priv->buffered_multicasts &&
1628 !priv->sta_asleep_mask)
1629 queue_work(priv->workqueue,
1630 &priv->multicast_start_work);
1631 priv->sta_asleep_mask |= bit;
1632 }
1633 break;
1634 case STA_NOTIFY_AWAKE:
1635 if (prev) {
1636 priv->sta_asleep_mask &= ~bit;
1637 priv->pspoll_mask &= ~bit;
1638 if (priv->tx_multicast && link_id &&
1639 !priv->sta_asleep_mask)
1640 queue_work(priv->workqueue,
1641 &priv->multicast_stop_work);
1642 cw1200_bh_wakeup(priv);
1643 }
1644 break;
1645 }
1646}
1647
1648void cw1200_sta_notify(struct ieee80211_hw *dev,
1649 struct ieee80211_vif *vif,
1650 enum sta_notify_cmd notify_cmd,
1651 struct ieee80211_sta *sta)
1652{
1653 struct cw1200_common *priv = dev->priv;
1654 struct cw1200_sta_priv *sta_priv =
1655 (struct cw1200_sta_priv *)&sta->drv_priv;
1656
1657 spin_lock_bh(&priv->ps_state_lock);
1658 __cw1200_sta_notify(dev, vif, notify_cmd, sta_priv->link_id);
1659 spin_unlock_bh(&priv->ps_state_lock);
1660}
1661
1662static void cw1200_ps_notify(struct cw1200_common *priv,
1663 int link_id, bool ps)
1664{
1665 if (link_id > CW1200_MAX_STA_IN_AP_MODE)
1666 return;
1667
1668 pr_debug("%s for LinkId: %d. STAs asleep: %.8X\n",
1669 ps ? "Stop" : "Start",
1670 link_id, priv->sta_asleep_mask);
1671
1672 __cw1200_sta_notify(priv->hw, priv->vif,
1673 ps ? STA_NOTIFY_SLEEP : STA_NOTIFY_AWAKE, link_id);
1674}
1675
1676static int cw1200_set_tim_impl(struct cw1200_common *priv, bool aid0_bit_set)
1677{
1678 struct sk_buff *skb;
1679 struct wsm_update_ie update_ie = {
1680 .what = WSM_UPDATE_IE_BEACON,
1681 .count = 1,
1682 };
1683 u16 tim_offset, tim_length;
1684
1685 pr_debug("[AP] mcast: %s.\n", aid0_bit_set ? "ena" : "dis");
1686
1687 skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
1688 &tim_offset, &tim_length);
1689 if (!skb) {
1690 if (!__cw1200_flush(priv, true))
1691 wsm_unlock_tx(priv);
1692 return -ENOENT;
1693 }
1694
1695 if (tim_offset && tim_length >= 6) {
1696 /* Ignore DTIM count from mac80211:
1697 * firmware handles DTIM internally.
1698 */
1699 skb->data[tim_offset + 2] = 0;
1700
1701 /* Set/reset aid0 bit */
1702 if (aid0_bit_set)
1703 skb->data[tim_offset + 4] |= 1;
1704 else
1705 skb->data[tim_offset + 4] &= ~1;
1706 }
1707
1708 update_ie.ies = &skb->data[tim_offset];
1709 update_ie.length = tim_length;
1710 wsm_update_ie(priv, &update_ie);
1711
1712 dev_kfree_skb(skb);
1713
1714 return 0;
1715}
1716
1717void cw1200_set_tim_work(struct work_struct *work)
1718{
1719 struct cw1200_common *priv =
1720 container_of(work, struct cw1200_common, set_tim_work);
1721 (void)cw1200_set_tim_impl(priv, priv->aid0_bit_set);
1722}
1723
1724int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
1725 bool set)
1726{
1727 struct cw1200_common *priv = dev->priv;
1728 queue_work(priv->workqueue, &priv->set_tim_work);
1729 return 0;
1730}
1731
1732void cw1200_set_cts_work(struct work_struct *work)
1733{
1734 struct cw1200_common *priv =
1735 container_of(work, struct cw1200_common, set_cts_work);
1736
1737 u8 erp_ie[3] = {WLAN_EID_ERP_INFO, 0x1, 0};
1738 struct wsm_update_ie update_ie = {
1739 .what = WSM_UPDATE_IE_BEACON,
1740 .count = 1,
1741 .ies = erp_ie,
1742 .length = 3,
1743 };
1744 u32 erp_info;
1745 __le32 use_cts_prot;
1746 mutex_lock(&priv->conf_mutex);
1747 erp_info = priv->erp_info;
1748 mutex_unlock(&priv->conf_mutex);
1749 use_cts_prot =
1750 erp_info & WLAN_ERP_USE_PROTECTION ?
1751 __cpu_to_le32(1) : 0;
1752
1753 erp_ie[ERP_INFO_BYTE_OFFSET] = erp_info;
1754
1755 pr_debug("[STA] ERP information 0x%x\n", erp_info);
1756
1757 wsm_write_mib(priv, WSM_MIB_ID_NON_ERP_PROTECTION,
1758 &use_cts_prot, sizeof(use_cts_prot));
1759 wsm_update_ie(priv, &update_ie);
1760
1761 return;
1762}
1763
1764static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
1765{
1766 struct wsm_override_internal_txrate arg;
1767 int ret = 0;
1768
1769 if (priv->mode == NL80211_IFTYPE_STATION) {
1770 /* Plumb PSPOLL and NULL template */
1771 cw1200_upload_pspoll(priv);
1772 cw1200_upload_null(priv);
1773 cw1200_upload_qosnull(priv);
1774 } else {
1775 return 0;
1776 }
1777
1778 memset(&arg, 0, sizeof(struct wsm_override_internal_txrate));
1779
1780 if (!priv->vif->p2p) {
1781 /* STATION mode */
1782 if (priv->bss_params.operational_rate_set & ~0xF) {
1783 pr_debug("[STA] STA has ERP rates\n");
1784 /* G or BG mode */
1785 arg.internalTxRate = (__ffs(
1786 priv->bss_params.operational_rate_set & ~0xF));
1787 } else {
1788 pr_debug("[STA] STA has non ERP rates\n");
1789 /* B only mode */
1790 arg.internalTxRate = (__ffs(priv->association_mode.basic_rate_set));
1791 }
1792 arg.nonErpInternalTxRate = (__ffs(priv->association_mode.basic_rate_set));
1793 } else {
1794 /* P2P mode */
1795 arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1796 arg.nonErpInternalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1797 }
1798
1799 pr_debug("[STA] BTCOEX_INFO MODE %d, internalTxRate : %x, nonErpInternalTxRate: %x\n",
1800 priv->mode,
1801 arg.internalTxRate,
1802 arg.nonErpInternalTxRate);
1803
1804 ret = wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
1805 &arg, sizeof(arg));
1806
1807 return ret;
1808}
1809
1810void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1811 struct ieee80211_vif *vif,
1812 struct ieee80211_bss_conf *info,
1813 u32 changed)
1814{
1815 struct cw1200_common *priv = dev->priv;
1816 bool do_join = false;
1817
1818 mutex_lock(&priv->conf_mutex);
1819
1820 pr_debug("BSS CHANGED: %08x\n", changed);
1821
1822 /* TODO: BSS_CHANGED_QOS */
1823 /* TODO: BSS_CHANGED_TXPOWER */
1824
1825 if (changed & BSS_CHANGED_ARP_FILTER) {
1826 struct wsm_mib_arp_ipv4_filter filter = {0};
1827 int i;
1828
1829 pr_debug("[STA] BSS_CHANGED_ARP_FILTER cnt: %d\n",
1830 info->arp_addr_cnt);
1831
1832 /* Currently only one IP address is supported by firmware.
1833 * In case of more IPs arp filtering will be disabled.
1834 */
1835 if (info->arp_addr_cnt > 0 &&
1836 info->arp_addr_cnt <= WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES) {
1837 for (i = 0; i < info->arp_addr_cnt; i++) {
1838 filter.ipv4addrs[i] = info->arp_addr_list[i];
1839 pr_debug("[STA] addr[%d]: 0x%X\n",
1840 i, filter.ipv4addrs[i]);
1841 }
1842 filter.enable = __cpu_to_le32(1);
1843 }
1844
1845 pr_debug("[STA] arp ip filter enable: %d\n",
1846 __le32_to_cpu(filter.enable));
1847
1848 wsm_set_arp_ipv4_filter(priv, &filter);
1849 }
1850
1851 if (changed &
1852 (BSS_CHANGED_BEACON |
1853 BSS_CHANGED_AP_PROBE_RESP |
1854 BSS_CHANGED_BSSID |
1855 BSS_CHANGED_SSID |
1856 BSS_CHANGED_IBSS)) {
1857 pr_debug("BSS_CHANGED_BEACON\n");
1858 priv->beacon_int = info->beacon_int;
1859 cw1200_update_beaconing(priv);
1860 cw1200_upload_beacon(priv);
1861 }
1862
1863 if (changed & BSS_CHANGED_BEACON_ENABLED) {
1864 pr_debug("BSS_CHANGED_BEACON_ENABLED (%d)\n", info->enable_beacon);
1865
1866 if (priv->enable_beacon != info->enable_beacon) {
1867 cw1200_enable_beaconing(priv, info->enable_beacon);
1868 priv->enable_beacon = info->enable_beacon;
1869 }
1870 }
1871
1872 if (changed & BSS_CHANGED_BEACON_INT) {
1873 pr_debug("CHANGED_BEACON_INT\n");
1874 if (info->ibss_joined)
1875 do_join = true;
1876 else if (priv->join_status == CW1200_JOIN_STATUS_AP)
1877 cw1200_update_beaconing(priv);
1878 }
1879
1880 /* assoc/disassoc, or maybe AID changed */
1881 if (changed & BSS_CHANGED_ASSOC) {
1882 wsm_lock_tx(priv);
1883 priv->wep_default_key_id = -1;
1884 wsm_unlock_tx(priv);
1885 }
1886
1887 if (changed & BSS_CHANGED_BSSID) {
1888 pr_debug("BSS_CHANGED_BSSID\n");
1889 do_join = true;
1890 }
1891
1892 if (changed &
1893 (BSS_CHANGED_ASSOC |
1894 BSS_CHANGED_BSSID |
1895 BSS_CHANGED_IBSS |
1896 BSS_CHANGED_BASIC_RATES |
1897 BSS_CHANGED_HT)) {
1898 pr_debug("BSS_CHANGED_ASSOC\n");
1899 if (info->assoc) {
1900 if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA) {
1901 ieee80211_connection_loss(vif);
1902 mutex_unlock(&priv->conf_mutex);
1903 return;
1904 } else if (priv->join_status == CW1200_JOIN_STATUS_PRE_STA) {
1905 priv->join_status = CW1200_JOIN_STATUS_STA;
1906 }
1907 } else {
1908 do_join = true;
1909 }
1910
1911 if (info->assoc || info->ibss_joined) {
1912 struct ieee80211_sta *sta = NULL;
1913 u32 val = 0;
1914
1915 if (info->dtim_period)
1916 priv->join_dtim_period = info->dtim_period;
1917 priv->beacon_int = info->beacon_int;
1918
1919 rcu_read_lock();
1920
1921 if (info->bssid && !info->ibss_joined)
1922 sta = ieee80211_find_sta(vif, info->bssid);
1923 if (sta) {
1924 priv->ht_info.ht_cap = sta->ht_cap;
1925 priv->bss_params.operational_rate_set =
1926 cw1200_rate_mask_to_wsm(priv,
1927 sta->supp_rates[priv->channel->band]);
1928 priv->ht_info.channel_type = cfg80211_get_chandef_type(&dev->conf.chandef);
1929 priv->ht_info.operation_mode = info->ht_operation_mode;
1930 } else {
1931 memset(&priv->ht_info, 0,
1932 sizeof(priv->ht_info));
1933 priv->bss_params.operational_rate_set = -1;
1934 }
1935 rcu_read_unlock();
1936
1937 /* Non Greenfield stations present */
1938 if (priv->ht_info.operation_mode &
1939 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
1940 val |= WSM_NON_GREENFIELD_STA_PRESENT;
1941
1942 /* Set HT protection method */
1943 val |= (priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2;
1944
1945 /* TODO:
1946 * STBC_param.dual_cts
1947 * STBC_param.LSIG_TXOP_FILL
1948 */
1949
1950 val = cpu_to_le32(val);
1951 wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION,
1952 &val, sizeof(val));
1953
1954 priv->association_mode.greenfield =
1955 cw1200_ht_greenfield(&priv->ht_info);
1956 priv->association_mode.flags =
1957 WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES |
1958 WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE |
1959 WSM_ASSOCIATION_MODE_USE_HT_MODE |
1960 WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET |
1961 WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING;
1962 priv->association_mode.preamble =
1963 info->use_short_preamble ?
1964 WSM_JOIN_PREAMBLE_SHORT :
1965 WSM_JOIN_PREAMBLE_LONG;
1966 priv->association_mode.basic_rate_set = __cpu_to_le32(
1967 cw1200_rate_mask_to_wsm(priv,
1968 info->basic_rates));
1969 priv->association_mode.mpdu_start_spacing =
1970 cw1200_ht_ampdu_density(&priv->ht_info);
1971
1972 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1973 cancel_work_sync(&priv->unjoin_work);
1974
1975 priv->bss_params.beacon_lost_count = priv->cqm_beacon_loss_count;
1976 priv->bss_params.aid = info->aid;
1977
1978 if (priv->join_dtim_period < 1)
1979 priv->join_dtim_period = 1;
1980
1981 pr_debug("[STA] DTIM %d, interval: %d\n",
1982 priv->join_dtim_period, priv->beacon_int);
1983 pr_debug("[STA] Preamble: %d, Greenfield: %d, Aid: %d, Rates: 0x%.8X, Basic: 0x%.8X\n",
1984 priv->association_mode.preamble,
1985 priv->association_mode.greenfield,
1986 priv->bss_params.aid,
1987 priv->bss_params.operational_rate_set,
1988 priv->association_mode.basic_rate_set);
1989 wsm_set_association_mode(priv, &priv->association_mode);
1990
1991 if (!info->ibss_joined) {
1992 wsm_keep_alive_period(priv, 30 /* sec */);
1993 wsm_set_bss_params(priv, &priv->bss_params);
1994 priv->setbssparams_done = true;
1995 cw1200_set_beacon_wakeup_period_work(&priv->set_beacon_wakeup_period_work);
1996 cw1200_set_pm(priv, &priv->powersave_mode);
1997 }
1998 if (priv->vif->p2p) {
1999 pr_debug("[STA] Setting p2p powersave configuration.\n");
2000 wsm_set_p2p_ps_modeinfo(priv,
2001 &priv->p2p_ps_modeinfo);
2002 }
2003 if (priv->bt_present)
2004 cw1200_set_btcoexinfo(priv);
2005 } else {
2006 memset(&priv->association_mode, 0,
2007 sizeof(priv->association_mode));
2008 memset(&priv->bss_params, 0, sizeof(priv->bss_params));
2009 }
2010 }
2011
2012 /* ERP Protection */
2013 if (changed & (BSS_CHANGED_ASSOC |
2014 BSS_CHANGED_ERP_CTS_PROT |
2015 BSS_CHANGED_ERP_PREAMBLE)) {
2016 u32 prev_erp_info = priv->erp_info;
2017 if (info->use_cts_prot)
2018 priv->erp_info |= WLAN_ERP_USE_PROTECTION;
2019 else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
2020 priv->erp_info &= ~WLAN_ERP_USE_PROTECTION;
2021
2022 if (info->use_short_preamble)
2023 priv->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
2024 else
2025 priv->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
2026
2027 pr_debug("[STA] ERP Protection: %x\n", priv->erp_info);
2028
2029 if (prev_erp_info != priv->erp_info)
2030 queue_work(priv->workqueue, &priv->set_cts_work);
2031 }
2032
2033 /* ERP Slottime */
2034 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT)) {
2035 __le32 slot_time = info->use_short_slot ?
2036 __cpu_to_le32(9) : __cpu_to_le32(20);
2037 pr_debug("[STA] Slot time: %d us.\n",
2038 __le32_to_cpu(slot_time));
2039 wsm_write_mib(priv, WSM_MIB_ID_DOT11_SLOT_TIME,
2040 &slot_time, sizeof(slot_time));
2041 }
2042
2043 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) {
2044 struct wsm_rcpi_rssi_threshold threshold = {
2045 .rollingAverageCount = 8,
2046 };
2047 pr_debug("[CQM] RSSI threshold subscribe: %d +- %d\n",
2048 info->cqm_rssi_thold, info->cqm_rssi_hyst);
2049 priv->cqm_rssi_thold = info->cqm_rssi_thold;
2050 priv->cqm_rssi_hyst = info->cqm_rssi_hyst;
2051
2052 if (info->cqm_rssi_thold || info->cqm_rssi_hyst) {
2053 /* RSSI subscription enabled */
2054 /* TODO: It's not a correct way of setting threshold.
2055 * Upper and lower must be set equal here and adjusted
2056 * in callback. However current implementation is much
2057 * more relaible and stable.
2058 */
2059
2060 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
2061 * RSSI = RCPI / 2 - 110
2062 */
2063 if (priv->cqm_use_rssi) {
2064 threshold.upperThreshold =
2065 info->cqm_rssi_thold + info->cqm_rssi_hyst;
2066 threshold.lowerThreshold =
2067 info->cqm_rssi_thold;
2068 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2069 } else {
2070 threshold.upperThreshold = (info->cqm_rssi_thold + info->cqm_rssi_hyst + 110) * 2;
2071 threshold.lowerThreshold = (info->cqm_rssi_thold + 110) * 2;
2072 }
2073 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_THRESHOLD_ENABLE;
2074 } else {
2075 /* There is a bug in FW, see sta.c. We have to enable
2076 * dummy subscription to get correct RSSI values.
2077 */
2078 threshold.rssiRcpiMode |=
2079 WSM_RCPI_RSSI_THRESHOLD_ENABLE |
2080 WSM_RCPI_RSSI_DONT_USE_UPPER |
2081 WSM_RCPI_RSSI_DONT_USE_LOWER;
2082 if (priv->cqm_use_rssi)
2083 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2084 }
2085 wsm_set_rcpi_rssi_threshold(priv, &threshold);
2086 }
2087 mutex_unlock(&priv->conf_mutex);
2088
2089 if (do_join) {
2090 wsm_lock_tx(priv);
2091 cw1200_do_join(priv); /* Will unlock it for us */
2092 }
2093}
2094
2095void cw1200_multicast_start_work(struct work_struct *work)
2096{
2097 struct cw1200_common *priv =
2098 container_of(work, struct cw1200_common, multicast_start_work);
2099 long tmo = priv->join_dtim_period *
2100 (priv->beacon_int + 20) * HZ / 1024;
2101
2102 cancel_work_sync(&priv->multicast_stop_work);
2103
2104 if (!priv->aid0_bit_set) {
2105 wsm_lock_tx(priv);
2106 cw1200_set_tim_impl(priv, true);
2107 priv->aid0_bit_set = true;
2108 mod_timer(&priv->mcast_timeout, jiffies + tmo);
2109 wsm_unlock_tx(priv);
2110 }
2111}
2112
2113void cw1200_multicast_stop_work(struct work_struct *work)
2114{
2115 struct cw1200_common *priv =
2116 container_of(work, struct cw1200_common, multicast_stop_work);
2117
2118 if (priv->aid0_bit_set) {
2119 del_timer_sync(&priv->mcast_timeout);
2120 wsm_lock_tx(priv);
2121 priv->aid0_bit_set = false;
2122 cw1200_set_tim_impl(priv, false);
2123 wsm_unlock_tx(priv);
2124 }
2125}
2126
2127void cw1200_mcast_timeout(unsigned long arg)
2128{
2129 struct cw1200_common *priv =
2130 (struct cw1200_common *)arg;
2131
2132 wiphy_warn(priv->hw->wiphy,
2133 "Multicast delivery timeout.\n");
2134 spin_lock_bh(&priv->ps_state_lock);
2135 priv->tx_multicast = priv->aid0_bit_set &&
2136 priv->buffered_multicasts;
2137 if (priv->tx_multicast)
2138 cw1200_bh_wakeup(priv);
2139 spin_unlock_bh(&priv->ps_state_lock);
2140}
2141
2142int cw1200_ampdu_action(struct ieee80211_hw *hw,
2143 struct ieee80211_vif *vif,
2144 enum ieee80211_ampdu_mlme_action action,
2145 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
2146 u8 buf_size)
2147{
2148 /* Aggregation is implemented fully in firmware,
2149 * including block ack negotiation. Do not allow
2150 * mac80211 stack to do anything: it interferes with
2151 * the firmware.
2152 */
2153
2154 /* Note that we still need this function stubbed. */
2155 return -ENOTSUPP;
2156}
2157
2158/* ******************************************************************** */
2159/* WSM callback */
2160void cw1200_suspend_resume(struct cw1200_common *priv,
2161 struct wsm_suspend_resume *arg)
2162{
2163 pr_debug("[AP] %s: %s\n",
2164 arg->stop ? "stop" : "start",
2165 arg->multicast ? "broadcast" : "unicast");
2166
2167 if (arg->multicast) {
2168 bool cancel_tmo = false;
2169 spin_lock_bh(&priv->ps_state_lock);
2170 if (arg->stop) {
2171 priv->tx_multicast = false;
2172 } else {
2173 /* Firmware sends this indication every DTIM if there
2174 * is a STA in powersave connected. There is no reason
2175 * to suspend, following wakeup will consume much more
2176 * power than it could be saved.
2177 */
2178 cw1200_pm_stay_awake(&priv->pm_state,
2179 priv->join_dtim_period *
2180 (priv->beacon_int + 20) * HZ / 1024);
2181 priv->tx_multicast = (priv->aid0_bit_set &&
2182 priv->buffered_multicasts);
2183 if (priv->tx_multicast) {
2184 cancel_tmo = true;
2185 cw1200_bh_wakeup(priv);
2186 }
2187 }
2188 spin_unlock_bh(&priv->ps_state_lock);
2189 if (cancel_tmo)
2190 del_timer_sync(&priv->mcast_timeout);
2191 } else {
2192 spin_lock_bh(&priv->ps_state_lock);
2193 cw1200_ps_notify(priv, arg->link_id, arg->stop);
2194 spin_unlock_bh(&priv->ps_state_lock);
2195 if (!arg->stop)
2196 cw1200_bh_wakeup(priv);
2197 }
2198 return;
2199}
2200
2201/* ******************************************************************** */
2202/* AP privates */
2203
2204static int cw1200_upload_beacon(struct cw1200_common *priv)
2205{
2206 int ret = 0;
2207 struct ieee80211_mgmt *mgmt;
2208 struct wsm_template_frame frame = {
2209 .frame_type = WSM_FRAME_TYPE_BEACON,
2210 };
2211
2212 u16 tim_offset;
2213 u16 tim_len;
2214
2215 if (priv->mode == NL80211_IFTYPE_STATION ||
2216 priv->mode == NL80211_IFTYPE_MONITOR ||
2217 priv->mode == NL80211_IFTYPE_UNSPECIFIED)
2218 goto done;
2219
2220 if (priv->vif->p2p)
2221 frame.rate = WSM_TRANSMIT_RATE_6;
2222
2223 frame.skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
2224 &tim_offset, &tim_len);
2225 if (!frame.skb)
2226 return -ENOMEM;
2227
2228 ret = wsm_set_template_frame(priv, &frame);
2229
2230 if (ret)
2231 goto done;
2232
2233 /* TODO: Distill probe resp; remove TIM
2234 * and any other beacon-specific IEs
2235 */
2236 mgmt = (void *)frame.skb->data;
2237 mgmt->frame_control =
2238 __cpu_to_le16(IEEE80211_FTYPE_MGMT |
2239 IEEE80211_STYPE_PROBE_RESP);
2240
2241 frame.frame_type = WSM_FRAME_TYPE_PROBE_RESPONSE;
2242 if (priv->vif->p2p) {
2243 ret = wsm_set_probe_responder(priv, true);
2244 } else {
2245 ret = wsm_set_template_frame(priv, &frame);
2246 wsm_set_probe_responder(priv, false);
2247 }
2248
2249done:
2250 dev_kfree_skb(frame.skb);
2251
2252 return ret;
2253}
2254
2255static int cw1200_upload_pspoll(struct cw1200_common *priv)
2256{
2257 int ret = 0;
2258 struct wsm_template_frame frame = {
2259 .frame_type = WSM_FRAME_TYPE_PS_POLL,
2260 .rate = 0xFF,
2261 };
2262
2263
2264 frame.skb = ieee80211_pspoll_get(priv->hw, priv->vif);
2265 if (!frame.skb)
2266 return -ENOMEM;
2267
2268 ret = wsm_set_template_frame(priv, &frame);
2269
2270 dev_kfree_skb(frame.skb);
2271
2272 return ret;
2273}
2274
2275static int cw1200_upload_null(struct cw1200_common *priv)
2276{
2277 int ret = 0;
2278 struct wsm_template_frame frame = {
2279 .frame_type = WSM_FRAME_TYPE_NULL,
2280 .rate = 0xFF,
2281 };
2282
2283 frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
2284 if (!frame.skb)
2285 return -ENOMEM;
2286
2287 ret = wsm_set_template_frame(priv, &frame);
2288
2289 dev_kfree_skb(frame.skb);
2290
2291 return ret;
2292}
2293
2294static int cw1200_upload_qosnull(struct cw1200_common *priv)
2295{
2296 int ret = 0;
2297 /* TODO: This needs to be implemented
2298
2299 struct wsm_template_frame frame = {
2300 .frame_type = WSM_FRAME_TYPE_QOS_NULL,
2301 .rate = 0xFF,
2302 };
2303
2304 frame.skb = ieee80211_qosnullfunc_get(priv->hw, priv->vif);
2305 if (!frame.skb)
2306 return -ENOMEM;
2307
2308 ret = wsm_set_template_frame(priv, &frame);
2309
2310 dev_kfree_skb(frame.skb);
2311
2312 */
2313 return ret;
2314}
2315
2316static int cw1200_enable_beaconing(struct cw1200_common *priv,
2317 bool enable)
2318{
2319 struct wsm_beacon_transmit transmit = {
2320 .enable_beaconing = enable,
2321 };
2322
2323 return wsm_beacon_transmit(priv, &transmit);
2324}
2325
2326static int cw1200_start_ap(struct cw1200_common *priv)
2327{
2328 int ret;
2329 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2330 struct wsm_start start = {
2331 .mode = priv->vif->p2p ?
2332 WSM_START_MODE_P2P_GO : WSM_START_MODE_AP,
2333 .band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
2334 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
2335 .channel_number = priv->channel->hw_value,
2336 .beacon_interval = conf->beacon_int,
2337 .dtim_period = conf->dtim_period,
2338 .preamble = conf->use_short_preamble ?
2339 WSM_JOIN_PREAMBLE_SHORT :
2340 WSM_JOIN_PREAMBLE_LONG,
2341 .probe_delay = 100,
2342 .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
2343 conf->basic_rates),
2344 };
2345 struct wsm_operational_mode mode = {
2346 .power_mode = cw1200_power_mode,
2347 .disable_more_flag_usage = true,
2348 };
2349
2350 memset(start.ssid, 0, sizeof(start.ssid));
2351 if (!conf->hidden_ssid) {
2352 start.ssid_len = conf->ssid_len;
2353 memcpy(start.ssid, conf->ssid, start.ssid_len);
2354 }
2355
2356 priv->beacon_int = conf->beacon_int;
2357 priv->join_dtim_period = conf->dtim_period;
2358
2359 memset(&priv->link_id_db, 0, sizeof(priv->link_id_db));
2360
2361 pr_debug("[AP] ch: %d(%d), bcn: %d(%d), brt: 0x%.8X, ssid: %.*s.\n",
2362 start.channel_number, start.band,
2363 start.beacon_interval, start.dtim_period,
2364 start.basic_rate_set,
2365 start.ssid_len, start.ssid);
2366 ret = wsm_start(priv, &start);
2367 if (!ret)
2368 ret = cw1200_upload_keys(priv);
2369 if (!ret && priv->vif->p2p) {
2370 pr_debug("[AP] Setting p2p powersave configuration.\n");
2371 wsm_set_p2p_ps_modeinfo(priv, &priv->p2p_ps_modeinfo);
2372 }
2373 if (!ret) {
2374 wsm_set_block_ack_policy(priv, 0, 0);
2375 priv->join_status = CW1200_JOIN_STATUS_AP;
2376 cw1200_update_filtering(priv);
2377 }
2378 wsm_set_operational_mode(priv, &mode);
2379 return ret;
2380}
2381
2382static int cw1200_update_beaconing(struct cw1200_common *priv)
2383{
2384 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2385 struct wsm_reset reset = {
2386 .link_id = 0,
2387 .reset_statistics = true,
2388 };
2389
2390 if (priv->mode == NL80211_IFTYPE_AP) {
2391 /* TODO: check if changed channel, band */
2392 if (priv->join_status != CW1200_JOIN_STATUS_AP ||
2393 priv->beacon_int != conf->beacon_int) {
2394 pr_debug("ap restarting\n");
2395 wsm_lock_tx(priv);
2396 if (priv->join_status != CW1200_JOIN_STATUS_PASSIVE)
2397 wsm_reset(priv, &reset);
2398 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
2399 cw1200_start_ap(priv);
2400 wsm_unlock_tx(priv);
2401 } else
2402 pr_debug("ap started join_status: %d\n",
2403 priv->join_status);
2404 }
2405 return 0;
2406}
diff --git a/drivers/net/wireless/cw1200/sta.h b/drivers/net/wireless/cw1200/sta.h
new file mode 100644
index 000000000000..35babb62cc6a
--- /dev/null
+++ b/drivers/net/wireless/cw1200/sta.h
@@ -0,0 +1,123 @@
1/*
2 * Mac80211 STA interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef STA_H_INCLUDED
13#define STA_H_INCLUDED
14
15/* ******************************************************************** */
16/* mac80211 API */
17
18int cw1200_start(struct ieee80211_hw *dev);
19void cw1200_stop(struct ieee80211_hw *dev);
20int cw1200_add_interface(struct ieee80211_hw *dev,
21 struct ieee80211_vif *vif);
22void cw1200_remove_interface(struct ieee80211_hw *dev,
23 struct ieee80211_vif *vif);
24int cw1200_change_interface(struct ieee80211_hw *dev,
25 struct ieee80211_vif *vif,
26 enum nl80211_iftype new_type,
27 bool p2p);
28int cw1200_config(struct ieee80211_hw *dev, u32 changed);
29void cw1200_configure_filter(struct ieee80211_hw *dev,
30 unsigned int changed_flags,
31 unsigned int *total_flags,
32 u64 multicast);
33int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
34 u16 queue, const struct ieee80211_tx_queue_params *params);
35int cw1200_get_stats(struct ieee80211_hw *dev,
36 struct ieee80211_low_level_stats *stats);
37int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
38 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
39 struct ieee80211_key_conf *key);
40
41int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
42
43void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
44
45u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
46 struct netdev_hw_addr_list *mc_list);
47
48int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
49
50/* ******************************************************************** */
51/* WSM callbacks */
52
53void cw1200_join_complete_cb(struct cw1200_common *priv,
54 struct wsm_join_complete *arg);
55
56/* ******************************************************************** */
57/* WSM events */
58
59void cw1200_free_event_queue(struct cw1200_common *priv);
60void cw1200_event_handler(struct work_struct *work);
61void cw1200_bss_loss_work(struct work_struct *work);
62void cw1200_bss_params_work(struct work_struct *work);
63void cw1200_keep_alive_work(struct work_struct *work);
64void cw1200_tx_failure_work(struct work_struct *work);
65
66void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv, int init, int good,
67 int bad);
68static inline void cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
69 int init, int good, int bad)
70{
71 spin_lock(&priv->bss_loss_lock);
72 __cw1200_cqm_bssloss_sm(priv, init, good, bad);
73 spin_unlock(&priv->bss_loss_lock);
74}
75
76/* ******************************************************************** */
77/* Internal API */
78
79int cw1200_setup_mac(struct cw1200_common *priv);
80void cw1200_join_timeout(struct work_struct *work);
81void cw1200_unjoin_work(struct work_struct *work);
82void cw1200_join_complete_work(struct work_struct *work);
83void cw1200_wep_key_work(struct work_struct *work);
84void cw1200_update_listening(struct cw1200_common *priv, bool enabled);
85void cw1200_update_filtering(struct cw1200_common *priv);
86void cw1200_update_filtering_work(struct work_struct *work);
87void cw1200_set_beacon_wakeup_period_work(struct work_struct *work);
88int cw1200_enable_listening(struct cw1200_common *priv);
89int cw1200_disable_listening(struct cw1200_common *priv);
90int cw1200_set_uapsd_param(struct cw1200_common *priv,
91 const struct wsm_edca_params *arg);
92void cw1200_ba_work(struct work_struct *work);
93void cw1200_ba_timer(unsigned long arg);
94
95/* AP stuffs */
96int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
97 bool set);
98int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
99 struct ieee80211_sta *sta);
100int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
101 struct ieee80211_sta *sta);
102void cw1200_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
103 enum sta_notify_cmd notify_cmd,
104 struct ieee80211_sta *sta);
105void cw1200_bss_info_changed(struct ieee80211_hw *dev,
106 struct ieee80211_vif *vif,
107 struct ieee80211_bss_conf *info,
108 u32 changed);
109int cw1200_ampdu_action(struct ieee80211_hw *hw,
110 struct ieee80211_vif *vif,
111 enum ieee80211_ampdu_mlme_action action,
112 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
113 u8 buf_size);
114
115void cw1200_suspend_resume(struct cw1200_common *priv,
116 struct wsm_suspend_resume *arg);
117void cw1200_set_tim_work(struct work_struct *work);
118void cw1200_set_cts_work(struct work_struct *work);
119void cw1200_multicast_start_work(struct work_struct *work);
120void cw1200_multicast_stop_work(struct work_struct *work);
121void cw1200_mcast_timeout(unsigned long arg);
122
123#endif
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
new file mode 100644
index 000000000000..0e40890e1993
--- /dev/null
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -0,0 +1,1474 @@
1/*
2 * Datapath implementation for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <net/mac80211.h>
13#include <linux/etherdevice.h>
14#include <linux/skbuff.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 CW1200_INVALID_RATE_ID (0xFF)
23
24static int cw1200_handle_action_rx(struct cw1200_common *priv,
25 struct sk_buff *skb);
26static const struct ieee80211_rate *
27cw1200_get_tx_rate(const struct cw1200_common *priv,
28 const struct ieee80211_tx_rate *rate);
29
30/* ******************************************************************** */
31/* TX queue lock / unlock */
32
33static inline void cw1200_tx_queues_lock(struct cw1200_common *priv)
34{
35 int i;
36 for (i = 0; i < 4; ++i)
37 cw1200_queue_lock(&priv->tx_queue[i]);
38}
39
40static inline void cw1200_tx_queues_unlock(struct cw1200_common *priv)
41{
42 int i;
43 for (i = 0; i < 4; ++i)
44 cw1200_queue_unlock(&priv->tx_queue[i]);
45}
46
47/* ******************************************************************** */
48/* TX policy cache implementation */
49
50static void tx_policy_dump(struct tx_policy *policy)
51{
52 pr_debug("[TX policy] %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X: %d\n",
53 policy->raw[0] & 0x0F, policy->raw[0] >> 4,
54 policy->raw[1] & 0x0F, policy->raw[1] >> 4,
55 policy->raw[2] & 0x0F, policy->raw[2] >> 4,
56 policy->raw[3] & 0x0F, policy->raw[3] >> 4,
57 policy->raw[4] & 0x0F, policy->raw[4] >> 4,
58 policy->raw[5] & 0x0F, policy->raw[5] >> 4,
59 policy->raw[6] & 0x0F, policy->raw[6] >> 4,
60 policy->raw[7] & 0x0F, policy->raw[7] >> 4,
61 policy->raw[8] & 0x0F, policy->raw[8] >> 4,
62 policy->raw[9] & 0x0F, policy->raw[9] >> 4,
63 policy->raw[10] & 0x0F, policy->raw[10] >> 4,
64 policy->raw[11] & 0x0F, policy->raw[11] >> 4,
65 policy->defined);
66}
67
68static void tx_policy_build(const struct cw1200_common *priv,
69 /* [out] */ struct tx_policy *policy,
70 struct ieee80211_tx_rate *rates, size_t count)
71{
72 int i, j;
73 unsigned limit = priv->short_frame_max_tx_count;
74 unsigned total = 0;
75 BUG_ON(rates[0].idx < 0);
76 memset(policy, 0, sizeof(*policy));
77
78 /* minstrel is buggy a little bit, so distille
79 * incoming rates first. */
80
81 /* Sort rates in descending order. */
82 for (i = 1; i < count; ++i) {
83 if (rates[i].idx < 0) {
84 count = i;
85 break;
86 }
87 if (rates[i].idx > rates[i - 1].idx) {
88 struct ieee80211_tx_rate tmp = rates[i - 1];
89 rates[i - 1] = rates[i];
90 rates[i] = tmp;
91 }
92 }
93
94 /* Eliminate duplicates. */
95 total = rates[0].count;
96 for (i = 0, j = 1; j < count; ++j) {
97 if (rates[j].idx == rates[i].idx) {
98 rates[i].count += rates[j].count;
99 } else if (rates[j].idx > rates[i].idx) {
100 break;
101 } else {
102 ++i;
103 if (i != j)
104 rates[i] = rates[j];
105 }
106 total += rates[j].count;
107 }
108 count = i + 1;
109
110 /* Re-fill policy trying to keep every requested rate and with
111 * respect to the global max tx retransmission count. */
112 if (limit < count)
113 limit = count;
114 if (total > limit) {
115 for (i = 0; i < count; ++i) {
116 int left = count - i - 1;
117 if (rates[i].count > limit - left)
118 rates[i].count = limit - left;
119 limit -= rates[i].count;
120 }
121 }
122
123 /* HACK!!! Device has problems (at least) switching from
124 * 54Mbps CTS to 1Mbps. This switch takes enormous amount
125 * of time (100-200 ms), leading to valuable throughput drop.
126 * As a workaround, additional g-rates are injected to the
127 * policy.
128 */
129 if (count == 2 && !(rates[0].flags & IEEE80211_TX_RC_MCS) &&
130 rates[0].idx > 4 && rates[0].count > 2 &&
131 rates[1].idx < 2) {
132 /* ">> 1" is an equivalent of "/ 2", but faster */
133 int mid_rate = (rates[0].idx + 4) >> 1;
134
135 /* Decrease number of retries for the initial rate */
136 rates[0].count -= 2;
137
138 if (mid_rate != 4) {
139 /* Keep fallback rate at 1Mbps. */
140 rates[3] = rates[1];
141
142 /* Inject 1 transmission on lowest g-rate */
143 rates[2].idx = 4;
144 rates[2].count = 1;
145 rates[2].flags = rates[1].flags;
146
147 /* Inject 1 transmission on mid-rate */
148 rates[1].idx = mid_rate;
149 rates[1].count = 1;
150
151 /* Fallback to 1 Mbps is a really bad thing,
152 * so let's try to increase probability of
153 * successful transmission on the lowest g rate
154 * even more */
155 if (rates[0].count >= 3) {
156 --rates[0].count;
157 ++rates[2].count;
158 }
159
160 /* Adjust amount of rates defined */
161 count += 2;
162 } else {
163 /* Keep fallback rate at 1Mbps. */
164 rates[2] = rates[1];
165
166 /* Inject 2 transmissions on lowest g-rate */
167 rates[1].idx = 4;
168 rates[1].count = 2;
169
170 /* Adjust amount of rates defined */
171 count += 1;
172 }
173 }
174
175 policy->defined = cw1200_get_tx_rate(priv, &rates[0])->hw_value + 1;
176
177 for (i = 0; i < count; ++i) {
178 register unsigned rateid, off, shift, retries;
179
180 rateid = cw1200_get_tx_rate(priv, &rates[i])->hw_value;
181 off = rateid >> 3; /* eq. rateid / 8 */
182 shift = (rateid & 0x07) << 2; /* eq. (rateid % 8) * 4 */
183
184 retries = rates[i].count;
185 if (retries > 0x0F) {
186 rates[i].count = 0x0f;
187 retries = 0x0F;
188 }
189 policy->tbl[off] |= __cpu_to_le32(retries << shift);
190 policy->retry_count += retries;
191 }
192
193 pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
194 count,
195 rates[0].idx, rates[0].count,
196 rates[1].idx, rates[1].count,
197 rates[2].idx, rates[2].count,
198 rates[3].idx, rates[3].count,
199 rates[4].idx, rates[4].count);
200}
201
202static inline bool tx_policy_is_equal(const struct tx_policy *wanted,
203 const struct tx_policy *cached)
204{
205 size_t count = wanted->defined >> 1;
206 if (wanted->defined > cached->defined)
207 return false;
208 if (count) {
209 if (memcmp(wanted->raw, cached->raw, count))
210 return false;
211 }
212 if (wanted->defined & 1) {
213 if ((wanted->raw[count] & 0x0F) != (cached->raw[count] & 0x0F))
214 return false;
215 }
216 return true;
217}
218
219static int tx_policy_find(struct tx_policy_cache *cache,
220 const struct tx_policy *wanted)
221{
222 /* O(n) complexity. Not so good, but there's only 8 entries in
223 * the cache.
224 * Also lru helps to reduce search time. */
225 struct tx_policy_cache_entry *it;
226 /* First search for policy in "used" list */
227 list_for_each_entry(it, &cache->used, link) {
228 if (tx_policy_is_equal(wanted, &it->policy))
229 return it - cache->cache;
230 }
231 /* Then - in "free list" */
232 list_for_each_entry(it, &cache->free, link) {
233 if (tx_policy_is_equal(wanted, &it->policy))
234 return it - cache->cache;
235 }
236 return -1;
237}
238
239static inline void tx_policy_use(struct tx_policy_cache *cache,
240 struct tx_policy_cache_entry *entry)
241{
242 ++entry->policy.usage_count;
243 list_move(&entry->link, &cache->used);
244}
245
246static inline int tx_policy_release(struct tx_policy_cache *cache,
247 struct tx_policy_cache_entry *entry)
248{
249 int ret = --entry->policy.usage_count;
250 if (!ret)
251 list_move(&entry->link, &cache->free);
252 return ret;
253}
254
255void tx_policy_clean(struct cw1200_common *priv)
256{
257 int idx, locked;
258 struct tx_policy_cache *cache = &priv->tx_policy_cache;
259 struct tx_policy_cache_entry *entry;
260
261 cw1200_tx_queues_lock(priv);
262 spin_lock_bh(&cache->lock);
263 locked = list_empty(&cache->free);
264
265 for (idx = 0; idx < TX_POLICY_CACHE_SIZE; idx++) {
266 entry = &cache->cache[idx];
267 /* Policy usage count should be 0 at this time as all queues
268 should be empty */
269 if (WARN_ON(entry->policy.usage_count)) {
270 entry->policy.usage_count = 0;
271 list_move(&entry->link, &cache->free);
272 }
273 memset(&entry->policy, 0, sizeof(entry->policy));
274 }
275 if (locked)
276 cw1200_tx_queues_unlock(priv);
277
278 cw1200_tx_queues_unlock(priv);
279 spin_unlock_bh(&cache->lock);
280}
281
282/* ******************************************************************** */
283/* External TX policy cache API */
284
285void tx_policy_init(struct cw1200_common *priv)
286{
287 struct tx_policy_cache *cache = &priv->tx_policy_cache;
288 int i;
289
290 memset(cache, 0, sizeof(*cache));
291
292 spin_lock_init(&cache->lock);
293 INIT_LIST_HEAD(&cache->used);
294 INIT_LIST_HEAD(&cache->free);
295
296 for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i)
297 list_add(&cache->cache[i].link, &cache->free);
298}
299
300static int tx_policy_get(struct cw1200_common *priv,
301 struct ieee80211_tx_rate *rates,
302 size_t count, bool *renew)
303{
304 int idx;
305 struct tx_policy_cache *cache = &priv->tx_policy_cache;
306 struct tx_policy wanted;
307
308 tx_policy_build(priv, &wanted, rates, count);
309
310 spin_lock_bh(&cache->lock);
311 if (WARN_ON_ONCE(list_empty(&cache->free))) {
312 spin_unlock_bh(&cache->lock);
313 return CW1200_INVALID_RATE_ID;
314 }
315 idx = tx_policy_find(cache, &wanted);
316 if (idx >= 0) {
317 pr_debug("[TX policy] Used TX policy: %d\n", idx);
318 *renew = false;
319 } else {
320 struct tx_policy_cache_entry *entry;
321 *renew = true;
322 /* If policy is not found create a new one
323 * using the oldest entry in "free" list */
324 entry = list_entry(cache->free.prev,
325 struct tx_policy_cache_entry, link);
326 entry->policy = wanted;
327 idx = entry - cache->cache;
328 pr_debug("[TX policy] New TX policy: %d\n", idx);
329 tx_policy_dump(&entry->policy);
330 }
331 tx_policy_use(cache, &cache->cache[idx]);
332 if (list_empty(&cache->free)) {
333 /* Lock TX queues. */
334 cw1200_tx_queues_lock(priv);
335 }
336 spin_unlock_bh(&cache->lock);
337 return idx;
338}
339
340static void tx_policy_put(struct cw1200_common *priv, int idx)
341{
342 int usage, locked;
343 struct tx_policy_cache *cache = &priv->tx_policy_cache;
344
345 spin_lock_bh(&cache->lock);
346 locked = list_empty(&cache->free);
347 usage = tx_policy_release(cache, &cache->cache[idx]);
348 if (locked && !usage) {
349 /* Unlock TX queues. */
350 cw1200_tx_queues_unlock(priv);
351 }
352 spin_unlock_bh(&cache->lock);
353}
354
355static int tx_policy_upload(struct cw1200_common *priv)
356{
357 struct tx_policy_cache *cache = &priv->tx_policy_cache;
358 int i;
359 struct wsm_set_tx_rate_retry_policy arg = {
360 .num = 0,
361 };
362 spin_lock_bh(&cache->lock);
363
364 /* Upload only modified entries. */
365 for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i) {
366 struct tx_policy *src = &cache->cache[i].policy;
367 if (src->retry_count && !src->uploaded) {
368 struct wsm_tx_rate_retry_policy *dst =
369 &arg.tbl[arg.num];
370 dst->index = i;
371 dst->short_retries = priv->short_frame_max_tx_count;
372 dst->long_retries = priv->long_frame_max_tx_count;
373
374 dst->flags = WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED |
375 WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT;
376 memcpy(dst->rate_count_indices, src->tbl,
377 sizeof(dst->rate_count_indices));
378 src->uploaded = 1;
379 ++arg.num;
380 }
381 }
382 spin_unlock_bh(&cache->lock);
383 cw1200_debug_tx_cache_miss(priv);
384 pr_debug("[TX policy] Upload %d policies\n", arg.num);
385 return wsm_set_tx_rate_retry_policy(priv, &arg);
386}
387
388void tx_policy_upload_work(struct work_struct *work)
389{
390 struct cw1200_common *priv =
391 container_of(work, struct cw1200_common, tx_policy_upload_work);
392
393 pr_debug("[TX] TX policy upload.\n");
394 tx_policy_upload(priv);
395
396 wsm_unlock_tx(priv);
397 cw1200_tx_queues_unlock(priv);
398}
399
400/* ******************************************************************** */
401/* cw1200 TX implementation */
402
403struct cw1200_txinfo {
404 struct sk_buff *skb;
405 unsigned queue;
406 struct ieee80211_tx_info *tx_info;
407 const struct ieee80211_rate *rate;
408 struct ieee80211_hdr *hdr;
409 size_t hdrlen;
410 const u8 *da;
411 struct cw1200_sta_priv *sta_priv;
412 struct ieee80211_sta *sta;
413 struct cw1200_txpriv txpriv;
414};
415
416u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv, u32 rates)
417{
418 u32 ret = 0;
419 int i;
420 for (i = 0; i < 32; ++i) {
421 if (rates & BIT(i))
422 ret |= BIT(priv->rates[i].hw_value);
423 }
424 return ret;
425}
426
427static const struct ieee80211_rate *
428cw1200_get_tx_rate(const struct cw1200_common *priv,
429 const struct ieee80211_tx_rate *rate)
430{
431 if (rate->idx < 0)
432 return NULL;
433 if (rate->flags & IEEE80211_TX_RC_MCS)
434 return &priv->mcs_rates[rate->idx];
435 return &priv->hw->wiphy->bands[priv->channel->band]->
436 bitrates[rate->idx];
437}
438
439static int
440cw1200_tx_h_calc_link_ids(struct cw1200_common *priv,
441 struct cw1200_txinfo *t)
442{
443 if (t->sta && t->sta_priv->link_id)
444 t->txpriv.raw_link_id =
445 t->txpriv.link_id =
446 t->sta_priv->link_id;
447 else if (priv->mode != NL80211_IFTYPE_AP)
448 t->txpriv.raw_link_id =
449 t->txpriv.link_id = 0;
450 else if (is_multicast_ether_addr(t->da)) {
451 if (priv->enable_beacon) {
452 t->txpriv.raw_link_id = 0;
453 t->txpriv.link_id = CW1200_LINK_ID_AFTER_DTIM;
454 } else {
455 t->txpriv.raw_link_id = 0;
456 t->txpriv.link_id = 0;
457 }
458 } else {
459 t->txpriv.link_id = cw1200_find_link_id(priv, t->da);
460 if (!t->txpriv.link_id)
461 t->txpriv.link_id = cw1200_alloc_link_id(priv, t->da);
462 if (!t->txpriv.link_id) {
463 wiphy_err(priv->hw->wiphy,
464 "No more link IDs available.\n");
465 return -ENOENT;
466 }
467 t->txpriv.raw_link_id = t->txpriv.link_id;
468 }
469 if (t->txpriv.raw_link_id)
470 priv->link_id_db[t->txpriv.raw_link_id - 1].timestamp =
471 jiffies;
472 if (t->sta && (t->sta->uapsd_queues & BIT(t->queue)))
473 t->txpriv.link_id = CW1200_LINK_ID_UAPSD;
474 return 0;
475}
476
477static void
478cw1200_tx_h_pm(struct cw1200_common *priv,
479 struct cw1200_txinfo *t)
480{
481 if (ieee80211_is_auth(t->hdr->frame_control)) {
482 u32 mask = ~BIT(t->txpriv.raw_link_id);
483 spin_lock_bh(&priv->ps_state_lock);
484 priv->sta_asleep_mask &= mask;
485 priv->pspoll_mask &= mask;
486 spin_unlock_bh(&priv->ps_state_lock);
487 }
488}
489
490static void
491cw1200_tx_h_calc_tid(struct cw1200_common *priv,
492 struct cw1200_txinfo *t)
493{
494 if (ieee80211_is_data_qos(t->hdr->frame_control)) {
495 u8 *qos = ieee80211_get_qos_ctl(t->hdr);
496 t->txpriv.tid = qos[0] & IEEE80211_QOS_CTL_TID_MASK;
497 } else if (ieee80211_is_data(t->hdr->frame_control)) {
498 t->txpriv.tid = 0;
499 }
500}
501
502static int
503cw1200_tx_h_crypt(struct cw1200_common *priv,
504 struct cw1200_txinfo *t)
505{
506 if (!t->tx_info->control.hw_key ||
507 !ieee80211_has_protected(t->hdr->frame_control))
508 return 0;
509
510 t->hdrlen += t->tx_info->control.hw_key->iv_len;
511 skb_put(t->skb, t->tx_info->control.hw_key->icv_len);
512
513 if (t->tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
514 skb_put(t->skb, 8); /* MIC space */
515
516 return 0;
517}
518
519static int
520cw1200_tx_h_align(struct cw1200_common *priv,
521 struct cw1200_txinfo *t,
522 u8 *flags)
523{
524 size_t offset = (size_t)t->skb->data & 3;
525
526 if (!offset)
527 return 0;
528
529 if (offset & 1) {
530 wiphy_err(priv->hw->wiphy,
531 "Bug: attempt to transmit a frame with wrong alignment: %zu\n",
532 offset);
533 return -EINVAL;
534 }
535
536 if (skb_headroom(t->skb) < offset) {
537 wiphy_err(priv->hw->wiphy,
538 "Bug: no space allocated for DMA alignment. headroom: %d\n",
539 skb_headroom(t->skb));
540 return -ENOMEM;
541 }
542 skb_push(t->skb, offset);
543 t->hdrlen += offset;
544 t->txpriv.offset += offset;
545 *flags |= WSM_TX_2BYTES_SHIFT;
546 cw1200_debug_tx_align(priv);
547 return 0;
548}
549
550static int
551cw1200_tx_h_action(struct cw1200_common *priv,
552 struct cw1200_txinfo *t)
553{
554 struct ieee80211_mgmt *mgmt =
555 (struct ieee80211_mgmt *)t->hdr;
556 if (ieee80211_is_action(t->hdr->frame_control) &&
557 mgmt->u.action.category == WLAN_CATEGORY_BACK)
558 return 1;
559 else
560 return 0;
561}
562
563/* Add WSM header */
564static struct wsm_tx *
565cw1200_tx_h_wsm(struct cw1200_common *priv,
566 struct cw1200_txinfo *t)
567{
568 struct wsm_tx *wsm;
569
570 if (skb_headroom(t->skb) < sizeof(struct wsm_tx)) {
571 wiphy_err(priv->hw->wiphy,
572 "Bug: no space allocated for WSM header. headroom: %d\n",
573 skb_headroom(t->skb));
574 return NULL;
575 }
576
577 wsm = (struct wsm_tx *)skb_push(t->skb, sizeof(struct wsm_tx));
578 t->txpriv.offset += sizeof(struct wsm_tx);
579 memset(wsm, 0, sizeof(*wsm));
580 wsm->hdr.len = __cpu_to_le16(t->skb->len);
581 wsm->hdr.id = __cpu_to_le16(0x0004);
582 wsm->queue_id = wsm_queue_id_to_wsm(t->queue);
583 return wsm;
584}
585
586/* BT Coex specific handling */
587static void
588cw1200_tx_h_bt(struct cw1200_common *priv,
589 struct cw1200_txinfo *t,
590 struct wsm_tx *wsm)
591{
592 u8 priority = 0;
593
594 if (!priv->bt_present)
595 return;
596
597 if (ieee80211_is_nullfunc(t->hdr->frame_control)) {
598 priority = WSM_EPTA_PRIORITY_MGT;
599 } else if (ieee80211_is_data(t->hdr->frame_control)) {
600 /* Skip LLC SNAP header (+6) */
601 u8 *payload = &t->skb->data[t->hdrlen];
602 u16 *ethertype = (u16 *)&payload[6];
603 if (*ethertype == __be16_to_cpu(ETH_P_PAE))
604 priority = WSM_EPTA_PRIORITY_EAPOL;
605 } else if (ieee80211_is_assoc_req(t->hdr->frame_control) ||
606 ieee80211_is_reassoc_req(t->hdr->frame_control)) {
607 struct ieee80211_mgmt *mgt_frame =
608 (struct ieee80211_mgmt *)t->hdr;
609
610 if (mgt_frame->u.assoc_req.listen_interval <
611 priv->listen_interval) {
612 pr_debug("Modified Listen Interval to %d from %d\n",
613 priv->listen_interval,
614 mgt_frame->u.assoc_req.listen_interval);
615 /* Replace listen interval derieved from
616 * the one read from SDD */
617 mgt_frame->u.assoc_req.listen_interval =
618 priv->listen_interval;
619 }
620 }
621
622 if (!priority) {
623 if (ieee80211_is_action(t->hdr->frame_control))
624 priority = WSM_EPTA_PRIORITY_ACTION;
625 else if (ieee80211_is_mgmt(t->hdr->frame_control))
626 priority = WSM_EPTA_PRIORITY_MGT;
627 else if ((wsm->queue_id == WSM_QUEUE_VOICE))
628 priority = WSM_EPTA_PRIORITY_VOICE;
629 else if ((wsm->queue_id == WSM_QUEUE_VIDEO))
630 priority = WSM_EPTA_PRIORITY_VIDEO;
631 else
632 priority = WSM_EPTA_PRIORITY_DATA;
633 }
634
635 pr_debug("[TX] EPTA priority %d.\n", priority);
636
637 wsm->flags |= priority << 1;
638}
639
640static int
641cw1200_tx_h_rate_policy(struct cw1200_common *priv,
642 struct cw1200_txinfo *t,
643 struct wsm_tx *wsm)
644{
645 bool tx_policy_renew = false;
646
647 t->txpriv.rate_id = tx_policy_get(priv,
648 t->tx_info->control.rates, IEEE80211_TX_MAX_RATES,
649 &tx_policy_renew);
650 if (t->txpriv.rate_id == CW1200_INVALID_RATE_ID)
651 return -EFAULT;
652
653 wsm->flags |= t->txpriv.rate_id << 4;
654
655 t->rate = cw1200_get_tx_rate(priv,
656 &t->tx_info->control.rates[0]),
657 wsm->max_tx_rate = t->rate->hw_value;
658 if (t->rate->flags & IEEE80211_TX_RC_MCS) {
659 if (cw1200_ht_greenfield(&priv->ht_info))
660 wsm->ht_tx_parameters |=
661 __cpu_to_le32(WSM_HT_TX_GREENFIELD);
662 else
663 wsm->ht_tx_parameters |=
664 __cpu_to_le32(WSM_HT_TX_MIXED);
665 }
666
667 if (tx_policy_renew) {
668 pr_debug("[TX] TX policy renew.\n");
669 /* It's not so optimal to stop TX queues every now and then.
670 * Better to reimplement task scheduling with
671 * a counter. TODO. */
672 wsm_lock_tx_async(priv);
673 cw1200_tx_queues_lock(priv);
674 if (queue_work(priv->workqueue,
675 &priv->tx_policy_upload_work) <= 0) {
676 cw1200_tx_queues_unlock(priv);
677 wsm_unlock_tx(priv);
678 }
679 }
680 return 0;
681}
682
683static bool
684cw1200_tx_h_pm_state(struct cw1200_common *priv,
685 struct cw1200_txinfo *t)
686{
687 int was_buffered = 1;
688
689 if (t->txpriv.link_id == CW1200_LINK_ID_AFTER_DTIM &&
690 !priv->buffered_multicasts) {
691 priv->buffered_multicasts = true;
692 if (priv->sta_asleep_mask)
693 queue_work(priv->workqueue,
694 &priv->multicast_start_work);
695 }
696
697 if (t->txpriv.raw_link_id && t->txpriv.tid < CW1200_MAX_TID)
698 was_buffered = priv->link_id_db[t->txpriv.raw_link_id - 1].buffered[t->txpriv.tid]++;
699
700 return !was_buffered;
701}
702
703/* ******************************************************************** */
704
705void cw1200_tx(struct ieee80211_hw *dev,
706 struct ieee80211_tx_control *control,
707 struct sk_buff *skb)
708{
709 struct cw1200_common *priv = dev->priv;
710 struct cw1200_txinfo t = {
711 .skb = skb,
712 .queue = skb_get_queue_mapping(skb),
713 .tx_info = IEEE80211_SKB_CB(skb),
714 .hdr = (struct ieee80211_hdr *)skb->data,
715 .txpriv.tid = CW1200_MAX_TID,
716 .txpriv.rate_id = CW1200_INVALID_RATE_ID,
717 };
718 struct ieee80211_sta *sta;
719 struct wsm_tx *wsm;
720 bool tid_update = 0;
721 u8 flags = 0;
722 int ret;
723
724 if (priv->bh_error)
725 goto drop;
726
727 t.hdrlen = ieee80211_hdrlen(t.hdr->frame_control);
728 t.da = ieee80211_get_DA(t.hdr);
729 if (control) {
730 t.sta = control->sta;
731 t.sta_priv = (struct cw1200_sta_priv *)&t.sta->drv_priv;
732 }
733
734 if (WARN_ON(t.queue >= 4))
735 goto drop;
736
737 ret = cw1200_tx_h_calc_link_ids(priv, &t);
738 if (ret)
739 goto drop;
740
741 pr_debug("[TX] TX %d bytes (queue: %d, link_id: %d (%d)).\n",
742 skb->len, t.queue, t.txpriv.link_id,
743 t.txpriv.raw_link_id);
744
745 cw1200_tx_h_pm(priv, &t);
746 cw1200_tx_h_calc_tid(priv, &t);
747 ret = cw1200_tx_h_crypt(priv, &t);
748 if (ret)
749 goto drop;
750 ret = cw1200_tx_h_align(priv, &t, &flags);
751 if (ret)
752 goto drop;
753 ret = cw1200_tx_h_action(priv, &t);
754 if (ret)
755 goto drop;
756 wsm = cw1200_tx_h_wsm(priv, &t);
757 if (!wsm) {
758 ret = -ENOMEM;
759 goto drop;
760 }
761 wsm->flags |= flags;
762 cw1200_tx_h_bt(priv, &t, wsm);
763 ret = cw1200_tx_h_rate_policy(priv, &t, wsm);
764 if (ret)
765 goto drop;
766
767 rcu_read_lock();
768 sta = rcu_dereference(t.sta);
769
770 spin_lock_bh(&priv->ps_state_lock);
771 {
772 tid_update = cw1200_tx_h_pm_state(priv, &t);
773 BUG_ON(cw1200_queue_put(&priv->tx_queue[t.queue],
774 t.skb, &t.txpriv));
775 }
776 spin_unlock_bh(&priv->ps_state_lock);
777
778 if (tid_update && sta)
779 ieee80211_sta_set_buffered(sta, t.txpriv.tid, true);
780
781 rcu_read_unlock();
782
783 cw1200_bh_wakeup(priv);
784
785 return;
786
787drop:
788 cw1200_skb_dtor(priv, skb, &t.txpriv);
789 return;
790}
791
792/* ******************************************************************** */
793
794static int cw1200_handle_action_rx(struct cw1200_common *priv,
795 struct sk_buff *skb)
796{
797 struct ieee80211_mgmt *mgmt = (void *)skb->data;
798
799 /* Filter block ACK negotiation: fully controlled by firmware */
800 if (mgmt->u.action.category == WLAN_CATEGORY_BACK)
801 return 1;
802
803 return 0;
804}
805
806static int cw1200_handle_pspoll(struct cw1200_common *priv,
807 struct sk_buff *skb)
808{
809 struct ieee80211_sta *sta;
810 struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)skb->data;
811 int link_id = 0;
812 u32 pspoll_mask = 0;
813 int drop = 1;
814 int i;
815
816 if (priv->join_status != CW1200_JOIN_STATUS_AP)
817 goto done;
818 if (memcmp(priv->vif->addr, pspoll->bssid, ETH_ALEN))
819 goto done;
820
821 rcu_read_lock();
822 sta = ieee80211_find_sta(priv->vif, pspoll->ta);
823 if (sta) {
824 struct cw1200_sta_priv *sta_priv;
825 sta_priv = (struct cw1200_sta_priv *)&sta->drv_priv;
826 link_id = sta_priv->link_id;
827 pspoll_mask = BIT(sta_priv->link_id);
828 }
829 rcu_read_unlock();
830 if (!link_id)
831 goto done;
832
833 priv->pspoll_mask |= pspoll_mask;
834 drop = 0;
835
836 /* Do not report pspols if data for given link id is
837 * queued already. */
838 for (i = 0; i < 4; ++i) {
839 if (cw1200_queue_get_num_queued(&priv->tx_queue[i],
840 pspoll_mask)) {
841 cw1200_bh_wakeup(priv);
842 drop = 1;
843 break;
844 }
845 }
846 pr_debug("[RX] PSPOLL: %s\n", drop ? "local" : "fwd");
847done:
848 return drop;
849}
850
851/* ******************************************************************** */
852
853void cw1200_tx_confirm_cb(struct cw1200_common *priv,
854 int link_id,
855 struct wsm_tx_confirm *arg)
856{
857 u8 queue_id = cw1200_queue_get_queue_id(arg->packet_id);
858 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
859 struct sk_buff *skb;
860 const struct cw1200_txpriv *txpriv;
861
862 pr_debug("[TX] TX confirm: %d, %d.\n",
863 arg->status, arg->ack_failures);
864
865 if (cw1200_itp_tx_running(priv))
866 return;
867
868 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
869 /* STA is stopped. */
870 return;
871 }
872
873 if (WARN_ON(queue_id >= 4))
874 return;
875
876 if (arg->status)
877 pr_debug("TX failed: %d.\n", arg->status);
878
879 if ((arg->status == WSM_REQUEUE) &&
880 (arg->flags & WSM_TX_STATUS_REQUEUE)) {
881 /* "Requeue" means "implicit suspend" */
882 struct wsm_suspend_resume suspend = {
883 .link_id = link_id,
884 .stop = 1,
885 .multicast = !link_id,
886 };
887 cw1200_suspend_resume(priv, &suspend);
888 wiphy_warn(priv->hw->wiphy, "Requeue for link_id %d (try %d). STAs asleep: 0x%.8X\n",
889 link_id,
890 cw1200_queue_get_generation(arg->packet_id) + 1,
891 priv->sta_asleep_mask);
892 cw1200_queue_requeue(queue, arg->packet_id);
893 spin_lock_bh(&priv->ps_state_lock);
894 if (!link_id) {
895 priv->buffered_multicasts = true;
896 if (priv->sta_asleep_mask) {
897 queue_work(priv->workqueue,
898 &priv->multicast_start_work);
899 }
900 }
901 spin_unlock_bh(&priv->ps_state_lock);
902 } else if (!cw1200_queue_get_skb(queue, arg->packet_id,
903 &skb, &txpriv)) {
904 struct ieee80211_tx_info *tx = IEEE80211_SKB_CB(skb);
905 int tx_count = arg->ack_failures;
906 u8 ht_flags = 0;
907 int i;
908
909 if (cw1200_ht_greenfield(&priv->ht_info))
910 ht_flags |= IEEE80211_TX_RC_GREEN_FIELD;
911
912 spin_lock(&priv->bss_loss_lock);
913 if (priv->bss_loss_state &&
914 arg->packet_id == priv->bss_loss_confirm_id) {
915 if (arg->status) {
916 /* Recovery failed */
917 __cw1200_cqm_bssloss_sm(priv, 0, 0, 1);
918 } else {
919 /* Recovery succeeded */
920 __cw1200_cqm_bssloss_sm(priv, 0, 1, 0);
921 }
922 }
923 spin_unlock(&priv->bss_loss_lock);
924
925 if (!arg->status) {
926 tx->flags |= IEEE80211_TX_STAT_ACK;
927 ++tx_count;
928 cw1200_debug_txed(priv);
929 if (arg->flags & WSM_TX_STATUS_AGGREGATION) {
930 /* Do not report aggregation to mac80211:
931 * it confuses minstrel a lot. */
932 /* tx->flags |= IEEE80211_TX_STAT_AMPDU; */
933 cw1200_debug_txed_agg(priv);
934 }
935 } else {
936 if (tx_count)
937 ++tx_count;
938 }
939
940 for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
941 if (tx->status.rates[i].count >= tx_count) {
942 tx->status.rates[i].count = tx_count;
943 break;
944 }
945 tx_count -= tx->status.rates[i].count;
946 if (tx->status.rates[i].flags & IEEE80211_TX_RC_MCS)
947 tx->status.rates[i].flags |= ht_flags;
948 }
949
950 for (++i; i < IEEE80211_TX_MAX_RATES; ++i) {
951 tx->status.rates[i].count = 0;
952 tx->status.rates[i].idx = -1;
953 }
954
955 /* Pull off any crypto trailers that we added on */
956 if (tx->control.hw_key) {
957 skb_trim(skb, skb->len - tx->control.hw_key->icv_len);
958 if (tx->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
959 skb_trim(skb, skb->len - 8); /* MIC space */
960 }
961 cw1200_queue_remove(queue, arg->packet_id);
962 }
963 /* XXX TODO: Only wake if there are pending transmits.. */
964 cw1200_bh_wakeup(priv);
965}
966
967static void cw1200_notify_buffered_tx(struct cw1200_common *priv,
968 struct sk_buff *skb, int link_id, int tid)
969{
970 struct ieee80211_sta *sta;
971 struct ieee80211_hdr *hdr;
972 u8 *buffered;
973 u8 still_buffered = 0;
974
975 if (link_id && tid < CW1200_MAX_TID) {
976 buffered = priv->link_id_db
977 [link_id - 1].buffered;
978
979 spin_lock_bh(&priv->ps_state_lock);
980 if (!WARN_ON(!buffered[tid]))
981 still_buffered = --buffered[tid];
982 spin_unlock_bh(&priv->ps_state_lock);
983
984 if (!still_buffered && tid < CW1200_MAX_TID) {
985 hdr = (struct ieee80211_hdr *)skb->data;
986 rcu_read_lock();
987 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
988 if (sta)
989 ieee80211_sta_set_buffered(sta, tid, false);
990 rcu_read_unlock();
991 }
992 }
993}
994
995void cw1200_skb_dtor(struct cw1200_common *priv,
996 struct sk_buff *skb,
997 const struct cw1200_txpriv *txpriv)
998{
999 skb_pull(skb, txpriv->offset);
1000 if (txpriv->rate_id != CW1200_INVALID_RATE_ID) {
1001 cw1200_notify_buffered_tx(priv, skb,
1002 txpriv->raw_link_id, txpriv->tid);
1003 tx_policy_put(priv, txpriv->rate_id);
1004 }
1005 if (!cw1200_is_itp(priv))
1006 ieee80211_tx_status(priv->hw, skb);
1007}
1008
1009void cw1200_rx_cb(struct cw1200_common *priv,
1010 struct wsm_rx *arg,
1011 int link_id,
1012 struct sk_buff **skb_p)
1013{
1014 struct sk_buff *skb = *skb_p;
1015 struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
1016 struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
1017 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1018 struct cw1200_link_entry *entry = NULL;
1019 unsigned long grace_period;
1020
1021 bool early_data = false;
1022 bool p2p = priv->vif && priv->vif->p2p;
1023 size_t hdrlen;
1024 hdr->flag = 0;
1025
1026 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
1027 /* STA is stopped. */
1028 goto drop;
1029 }
1030
1031 if (link_id && link_id <= CW1200_MAX_STA_IN_AP_MODE) {
1032 entry = &priv->link_id_db[link_id - 1];
1033 if (entry->status == CW1200_LINK_SOFT &&
1034 ieee80211_is_data(frame->frame_control))
1035 early_data = true;
1036 entry->timestamp = jiffies;
1037 } else if (p2p &&
1038 ieee80211_is_action(frame->frame_control) &&
1039 (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
1040 pr_debug("[RX] Going to MAP&RESET link ID\n");
1041 WARN_ON(work_pending(&priv->linkid_reset_work));
1042 memcpy(&priv->action_frame_sa[0],
1043 ieee80211_get_SA(frame), ETH_ALEN);
1044 priv->action_linkid = 0;
1045 schedule_work(&priv->linkid_reset_work);
1046 }
1047
1048 if (link_id && p2p &&
1049 ieee80211_is_action(frame->frame_control) &&
1050 (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
1051 /* Link ID already exists for the ACTION frame.
1052 * Reset and Remap */
1053 WARN_ON(work_pending(&priv->linkid_reset_work));
1054 memcpy(&priv->action_frame_sa[0],
1055 ieee80211_get_SA(frame), ETH_ALEN);
1056 priv->action_linkid = link_id;
1057 schedule_work(&priv->linkid_reset_work);
1058 }
1059 if (arg->status) {
1060 if (arg->status == WSM_STATUS_MICFAILURE) {
1061 pr_debug("[RX] MIC failure.\n");
1062 hdr->flag |= RX_FLAG_MMIC_ERROR;
1063 } else if (arg->status == WSM_STATUS_NO_KEY_FOUND) {
1064 pr_debug("[RX] No key found.\n");
1065 goto drop;
1066 } else {
1067 pr_debug("[RX] Receive failure: %d.\n",
1068 arg->status);
1069 goto drop;
1070 }
1071 }
1072
1073 if (skb->len < sizeof(struct ieee80211_pspoll)) {
1074 wiphy_warn(priv->hw->wiphy, "Mailformed SDU rx'ed. Size is lesser than IEEE header.\n");
1075 goto drop;
1076 }
1077
1078 if (ieee80211_is_pspoll(frame->frame_control))
1079 if (cw1200_handle_pspoll(priv, skb))
1080 goto drop;
1081
1082 hdr->mactime = 0; /* Not supported by WSM */
1083 hdr->band = ((arg->channel_number & 0xff00) ||
1084 (arg->channel_number > 14)) ?
1085 IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
1086 hdr->freq = ieee80211_channel_to_frequency(
1087 arg->channel_number,
1088 hdr->band);
1089
1090 if (arg->rx_rate >= 14) {
1091 hdr->flag |= RX_FLAG_HT;
1092 hdr->rate_idx = arg->rx_rate - 14;
1093 } else if (arg->rx_rate >= 4) {
1094 hdr->rate_idx = arg->rx_rate - 2;
1095 } else {
1096 hdr->rate_idx = arg->rx_rate;
1097 }
1098
1099 hdr->signal = (s8)arg->rcpi_rssi;
1100 hdr->antenna = 0;
1101
1102 hdrlen = ieee80211_hdrlen(frame->frame_control);
1103
1104 if (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
1105 size_t iv_len = 0, icv_len = 0;
1106
1107 hdr->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED;
1108
1109 /* Oops... There is no fast way to ask mac80211 about
1110 * IV/ICV lengths. Even defineas are not exposed.*/
1111 switch (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
1112 case WSM_RX_STATUS_WEP:
1113 iv_len = 4 /* WEP_IV_LEN */;
1114 icv_len = 4 /* WEP_ICV_LEN */;
1115 break;
1116 case WSM_RX_STATUS_TKIP:
1117 iv_len = 8 /* TKIP_IV_LEN */;
1118 icv_len = 4 /* TKIP_ICV_LEN */
1119 + 8 /*MICHAEL_MIC_LEN*/;
1120 hdr->flag |= RX_FLAG_MMIC_STRIPPED;
1121 break;
1122 case WSM_RX_STATUS_AES:
1123 iv_len = 8 /* CCMP_HDR_LEN */;
1124 icv_len = 8 /* CCMP_MIC_LEN */;
1125 break;
1126 case WSM_RX_STATUS_WAPI:
1127 iv_len = 18 /* WAPI_HDR_LEN */;
1128 icv_len = 16 /* WAPI_MIC_LEN */;
1129 break;
1130 default:
1131 pr_warn("Unknown encryption type %d\n",
1132 WSM_RX_STATUS_ENCRYPTION(arg->flags));
1133 goto drop;
1134 }
1135
1136 /* Firmware strips ICV in case of MIC failure. */
1137 if (arg->status == WSM_STATUS_MICFAILURE)
1138 icv_len = 0;
1139
1140 if (skb->len < hdrlen + iv_len + icv_len) {
1141 wiphy_warn(priv->hw->wiphy, "Malformed SDU rx'ed. Size is lesser than crypto headers.\n");
1142 goto drop;
1143 }
1144
1145 /* Remove IV, ICV and MIC */
1146 skb_trim(skb, skb->len - icv_len);
1147 memmove(skb->data + iv_len, skb->data, hdrlen);
1148 skb_pull(skb, iv_len);
1149 }
1150
1151 /* Remove TSF from the end of frame */
1152 if (arg->flags & WSM_RX_STATUS_TSF_INCLUDED) {
1153 memcpy(&hdr->mactime, skb->data + skb->len - 8, 8);
1154 hdr->mactime = le64_to_cpu(hdr->mactime);
1155 if (skb->len >= 8)
1156 skb_trim(skb, skb->len - 8);
1157 }
1158
1159 cw1200_debug_rxed(priv);
1160 if (arg->flags & WSM_RX_STATUS_AGGREGATE)
1161 cw1200_debug_rxed_agg(priv);
1162
1163 if (ieee80211_is_action(frame->frame_control) &&
1164 (arg->flags & WSM_RX_STATUS_ADDRESS1)) {
1165 if (cw1200_handle_action_rx(priv, skb))
1166 return;
1167 } else if (ieee80211_is_beacon(frame->frame_control) &&
1168 !arg->status &&
1169 !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid,
1170 ETH_ALEN)) {
1171 const u8 *tim_ie;
1172 u8 *ies = ((struct ieee80211_mgmt *)
1173 (skb->data))->u.beacon.variable;
1174 size_t ies_len = skb->len - (ies - (u8 *)(skb->data));
1175
1176 tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
1177 if (tim_ie) {
1178 struct ieee80211_tim_ie *tim =
1179 (struct ieee80211_tim_ie *)&tim_ie[2];
1180
1181 if (priv->join_dtim_period != tim->dtim_period) {
1182 priv->join_dtim_period = tim->dtim_period;
1183 queue_work(priv->workqueue,
1184 &priv->set_beacon_wakeup_period_work);
1185 }
1186 }
1187
1188 /* Disable beacon filter once we're associated... */
1189 if (priv->disable_beacon_filter &&
1190 (priv->vif->bss_conf.assoc ||
1191 priv->vif->bss_conf.ibss_joined)) {
1192 priv->disable_beacon_filter = false;
1193 queue_work(priv->workqueue,
1194 &priv->update_filtering_work);
1195 }
1196 }
1197
1198 /* Stay awake after frame is received to give
1199 * userspace chance to react and acquire appropriate
1200 * wakelock. */
1201 if (ieee80211_is_auth(frame->frame_control))
1202 grace_period = 5 * HZ;
1203 else if (ieee80211_is_deauth(frame->frame_control))
1204 grace_period = 5 * HZ;
1205 else
1206 grace_period = 1 * HZ;
1207 cw1200_pm_stay_awake(&priv->pm_state, grace_period);
1208
1209 if (cw1200_itp_rxed(priv, skb)) {
1210 consume_skb(skb);
1211 } else if (early_data) {
1212 spin_lock_bh(&priv->ps_state_lock);
1213 /* Double-check status with lock held */
1214 if (entry->status == CW1200_LINK_SOFT)
1215 skb_queue_tail(&entry->rx_queue, skb);
1216 else
1217 ieee80211_rx_irqsafe(priv->hw, skb);
1218 spin_unlock_bh(&priv->ps_state_lock);
1219 } else {
1220 ieee80211_rx_irqsafe(priv->hw, skb);
1221 }
1222 *skb_p = NULL;
1223
1224 return;
1225
1226drop:
1227 /* TODO: update failure counters */
1228 return;
1229}
1230
1231/* ******************************************************************** */
1232/* Security */
1233
1234int cw1200_alloc_key(struct cw1200_common *priv)
1235{
1236 int idx;
1237
1238 idx = ffs(~priv->key_map) - 1;
1239 if (idx < 0 || idx > WSM_KEY_MAX_INDEX)
1240 return -1;
1241
1242 priv->key_map |= BIT(idx);
1243 priv->keys[idx].index = idx;
1244 return idx;
1245}
1246
1247void cw1200_free_key(struct cw1200_common *priv, int idx)
1248{
1249 BUG_ON(!(priv->key_map & BIT(idx)));
1250 memset(&priv->keys[idx], 0, sizeof(priv->keys[idx]));
1251 priv->key_map &= ~BIT(idx);
1252}
1253
1254void cw1200_free_keys(struct cw1200_common *priv)
1255{
1256 memset(&priv->keys, 0, sizeof(priv->keys));
1257 priv->key_map = 0;
1258}
1259
1260int cw1200_upload_keys(struct cw1200_common *priv)
1261{
1262 int idx, ret = 0;
1263 for (idx = 0; idx <= WSM_KEY_MAX_INDEX; ++idx)
1264 if (priv->key_map & BIT(idx)) {
1265 ret = wsm_add_key(priv, &priv->keys[idx]);
1266 if (ret < 0)
1267 break;
1268 }
1269 return ret;
1270}
1271
1272/* Workaround for WFD test case 6.1.10 */
1273void cw1200_link_id_reset(struct work_struct *work)
1274{
1275 struct cw1200_common *priv =
1276 container_of(work, struct cw1200_common, linkid_reset_work);
1277 int temp_linkid;
1278
1279 if (!priv->action_linkid) {
1280 /* In GO mode we can receive ACTION frames without a linkID */
1281 temp_linkid = cw1200_alloc_link_id(priv,
1282 &priv->action_frame_sa[0]);
1283 WARN_ON(!temp_linkid);
1284 if (temp_linkid) {
1285 /* Make sure we execute the WQ */
1286 flush_workqueue(priv->workqueue);
1287 /* Release the link ID */
1288 spin_lock_bh(&priv->ps_state_lock);
1289 priv->link_id_db[temp_linkid - 1].prev_status =
1290 priv->link_id_db[temp_linkid - 1].status;
1291 priv->link_id_db[temp_linkid - 1].status =
1292 CW1200_LINK_RESET;
1293 spin_unlock_bh(&priv->ps_state_lock);
1294 wsm_lock_tx_async(priv);
1295 if (queue_work(priv->workqueue,
1296 &priv->link_id_work) <= 0)
1297 wsm_unlock_tx(priv);
1298 }
1299 } else {
1300 spin_lock_bh(&priv->ps_state_lock);
1301 priv->link_id_db[priv->action_linkid - 1].prev_status =
1302 priv->link_id_db[priv->action_linkid - 1].status;
1303 priv->link_id_db[priv->action_linkid - 1].status =
1304 CW1200_LINK_RESET_REMAP;
1305 spin_unlock_bh(&priv->ps_state_lock);
1306 wsm_lock_tx_async(priv);
1307 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1308 wsm_unlock_tx(priv);
1309 flush_workqueue(priv->workqueue);
1310 }
1311}
1312
1313int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac)
1314{
1315 int i, ret = 0;
1316 spin_lock_bh(&priv->ps_state_lock);
1317 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1318 if (!memcmp(mac, priv->link_id_db[i].mac, ETH_ALEN) &&
1319 priv->link_id_db[i].status) {
1320 priv->link_id_db[i].timestamp = jiffies;
1321 ret = i + 1;
1322 break;
1323 }
1324 }
1325 spin_unlock_bh(&priv->ps_state_lock);
1326 return ret;
1327}
1328
1329int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac)
1330{
1331 int i, ret = 0;
1332 unsigned long max_inactivity = 0;
1333 unsigned long now = jiffies;
1334
1335 spin_lock_bh(&priv->ps_state_lock);
1336 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1337 if (!priv->link_id_db[i].status) {
1338 ret = i + 1;
1339 break;
1340 } else if (priv->link_id_db[i].status != CW1200_LINK_HARD &&
1341 !priv->tx_queue_stats.link_map_cache[i + 1]) {
1342 unsigned long inactivity =
1343 now - priv->link_id_db[i].timestamp;
1344 if (inactivity < max_inactivity)
1345 continue;
1346 max_inactivity = inactivity;
1347 ret = i + 1;
1348 }
1349 }
1350 if (ret) {
1351 struct cw1200_link_entry *entry = &priv->link_id_db[ret - 1];
1352 pr_debug("[AP] STA added, link_id: %d\n", ret);
1353 entry->status = CW1200_LINK_RESERVE;
1354 memcpy(&entry->mac, mac, ETH_ALEN);
1355 memset(&entry->buffered, 0, CW1200_MAX_TID);
1356 skb_queue_head_init(&entry->rx_queue);
1357 wsm_lock_tx_async(priv);
1358 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1359 wsm_unlock_tx(priv);
1360 } else {
1361 wiphy_info(priv->hw->wiphy,
1362 "[AP] Early: no more link IDs available.\n");
1363 }
1364
1365 spin_unlock_bh(&priv->ps_state_lock);
1366 return ret;
1367}
1368
1369void cw1200_link_id_work(struct work_struct *work)
1370{
1371 struct cw1200_common *priv =
1372 container_of(work, struct cw1200_common, link_id_work);
1373 wsm_flush_tx(priv);
1374 cw1200_link_id_gc_work(&priv->link_id_gc_work.work);
1375 wsm_unlock_tx(priv);
1376}
1377
1378void cw1200_link_id_gc_work(struct work_struct *work)
1379{
1380 struct cw1200_common *priv =
1381 container_of(work, struct cw1200_common, link_id_gc_work.work);
1382 struct wsm_reset reset = {
1383 .reset_statistics = false,
1384 };
1385 struct wsm_map_link map_link = {
1386 .link_id = 0,
1387 };
1388 unsigned long now = jiffies;
1389 unsigned long next_gc = -1;
1390 long ttl;
1391 bool need_reset;
1392 u32 mask;
1393 int i;
1394
1395 if (priv->join_status != CW1200_JOIN_STATUS_AP)
1396 return;
1397
1398 wsm_lock_tx(priv);
1399 spin_lock_bh(&priv->ps_state_lock);
1400 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1401 need_reset = false;
1402 mask = BIT(i + 1);
1403 if (priv->link_id_db[i].status == CW1200_LINK_RESERVE ||
1404 (priv->link_id_db[i].status == CW1200_LINK_HARD &&
1405 !(priv->link_id_map & mask))) {
1406 if (priv->link_id_map & mask) {
1407 priv->sta_asleep_mask &= ~mask;
1408 priv->pspoll_mask &= ~mask;
1409 need_reset = true;
1410 }
1411 priv->link_id_map |= mask;
1412 if (priv->link_id_db[i].status != CW1200_LINK_HARD)
1413 priv->link_id_db[i].status = CW1200_LINK_SOFT;
1414 memcpy(map_link.mac_addr, priv->link_id_db[i].mac,
1415 ETH_ALEN);
1416 spin_unlock_bh(&priv->ps_state_lock);
1417 if (need_reset) {
1418 reset.link_id = i + 1;
1419 wsm_reset(priv, &reset);
1420 }
1421 map_link.link_id = i + 1;
1422 wsm_map_link(priv, &map_link);
1423 next_gc = min(next_gc, CW1200_LINK_ID_GC_TIMEOUT);
1424 spin_lock_bh(&priv->ps_state_lock);
1425 } else if (priv->link_id_db[i].status == CW1200_LINK_SOFT) {
1426 ttl = priv->link_id_db[i].timestamp - now +
1427 CW1200_LINK_ID_GC_TIMEOUT;
1428 if (ttl <= 0) {
1429 need_reset = true;
1430 priv->link_id_db[i].status = CW1200_LINK_OFF;
1431 priv->link_id_map &= ~mask;
1432 priv->sta_asleep_mask &= ~mask;
1433 priv->pspoll_mask &= ~mask;
1434 memset(map_link.mac_addr, 0, ETH_ALEN);
1435 spin_unlock_bh(&priv->ps_state_lock);
1436 reset.link_id = i + 1;
1437 wsm_reset(priv, &reset);
1438 spin_lock_bh(&priv->ps_state_lock);
1439 } else {
1440 next_gc = min_t(unsigned long, next_gc, ttl);
1441 }
1442 } else if (priv->link_id_db[i].status == CW1200_LINK_RESET ||
1443 priv->link_id_db[i].status ==
1444 CW1200_LINK_RESET_REMAP) {
1445 int status = priv->link_id_db[i].status;
1446 priv->link_id_db[i].status =
1447 priv->link_id_db[i].prev_status;
1448 priv->link_id_db[i].timestamp = now;
1449 reset.link_id = i + 1;
1450 spin_unlock_bh(&priv->ps_state_lock);
1451 wsm_reset(priv, &reset);
1452 if (status == CW1200_LINK_RESET_REMAP) {
1453 memcpy(map_link.mac_addr,
1454 priv->link_id_db[i].mac,
1455 ETH_ALEN);
1456 map_link.link_id = i + 1;
1457 wsm_map_link(priv, &map_link);
1458 next_gc = min(next_gc,
1459 CW1200_LINK_ID_GC_TIMEOUT);
1460 }
1461 spin_lock_bh(&priv->ps_state_lock);
1462 }
1463 if (need_reset) {
1464 skb_queue_purge(&priv->link_id_db[i].rx_queue);
1465 pr_debug("[AP] STA removed, link_id: %d\n",
1466 reset.link_id);
1467 }
1468 }
1469 spin_unlock_bh(&priv->ps_state_lock);
1470 if (next_gc != -1)
1471 queue_delayed_work(priv->workqueue,
1472 &priv->link_id_gc_work, next_gc);
1473 wsm_unlock_tx(priv);
1474}
diff --git a/drivers/net/wireless/cw1200/txrx.h b/drivers/net/wireless/cw1200/txrx.h
new file mode 100644
index 000000000000..492a4e14213b
--- /dev/null
+++ b/drivers/net/wireless/cw1200/txrx.h
@@ -0,0 +1,106 @@
1/*
2 * Datapath interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_TXRX_H
13#define CW1200_TXRX_H
14
15#include <linux/list.h>
16
17/* extern */ struct ieee80211_hw;
18/* extern */ struct sk_buff;
19/* extern */ struct wsm_tx;
20/* extern */ struct wsm_rx;
21/* extern */ struct wsm_tx_confirm;
22/* extern */ struct cw1200_txpriv;
23
24struct tx_policy {
25 union {
26 __le32 tbl[3];
27 u8 raw[12];
28 };
29 u8 defined;
30 u8 usage_count;
31 u8 retry_count;
32 u8 uploaded;
33};
34
35struct tx_policy_cache_entry {
36 struct tx_policy policy;
37 struct list_head link;
38};
39
40#define TX_POLICY_CACHE_SIZE (8)
41struct tx_policy_cache {
42 struct tx_policy_cache_entry cache[TX_POLICY_CACHE_SIZE];
43 struct list_head used;
44 struct list_head free;
45 spinlock_t lock; /* Protect policy cache */
46};
47
48/* ******************************************************************** */
49/* TX policy cache */
50/* Intention of TX policy cache is an overcomplicated WSM API.
51 * Device does not accept per-PDU tx retry sequence.
52 * It uses "tx retry policy id" instead, so driver code has to sync
53 * linux tx retry sequences with a retry policy table in the device.
54 */
55void tx_policy_init(struct cw1200_common *priv);
56void tx_policy_upload_work(struct work_struct *work);
57void tx_policy_clean(struct cw1200_common *priv);
58
59/* ******************************************************************** */
60/* TX implementation */
61
62u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv,
63 u32 rates);
64void cw1200_tx(struct ieee80211_hw *dev,
65 struct ieee80211_tx_control *control,
66 struct sk_buff *skb);
67void cw1200_skb_dtor(struct cw1200_common *priv,
68 struct sk_buff *skb,
69 const struct cw1200_txpriv *txpriv);
70
71/* ******************************************************************** */
72/* WSM callbacks */
73
74void cw1200_tx_confirm_cb(struct cw1200_common *priv,
75 int link_id,
76 struct wsm_tx_confirm *arg);
77void cw1200_rx_cb(struct cw1200_common *priv,
78 struct wsm_rx *arg,
79 int link_id,
80 struct sk_buff **skb_p);
81
82/* ******************************************************************** */
83/* Timeout */
84
85void cw1200_tx_timeout(struct work_struct *work);
86
87/* ******************************************************************** */
88/* Security */
89int cw1200_alloc_key(struct cw1200_common *priv);
90void cw1200_free_key(struct cw1200_common *priv, int idx);
91void cw1200_free_keys(struct cw1200_common *priv);
92int cw1200_upload_keys(struct cw1200_common *priv);
93
94/* ******************************************************************** */
95/* Workaround for WFD test case 6.1.10 */
96void cw1200_link_id_reset(struct work_struct *work);
97
98#define CW1200_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
99
100int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac);
101int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac);
102void cw1200_link_id_work(struct work_struct *work);
103void cw1200_link_id_gc_work(struct work_struct *work);
104
105
106#endif /* CW1200_TXRX_H */
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
new file mode 100644
index 000000000000..4db6cc16879c
--- /dev/null
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -0,0 +1,1884 @@
1/*
2 * WSM host interface (HI) implementation for
3 * ST-Ericsson CW1200 mac80211 drivers.
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/skbuff.h>
14#include <linux/wait.h>
15#include <linux/skbuff.h>
16#include <linux/delay.h>
17#include <linux/sched.h>
18#include <linux/random.h>
19
20#include "cw1200.h"
21#include "wsm.h"
22#include "bh.h"
23#include "sta.h"
24#include "debug.h"
25#include "itp.h"
26
27#define WSM_CMD_TIMEOUT (2 * HZ) /* With respect to interrupt loss */
28#define WSM_CMD_START_TIMEOUT (7 * HZ)
29#define WSM_CMD_RESET_TIMEOUT (3 * HZ) /* 2 sec. timeout was observed. */
30#define WSM_CMD_MAX_TIMEOUT (3 * HZ)
31
32#define WSM_SKIP(buf, size) \
33 do { \
34 if ((buf)->data + size > (buf)->end) \
35 goto underflow; \
36 (buf)->data += size; \
37 } while (0)
38
39#define WSM_GET(buf, ptr, size) \
40 do { \
41 if ((buf)->data + size > (buf)->end) \
42 goto underflow; \
43 memcpy(ptr, (buf)->data, size); \
44 (buf)->data += size; \
45 } while (0)
46
47#define __WSM_GET(buf, type, cvt) \
48 ({ \
49 type val; \
50 if ((buf)->data + sizeof(type) > (buf)->end) \
51 goto underflow; \
52 val = cvt(*(type *)(buf)->data); \
53 (buf)->data += sizeof(type); \
54 val; \
55 })
56
57#define WSM_GET8(buf) __WSM_GET(buf, u8, (u8))
58#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16_to_cpu)
59#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32_to_cpu)
60
61#define WSM_PUT(buf, ptr, size) \
62 do { \
63 if ((buf)->data + size > (buf)->end) \
64 if (wsm_buf_reserve((buf), size)) \
65 goto nomem; \
66 memcpy((buf)->data, ptr, size); \
67 (buf)->data += size; \
68 } while (0)
69
70#define __WSM_PUT(buf, val, type, cvt) \
71 do { \
72 if ((buf)->data + sizeof(type) > (buf)->end) \
73 if (wsm_buf_reserve((buf), sizeof(type))) \
74 goto nomem; \
75 *(type *)(buf)->data = cvt(val); \
76 (buf)->data += sizeof(type); \
77 } while (0)
78
79#define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, (u8))
80#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __cpu_to_le16)
81#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __cpu_to_le32)
82
83static void wsm_buf_reset(struct wsm_buf *buf);
84static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
85
86static int wsm_cmd_send(struct cw1200_common *priv,
87 struct wsm_buf *buf,
88 void *arg, u16 cmd, long tmo);
89
90#define wsm_cmd_lock(__priv) mutex_lock(&((__priv)->wsm_cmd_mux))
91#define wsm_cmd_unlock(__priv) mutex_unlock(&((__priv)->wsm_cmd_mux))
92
93/* ******************************************************************** */
94/* WSM API implementation */
95
96static int wsm_generic_confirm(struct cw1200_common *priv,
97 void *arg,
98 struct wsm_buf *buf)
99{
100 u32 status = WSM_GET32(buf);
101 if (status != WSM_STATUS_SUCCESS)
102 return -EINVAL;
103 return 0;
104
105underflow:
106 WARN_ON(1);
107 return -EINVAL;
108}
109
110int wsm_configuration(struct cw1200_common *priv, struct wsm_configuration *arg)
111{
112 int ret;
113 struct wsm_buf *buf = &priv->wsm_cmd_buf;
114
115 wsm_cmd_lock(priv);
116
117 WSM_PUT32(buf, arg->dot11MaxTransmitMsduLifeTime);
118 WSM_PUT32(buf, arg->dot11MaxReceiveLifeTime);
119 WSM_PUT32(buf, arg->dot11RtsThreshold);
120
121 /* DPD block. */
122 WSM_PUT16(buf, arg->dpdData_size + 12);
123 WSM_PUT16(buf, 1); /* DPD version */
124 WSM_PUT(buf, arg->dot11StationId, ETH_ALEN);
125 WSM_PUT16(buf, 5); /* DPD flags */
126 WSM_PUT(buf, arg->dpdData, arg->dpdData_size);
127
128 ret = wsm_cmd_send(priv, buf, arg,
129 WSM_CONFIGURATION_REQ_ID, WSM_CMD_TIMEOUT);
130
131 wsm_cmd_unlock(priv);
132 return ret;
133
134nomem:
135 wsm_cmd_unlock(priv);
136 return -ENOMEM;
137}
138
139static int wsm_configuration_confirm(struct cw1200_common *priv,
140 struct wsm_configuration *arg,
141 struct wsm_buf *buf)
142{
143 int i;
144 int status;
145
146 status = WSM_GET32(buf);
147 if (WARN_ON(status != WSM_STATUS_SUCCESS))
148 return -EINVAL;
149
150 WSM_GET(buf, arg->dot11StationId, ETH_ALEN);
151 arg->dot11FrequencyBandsSupported = WSM_GET8(buf);
152 WSM_SKIP(buf, 1);
153 arg->supportedRateMask = WSM_GET32(buf);
154 for (i = 0; i < 2; ++i) {
155 arg->txPowerRange[i].min_power_level = WSM_GET32(buf);
156 arg->txPowerRange[i].max_power_level = WSM_GET32(buf);
157 arg->txPowerRange[i].stepping = WSM_GET32(buf);
158 }
159 return 0;
160
161underflow:
162 WARN_ON(1);
163 return -EINVAL;
164}
165
166/* ******************************************************************** */
167
168int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg)
169{
170 int ret;
171 struct wsm_buf *buf = &priv->wsm_cmd_buf;
172 u16 cmd = WSM_RESET_REQ_ID | WSM_TX_LINK_ID(arg->link_id);
173
174 wsm_cmd_lock(priv);
175
176 WSM_PUT32(buf, arg->reset_statistics ? 0 : 1);
177 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_RESET_TIMEOUT);
178 wsm_cmd_unlock(priv);
179 return ret;
180
181nomem:
182 wsm_cmd_unlock(priv);
183 return -ENOMEM;
184}
185
186/* ******************************************************************** */
187
188struct wsm_mib {
189 u16 mib_id;
190 void *buf;
191 size_t buf_size;
192};
193
194int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
195 size_t buf_size)
196{
197 int ret;
198 struct wsm_buf *buf = &priv->wsm_cmd_buf;
199 struct wsm_mib mib_buf = {
200 .mib_id = mib_id,
201 .buf = _buf,
202 .buf_size = buf_size,
203 };
204 wsm_cmd_lock(priv);
205
206 WSM_PUT16(buf, mib_id);
207 WSM_PUT16(buf, 0);
208
209 ret = wsm_cmd_send(priv, buf, &mib_buf,
210 WSM_READ_MIB_REQ_ID, WSM_CMD_TIMEOUT);
211 wsm_cmd_unlock(priv);
212 return ret;
213
214nomem:
215 wsm_cmd_unlock(priv);
216 return -ENOMEM;
217}
218
219static int wsm_read_mib_confirm(struct cw1200_common *priv,
220 struct wsm_mib *arg,
221 struct wsm_buf *buf)
222{
223 u16 size;
224 if (WARN_ON(WSM_GET32(buf) != WSM_STATUS_SUCCESS))
225 return -EINVAL;
226
227 if (WARN_ON(WSM_GET16(buf) != arg->mib_id))
228 return -EINVAL;
229
230 size = WSM_GET16(buf);
231 if (size > arg->buf_size)
232 size = arg->buf_size;
233
234 WSM_GET(buf, arg->buf, size);
235 arg->buf_size = size;
236 return 0;
237
238underflow:
239 WARN_ON(1);
240 return -EINVAL;
241}
242
243/* ******************************************************************** */
244
245int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
246 size_t buf_size)
247{
248 int ret;
249 struct wsm_buf *buf = &priv->wsm_cmd_buf;
250 struct wsm_mib mib_buf = {
251 .mib_id = mib_id,
252 .buf = _buf,
253 .buf_size = buf_size,
254 };
255
256 wsm_cmd_lock(priv);
257
258 WSM_PUT16(buf, mib_id);
259 WSM_PUT16(buf, buf_size);
260 WSM_PUT(buf, _buf, buf_size);
261
262 ret = wsm_cmd_send(priv, buf, &mib_buf,
263 WSM_WRITE_MIB_REQ_ID, WSM_CMD_TIMEOUT);
264 wsm_cmd_unlock(priv);
265 return ret;
266
267nomem:
268 wsm_cmd_unlock(priv);
269 return -ENOMEM;
270}
271
272static int wsm_write_mib_confirm(struct cw1200_common *priv,
273 struct wsm_mib *arg,
274 struct wsm_buf *buf)
275{
276 int ret;
277
278 ret = wsm_generic_confirm(priv, arg, buf);
279 if (ret)
280 return ret;
281
282 if (arg->mib_id == WSM_MIB_ID_OPERATIONAL_POWER_MODE) {
283 /* OperationalMode: update PM status. */
284 const char *p = arg->buf;
285 cw1200_enable_powersave(priv, (p[0] & 0x0F) ? true : false);
286 }
287 return 0;
288}
289
290/* ******************************************************************** */
291
292int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg)
293{
294 int i;
295 int ret;
296 struct wsm_buf *buf = &priv->wsm_cmd_buf;
297
298 if (arg->num_channels > 48)
299 return -EINVAL;
300
301 if (arg->num_ssids > 2)
302 return -EINVAL;
303
304 if (arg->band > 1)
305 return -EINVAL;
306
307 wsm_cmd_lock(priv);
308
309 WSM_PUT8(buf, arg->band);
310 WSM_PUT8(buf, arg->type);
311 WSM_PUT8(buf, arg->flags);
312 WSM_PUT8(buf, arg->max_tx_rate);
313 WSM_PUT32(buf, arg->auto_scan_interval);
314 WSM_PUT8(buf, arg->num_probes);
315 WSM_PUT8(buf, arg->num_channels);
316 WSM_PUT8(buf, arg->num_ssids);
317 WSM_PUT8(buf, arg->probe_delay);
318
319 for (i = 0; i < arg->num_channels; ++i) {
320 WSM_PUT16(buf, arg->ch[i].number);
321 WSM_PUT16(buf, 0);
322 WSM_PUT32(buf, arg->ch[i].min_chan_time);
323 WSM_PUT32(buf, arg->ch[i].max_chan_time);
324 WSM_PUT32(buf, 0);
325 }
326
327 for (i = 0; i < arg->num_ssids; ++i) {
328 WSM_PUT32(buf, arg->ssids[i].length);
329 WSM_PUT(buf, &arg->ssids[i].ssid[0],
330 sizeof(arg->ssids[i].ssid));
331 }
332
333 ret = wsm_cmd_send(priv, buf, NULL,
334 WSM_START_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
335 wsm_cmd_unlock(priv);
336 return ret;
337
338nomem:
339 wsm_cmd_unlock(priv);
340 return -ENOMEM;
341}
342
343/* ******************************************************************** */
344
345int wsm_stop_scan(struct cw1200_common *priv)
346{
347 int ret;
348 struct wsm_buf *buf = &priv->wsm_cmd_buf;
349 wsm_cmd_lock(priv);
350 ret = wsm_cmd_send(priv, buf, NULL,
351 WSM_STOP_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
352 wsm_cmd_unlock(priv);
353 return ret;
354}
355
356
357static int wsm_tx_confirm(struct cw1200_common *priv,
358 struct wsm_buf *buf,
359 int link_id)
360{
361 struct wsm_tx_confirm tx_confirm;
362
363 tx_confirm.packet_id = WSM_GET32(buf);
364 tx_confirm.status = WSM_GET32(buf);
365 tx_confirm.tx_rate = WSM_GET8(buf);
366 tx_confirm.ack_failures = WSM_GET8(buf);
367 tx_confirm.flags = WSM_GET16(buf);
368 tx_confirm.media_delay = WSM_GET32(buf);
369 tx_confirm.tx_queue_delay = WSM_GET32(buf);
370
371 cw1200_tx_confirm_cb(priv, link_id, &tx_confirm);
372 return 0;
373
374underflow:
375 WARN_ON(1);
376 return -EINVAL;
377}
378
379static int wsm_multi_tx_confirm(struct cw1200_common *priv,
380 struct wsm_buf *buf, int link_id)
381{
382 int ret;
383 int count;
384 int i;
385
386 count = WSM_GET32(buf);
387 if (WARN_ON(count <= 0))
388 return -EINVAL;
389
390 if (count > 1) {
391 /* We already released one buffer, now for the rest */
392 ret = wsm_release_tx_buffer(priv, count - 1);
393 if (ret < 0)
394 return ret;
395 else if (ret > 0)
396 cw1200_bh_wakeup(priv);
397 }
398
399 cw1200_debug_txed_multi(priv, count);
400 for (i = 0; i < count; ++i) {
401 ret = wsm_tx_confirm(priv, buf, link_id);
402 if (ret)
403 return ret;
404 }
405 return ret;
406
407underflow:
408 WARN_ON(1);
409 return -EINVAL;
410}
411
412/* ******************************************************************** */
413
414static int wsm_join_confirm(struct cw1200_common *priv,
415 struct wsm_join_cnf *arg,
416 struct wsm_buf *buf)
417{
418 arg->status = WSM_GET32(buf);
419 if (WARN_ON(arg->status) != WSM_STATUS_SUCCESS)
420 return -EINVAL;
421
422 arg->min_power_level = WSM_GET32(buf);
423 arg->max_power_level = WSM_GET32(buf);
424
425 return 0;
426
427underflow:
428 WARN_ON(1);
429 return -EINVAL;
430}
431
432int wsm_join(struct cw1200_common *priv, struct wsm_join *arg)
433{
434 int ret;
435 struct wsm_buf *buf = &priv->wsm_cmd_buf;
436 struct wsm_join_cnf resp;
437 wsm_cmd_lock(priv);
438
439 WSM_PUT8(buf, arg->mode);
440 WSM_PUT8(buf, arg->band);
441 WSM_PUT16(buf, arg->channel_number);
442 WSM_PUT(buf, &arg->bssid[0], sizeof(arg->bssid));
443 WSM_PUT16(buf, arg->atim_window);
444 WSM_PUT8(buf, arg->preamble_type);
445 WSM_PUT8(buf, arg->probe_for_join);
446 WSM_PUT8(buf, arg->dtim_period);
447 WSM_PUT8(buf, arg->flags);
448 WSM_PUT32(buf, arg->ssid_len);
449 WSM_PUT(buf, &arg->ssid[0], sizeof(arg->ssid));
450 WSM_PUT32(buf, arg->beacon_interval);
451 WSM_PUT32(buf, arg->basic_rate_set);
452
453 priv->tx_burst_idx = -1;
454 ret = wsm_cmd_send(priv, buf, &resp,
455 WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT);
456 /* TODO: Update state based on resp.min|max_power_level */
457
458 priv->join_complete_status = resp.status;
459
460 wsm_cmd_unlock(priv);
461 return ret;
462
463nomem:
464 wsm_cmd_unlock(priv);
465 return -ENOMEM;
466}
467
468/* ******************************************************************** */
469
470int wsm_set_bss_params(struct cw1200_common *priv,
471 const struct wsm_set_bss_params *arg)
472{
473 int ret;
474 struct wsm_buf *buf = &priv->wsm_cmd_buf;
475
476 wsm_cmd_lock(priv);
477
478 WSM_PUT8(buf, (arg->reset_beacon_loss ? 0x1 : 0));
479 WSM_PUT8(buf, arg->beacon_lost_count);
480 WSM_PUT16(buf, arg->aid);
481 WSM_PUT32(buf, arg->operational_rate_set);
482
483 ret = wsm_cmd_send(priv, buf, NULL,
484 WSM_SET_BSS_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
485
486 wsm_cmd_unlock(priv);
487 return ret;
488
489nomem:
490 wsm_cmd_unlock(priv);
491 return -ENOMEM;
492}
493
494/* ******************************************************************** */
495
496int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg)
497{
498 int ret;
499 struct wsm_buf *buf = &priv->wsm_cmd_buf;
500
501 wsm_cmd_lock(priv);
502
503 WSM_PUT(buf, arg, sizeof(*arg));
504
505 ret = wsm_cmd_send(priv, buf, NULL,
506 WSM_ADD_KEY_REQ_ID, WSM_CMD_TIMEOUT);
507
508 wsm_cmd_unlock(priv);
509 return ret;
510
511nomem:
512 wsm_cmd_unlock(priv);
513 return -ENOMEM;
514}
515
516/* ******************************************************************** */
517
518int wsm_remove_key(struct cw1200_common *priv, const struct wsm_remove_key *arg)
519{
520 int ret;
521 struct wsm_buf *buf = &priv->wsm_cmd_buf;
522
523 wsm_cmd_lock(priv);
524
525 WSM_PUT8(buf, arg->index);
526 WSM_PUT8(buf, 0);
527 WSM_PUT16(buf, 0);
528
529 ret = wsm_cmd_send(priv, buf, NULL,
530 WSM_REMOVE_KEY_REQ_ID, WSM_CMD_TIMEOUT);
531
532 wsm_cmd_unlock(priv);
533 return ret;
534
535nomem:
536 wsm_cmd_unlock(priv);
537 return -ENOMEM;
538}
539
540/* ******************************************************************** */
541
542int wsm_set_tx_queue_params(struct cw1200_common *priv,
543 const struct wsm_set_tx_queue_params *arg, u8 id)
544{
545 int ret;
546 struct wsm_buf *buf = &priv->wsm_cmd_buf;
547 u8 queue_id_to_wmm_aci[] = {3, 2, 0, 1};
548
549 wsm_cmd_lock(priv);
550
551 WSM_PUT8(buf, queue_id_to_wmm_aci[id]);
552 WSM_PUT8(buf, 0);
553 WSM_PUT8(buf, arg->ackPolicy);
554 WSM_PUT8(buf, 0);
555 WSM_PUT32(buf, arg->maxTransmitLifetime);
556 WSM_PUT16(buf, arg->allowedMediumTime);
557 WSM_PUT16(buf, 0);
558
559 ret = wsm_cmd_send(priv, buf, NULL, 0x0012, WSM_CMD_TIMEOUT);
560
561 wsm_cmd_unlock(priv);
562 return ret;
563
564nomem:
565 wsm_cmd_unlock(priv);
566 return -ENOMEM;
567}
568
569/* ******************************************************************** */
570
571int wsm_set_edca_params(struct cw1200_common *priv,
572 const struct wsm_edca_params *arg)
573{
574 int ret;
575 struct wsm_buf *buf = &priv->wsm_cmd_buf;
576
577 wsm_cmd_lock(priv);
578
579 /* Implemented according to specification. */
580
581 WSM_PUT16(buf, arg->params[3].cwmin);
582 WSM_PUT16(buf, arg->params[2].cwmin);
583 WSM_PUT16(buf, arg->params[1].cwmin);
584 WSM_PUT16(buf, arg->params[0].cwmin);
585
586 WSM_PUT16(buf, arg->params[3].cwmax);
587 WSM_PUT16(buf, arg->params[2].cwmax);
588 WSM_PUT16(buf, arg->params[1].cwmax);
589 WSM_PUT16(buf, arg->params[0].cwmax);
590
591 WSM_PUT8(buf, arg->params[3].aifns);
592 WSM_PUT8(buf, arg->params[2].aifns);
593 WSM_PUT8(buf, arg->params[1].aifns);
594 WSM_PUT8(buf, arg->params[0].aifns);
595
596 WSM_PUT16(buf, arg->params[3].txop_limit);
597 WSM_PUT16(buf, arg->params[2].txop_limit);
598 WSM_PUT16(buf, arg->params[1].txop_limit);
599 WSM_PUT16(buf, arg->params[0].txop_limit);
600
601 WSM_PUT32(buf, arg->params[3].max_rx_lifetime);
602 WSM_PUT32(buf, arg->params[2].max_rx_lifetime);
603 WSM_PUT32(buf, arg->params[1].max_rx_lifetime);
604 WSM_PUT32(buf, arg->params[0].max_rx_lifetime);
605
606 ret = wsm_cmd_send(priv, buf, NULL,
607 WSM_EDCA_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
608 wsm_cmd_unlock(priv);
609 return ret;
610
611nomem:
612 wsm_cmd_unlock(priv);
613 return -ENOMEM;
614}
615
616/* ******************************************************************** */
617
618int wsm_switch_channel(struct cw1200_common *priv,
619 const struct wsm_switch_channel *arg)
620{
621 int ret;
622 struct wsm_buf *buf = &priv->wsm_cmd_buf;
623
624 wsm_cmd_lock(priv);
625
626 WSM_PUT8(buf, arg->mode);
627 WSM_PUT8(buf, arg->switch_count);
628 WSM_PUT16(buf, arg->channel_number);
629
630 priv->channel_switch_in_progress = 1;
631
632 ret = wsm_cmd_send(priv, buf, NULL,
633 WSM_SWITCH_CHANNEL_REQ_ID, WSM_CMD_TIMEOUT);
634 if (ret)
635 priv->channel_switch_in_progress = 0;
636
637 wsm_cmd_unlock(priv);
638 return ret;
639
640nomem:
641 wsm_cmd_unlock(priv);
642 return -ENOMEM;
643}
644
645/* ******************************************************************** */
646
647int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
648{
649 int ret;
650 struct wsm_buf *buf = &priv->wsm_cmd_buf;
651 priv->ps_mode_switch_in_progress = 1;
652
653 wsm_cmd_lock(priv);
654
655 WSM_PUT8(buf, arg->mode);
656 WSM_PUT8(buf, arg->fast_psm_idle_period);
657 WSM_PUT8(buf, arg->ap_psm_change_period);
658 WSM_PUT8(buf, arg->min_auto_pspoll_period);
659
660 ret = wsm_cmd_send(priv, buf, NULL,
661 WSM_SET_PM_REQ_ID, WSM_CMD_TIMEOUT);
662
663 wsm_cmd_unlock(priv);
664 return ret;
665
666nomem:
667 wsm_cmd_unlock(priv);
668 return -ENOMEM;
669}
670
671/* ******************************************************************** */
672
673int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg)
674{
675 int ret;
676 struct wsm_buf *buf = &priv->wsm_cmd_buf;
677
678 wsm_cmd_lock(priv);
679
680 WSM_PUT8(buf, arg->mode);
681 WSM_PUT8(buf, arg->band);
682 WSM_PUT16(buf, arg->channel_number);
683 WSM_PUT32(buf, arg->ct_window);
684 WSM_PUT32(buf, arg->beacon_interval);
685 WSM_PUT8(buf, arg->dtim_period);
686 WSM_PUT8(buf, arg->preamble);
687 WSM_PUT8(buf, arg->probe_delay);
688 WSM_PUT8(buf, arg->ssid_len);
689 WSM_PUT(buf, arg->ssid, sizeof(arg->ssid));
690 WSM_PUT32(buf, arg->basic_rate_set);
691
692 priv->tx_burst_idx = -1;
693 ret = wsm_cmd_send(priv, buf, NULL,
694 WSM_START_REQ_ID, WSM_CMD_START_TIMEOUT);
695
696 wsm_cmd_unlock(priv);
697 return ret;
698
699nomem:
700 wsm_cmd_unlock(priv);
701 return -ENOMEM;
702}
703
704/* ******************************************************************** */
705
706int wsm_beacon_transmit(struct cw1200_common *priv,
707 const struct wsm_beacon_transmit *arg)
708{
709 int ret;
710 struct wsm_buf *buf = &priv->wsm_cmd_buf;
711
712 wsm_cmd_lock(priv);
713
714 WSM_PUT32(buf, arg->enable_beaconing ? 1 : 0);
715
716 ret = wsm_cmd_send(priv, buf, NULL,
717 WSM_BEACON_TRANSMIT_REQ_ID, WSM_CMD_TIMEOUT);
718
719 wsm_cmd_unlock(priv);
720 return ret;
721
722nomem:
723 wsm_cmd_unlock(priv);
724 return -ENOMEM;
725}
726
727/* ******************************************************************** */
728
729int wsm_start_find(struct cw1200_common *priv)
730{
731 int ret;
732 struct wsm_buf *buf = &priv->wsm_cmd_buf;
733
734 wsm_cmd_lock(priv);
735 ret = wsm_cmd_send(priv, buf, NULL, 0x0019, WSM_CMD_TIMEOUT);
736 wsm_cmd_unlock(priv);
737 return ret;
738}
739
740/* ******************************************************************** */
741
742int wsm_stop_find(struct cw1200_common *priv)
743{
744 int ret;
745 struct wsm_buf *buf = &priv->wsm_cmd_buf;
746
747 wsm_cmd_lock(priv);
748 ret = wsm_cmd_send(priv, buf, NULL, 0x001A, WSM_CMD_TIMEOUT);
749 wsm_cmd_unlock(priv);
750 return ret;
751}
752
753/* ******************************************************************** */
754
755int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg)
756{
757 int ret;
758 struct wsm_buf *buf = &priv->wsm_cmd_buf;
759 u16 cmd = 0x001C | WSM_TX_LINK_ID(arg->link_id);
760
761 wsm_cmd_lock(priv);
762
763 WSM_PUT(buf, &arg->mac_addr[0], sizeof(arg->mac_addr));
764 WSM_PUT16(buf, 0);
765
766 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_TIMEOUT);
767
768 wsm_cmd_unlock(priv);
769 return ret;
770
771nomem:
772 wsm_cmd_unlock(priv);
773 return -ENOMEM;
774}
775
776/* ******************************************************************** */
777
778int wsm_update_ie(struct cw1200_common *priv,
779 const struct wsm_update_ie *arg)
780{
781 int ret;
782 struct wsm_buf *buf = &priv->wsm_cmd_buf;
783
784 wsm_cmd_lock(priv);
785
786 WSM_PUT16(buf, arg->what);
787 WSM_PUT16(buf, arg->count);
788 WSM_PUT(buf, arg->ies, arg->length);
789
790 ret = wsm_cmd_send(priv, buf, NULL, 0x001B, WSM_CMD_TIMEOUT);
791
792 wsm_cmd_unlock(priv);
793 return ret;
794
795nomem:
796 wsm_cmd_unlock(priv);
797 return -ENOMEM;
798}
799
800/* ******************************************************************** */
801int wsm_set_probe_responder(struct cw1200_common *priv, bool enable)
802{
803 priv->rx_filter.probeResponder = enable;
804 return wsm_set_rx_filter(priv, &priv->rx_filter);
805}
806
807/* ******************************************************************** */
808/* WSM indication events implementation */
809const char * const cw1200_fw_types[] = {
810 "ETF",
811 "WFM",
812 "WSM",
813 "HI test",
814 "Platform test"
815};
816
817static int wsm_startup_indication(struct cw1200_common *priv,
818 struct wsm_buf *buf)
819{
820 priv->wsm_caps.input_buffers = WSM_GET16(buf);
821 priv->wsm_caps.input_buffer_size = WSM_GET16(buf);
822 priv->wsm_caps.hw_id = WSM_GET16(buf);
823 priv->wsm_caps.hw_subid = WSM_GET16(buf);
824 priv->wsm_caps.status = WSM_GET16(buf);
825 priv->wsm_caps.fw_cap = WSM_GET16(buf);
826 priv->wsm_caps.fw_type = WSM_GET16(buf);
827 priv->wsm_caps.fw_api = WSM_GET16(buf);
828 priv->wsm_caps.fw_build = WSM_GET16(buf);
829 priv->wsm_caps.fw_ver = WSM_GET16(buf);
830 WSM_GET(buf, priv->wsm_caps.fw_label, sizeof(priv->wsm_caps.fw_label));
831 priv->wsm_caps.fw_label[sizeof(priv->wsm_caps.fw_label) - 1] = 0; /* Do not trust FW too much... */
832
833 if (WARN_ON(priv->wsm_caps.status))
834 return -EINVAL;
835
836 if (WARN_ON(priv->wsm_caps.fw_type > 4))
837 return -EINVAL;
838
839 pr_info("CW1200 WSM init done.\n"
840 " Input buffers: %d x %d bytes\n"
841 " Hardware: %d.%d\n"
842 " %s firmware [%s], ver: %d, build: %d,"
843 " api: %d, cap: 0x%.4X\n",
844 priv->wsm_caps.input_buffers,
845 priv->wsm_caps.input_buffer_size,
846 priv->wsm_caps.hw_id, priv->wsm_caps.hw_subid,
847 cw1200_fw_types[priv->wsm_caps.fw_type],
848 priv->wsm_caps.fw_label, priv->wsm_caps.fw_ver,
849 priv->wsm_caps.fw_build,
850 priv->wsm_caps.fw_api, priv->wsm_caps.fw_cap);
851
852 /* Disable unsupported frequency bands */
853 if (!(priv->wsm_caps.fw_cap & 0x1))
854 priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
855 if (!(priv->wsm_caps.fw_cap & 0x2))
856 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
857
858 priv->firmware_ready = 1;
859 wake_up(&priv->wsm_startup_done);
860 return 0;
861
862underflow:
863 WARN_ON(1);
864 return -EINVAL;
865}
866
867static int wsm_receive_indication(struct cw1200_common *priv,
868 int link_id,
869 struct wsm_buf *buf,
870 struct sk_buff **skb_p)
871{
872 struct wsm_rx rx;
873 struct ieee80211_hdr *hdr;
874 size_t hdr_len;
875 __le16 fctl;
876
877 rx.status = WSM_GET32(buf);
878 rx.channel_number = WSM_GET16(buf);
879 rx.rx_rate = WSM_GET8(buf);
880 rx.rcpi_rssi = WSM_GET8(buf);
881 rx.flags = WSM_GET32(buf);
882
883 /* FW Workaround: Drop probe resp or
884 beacon when RSSI is 0
885 */
886 hdr = (struct ieee80211_hdr *)(*skb_p)->data;
887
888 if (!rx.rcpi_rssi &&
889 (ieee80211_is_probe_resp(hdr->frame_control) ||
890 ieee80211_is_beacon(hdr->frame_control)))
891 return 0;
892
893 /* If no RSSI subscription has been made,
894 * convert RCPI to RSSI here
895 */
896 if (!priv->cqm_use_rssi)
897 rx.rcpi_rssi = rx.rcpi_rssi / 2 - 110;
898
899 fctl = *(__le16 *)buf->data;
900 hdr_len = buf->data - buf->begin;
901 skb_pull(*skb_p, hdr_len);
902 if (!rx.status && ieee80211_is_deauth(fctl)) {
903 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
904 /* Shedule unjoin work */
905 pr_debug("[WSM] Issue unjoin command (RX).\n");
906 wsm_lock_tx_async(priv);
907 if (queue_work(priv->workqueue,
908 &priv->unjoin_work) <= 0)
909 wsm_unlock_tx(priv);
910 }
911 }
912 cw1200_rx_cb(priv, &rx, link_id, skb_p);
913 if (*skb_p)
914 skb_push(*skb_p, hdr_len);
915
916 return 0;
917
918underflow:
919 return -EINVAL;
920}
921
922static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
923{
924 int first;
925 struct cw1200_wsm_event *event;
926
927 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
928 /* STA is stopped. */
929 return 0;
930 }
931
932 event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
933
934 event->evt.id = __le32_to_cpu(WSM_GET32(buf));
935 event->evt.data = __le32_to_cpu(WSM_GET32(buf));
936
937 pr_debug("[WSM] Event: %d(%d)\n",
938 event->evt.id, event->evt.data);
939
940 spin_lock(&priv->event_queue_lock);
941 first = list_empty(&priv->event_queue);
942 list_add_tail(&event->link, &priv->event_queue);
943 spin_unlock(&priv->event_queue_lock);
944
945 if (first)
946 queue_work(priv->workqueue, &priv->event_handler);
947
948 return 0;
949
950underflow:
951 kfree(event);
952 return -EINVAL;
953}
954
955static int wsm_channel_switch_indication(struct cw1200_common *priv,
956 struct wsm_buf *buf)
957{
958 WARN_ON(WSM_GET32(buf));
959
960 priv->channel_switch_in_progress = 0;
961 wake_up(&priv->channel_switch_done);
962
963 wsm_unlock_tx(priv);
964
965 return 0;
966
967underflow:
968 return -EINVAL;
969}
970
971static int wsm_set_pm_indication(struct cw1200_common *priv,
972 struct wsm_buf *buf)
973{
974 /* TODO: Check buf (struct wsm_set_pm_complete) for validity */
975 if (priv->ps_mode_switch_in_progress) {
976 priv->ps_mode_switch_in_progress = 0;
977 wake_up(&priv->ps_mode_switch_done);
978 }
979 return 0;
980}
981
982static int wsm_scan_started(struct cw1200_common *priv, void *arg,
983 struct wsm_buf *buf)
984{
985 u32 status = WSM_GET32(buf);
986 if (status != WSM_STATUS_SUCCESS) {
987 cw1200_scan_failed_cb(priv);
988 return -EINVAL;
989 }
990 return 0;
991
992underflow:
993 WARN_ON(1);
994 return -EINVAL;
995}
996
997static int wsm_scan_complete_indication(struct cw1200_common *priv,
998 struct wsm_buf *buf)
999{
1000 struct wsm_scan_complete arg;
1001 arg.status = WSM_GET32(buf);
1002 arg.psm = WSM_GET8(buf);
1003 arg.num_channels = WSM_GET8(buf);
1004 cw1200_scan_complete_cb(priv, &arg);
1005
1006 return 0;
1007
1008underflow:
1009 return -EINVAL;
1010}
1011
1012static int wsm_join_complete_indication(struct cw1200_common *priv,
1013 struct wsm_buf *buf)
1014{
1015 struct wsm_join_complete arg;
1016 arg.status = WSM_GET32(buf);
1017 pr_debug("[WSM] Join complete indication, status: %d\n", arg.status);
1018 cw1200_join_complete_cb(priv, &arg);
1019
1020 return 0;
1021
1022underflow:
1023 return -EINVAL;
1024}
1025
1026static int wsm_find_complete_indication(struct cw1200_common *priv,
1027 struct wsm_buf *buf)
1028{
1029 pr_warn("Implement find_complete_indication\n");
1030 return 0;
1031}
1032
1033static int wsm_ba_timeout_indication(struct cw1200_common *priv,
1034 struct wsm_buf *buf)
1035{
1036 u32 dummy;
1037 u8 tid;
1038 u8 dummy2;
1039 u8 addr[ETH_ALEN];
1040
1041 dummy = WSM_GET32(buf);
1042 tid = WSM_GET8(buf);
1043 dummy2 = WSM_GET8(buf);
1044 WSM_GET(buf, addr, ETH_ALEN);
1045
1046 pr_info("BlockACK timeout, tid %d, addr %pM\n",
1047 tid, addr);
1048
1049 return 0;
1050
1051underflow:
1052 return -EINVAL;
1053}
1054
1055static int wsm_suspend_resume_indication(struct cw1200_common *priv,
1056 int link_id, struct wsm_buf *buf)
1057{
1058 u32 flags;
1059 struct wsm_suspend_resume arg;
1060
1061 flags = WSM_GET32(buf);
1062 arg.link_id = link_id;
1063 arg.stop = !(flags & 1);
1064 arg.multicast = !!(flags & 8);
1065 arg.queue = (flags >> 1) & 3;
1066
1067 cw1200_suspend_resume(priv, &arg);
1068
1069 return 0;
1070
1071underflow:
1072 return -EINVAL;
1073}
1074
1075
1076/* ******************************************************************** */
1077/* WSM TX */
1078
1079static int wsm_cmd_send(struct cw1200_common *priv,
1080 struct wsm_buf *buf,
1081 void *arg, u16 cmd, long tmo)
1082{
1083 size_t buf_len = buf->data - buf->begin;
1084 int ret;
1085
1086 /* Don't bother if we're dead. */
1087 if (priv->bh_error) {
1088 ret = 0;
1089 goto done;
1090 }
1091
1092 /* Block until the cmd buffer is completed. Tortuous. */
1093 spin_lock(&priv->wsm_cmd.lock);
1094 while (!priv->wsm_cmd.done) {
1095 spin_unlock(&priv->wsm_cmd.lock);
1096 spin_lock(&priv->wsm_cmd.lock);
1097 }
1098 priv->wsm_cmd.done = 0;
1099 spin_unlock(&priv->wsm_cmd.lock);
1100
1101 if (cmd == WSM_WRITE_MIB_REQ_ID ||
1102 cmd == WSM_READ_MIB_REQ_ID)
1103 pr_debug("[WSM] >>> 0x%.4X [MIB: 0x%.4X] (%zu)\n",
1104 cmd, __le16_to_cpu(((__le16 *)buf->begin)[2]),
1105 buf_len);
1106 else
1107 pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len);
1108
1109 /*
1110 * Due to buggy SPI on CW1200, we need to
1111 * pad the message by a few bytes to ensure
1112 * that it's completely received.
1113 */
1114#ifdef CONFIG_CW1200_ETF
1115 if (!etf_mode)
1116#endif
1117 buf_len += 4;
1118
1119 /* Fill HI message header */
1120 /* BH will add sequence number */
1121 ((__le16 *)buf->begin)[0] = __cpu_to_le16(buf_len);
1122 ((__le16 *)buf->begin)[1] = __cpu_to_le16(cmd);
1123
1124 spin_lock(&priv->wsm_cmd.lock);
1125 BUG_ON(priv->wsm_cmd.ptr);
1126 priv->wsm_cmd.ptr = buf->begin;
1127 priv->wsm_cmd.len = buf_len;
1128 priv->wsm_cmd.arg = arg;
1129 priv->wsm_cmd.cmd = cmd;
1130 spin_unlock(&priv->wsm_cmd.lock);
1131
1132 cw1200_bh_wakeup(priv);
1133
1134 /* Wait for command completion */
1135 ret = wait_event_timeout(priv->wsm_cmd_wq,
1136 priv->wsm_cmd.done, tmo);
1137
1138 if (!ret && !priv->wsm_cmd.done) {
1139 spin_lock(&priv->wsm_cmd.lock);
1140 priv->wsm_cmd.done = 1;
1141 priv->wsm_cmd.ptr = NULL;
1142 spin_unlock(&priv->wsm_cmd.lock);
1143 if (priv->bh_error) {
1144 /* Return ok to help system cleanup */
1145 ret = 0;
1146 } else {
1147 pr_err("CMD req (0x%04x) stuck in firmware, killing BH\n", priv->wsm_cmd.cmd);
1148 print_hex_dump_bytes("REQDUMP: ", DUMP_PREFIX_NONE,
1149 buf->begin, buf_len);
1150 pr_err("Outstanding outgoing frames: %d\n", priv->hw_bufs_used);
1151
1152 /* Kill BH thread to report the error to the top layer. */
1153 atomic_add(1, &priv->bh_term);
1154 wake_up(&priv->bh_wq);
1155 ret = -ETIMEDOUT;
1156 }
1157 } else {
1158 spin_lock(&priv->wsm_cmd.lock);
1159 BUG_ON(!priv->wsm_cmd.done);
1160 ret = priv->wsm_cmd.ret;
1161 spin_unlock(&priv->wsm_cmd.lock);
1162 }
1163done:
1164 wsm_buf_reset(buf);
1165 return ret;
1166}
1167
1168#ifdef CONFIG_CW1200_ETF
1169int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len)
1170{
1171 struct wsm_buf *buf = &priv->wsm_cmd_buf;
1172 int ret;
1173
1174 u16 *cmd = (u16 *)(data + 2);
1175
1176 wsm_cmd_lock(priv);
1177
1178 WSM_PUT(buf, data + 4, len - 4); /* Skip over header (u16+u16) */
1179
1180 ret = wsm_cmd_send(priv, buf, NULL, __le16_to_cpu(*cmd), WSM_CMD_TIMEOUT);
1181
1182 wsm_cmd_unlock(priv);
1183 return ret;
1184
1185nomem:
1186 wsm_cmd_unlock(priv);
1187 return -ENOMEM;
1188}
1189#endif /* CONFIG_CW1200_ETF */
1190
1191/* ******************************************************************** */
1192/* WSM TX port control */
1193
1194void wsm_lock_tx(struct cw1200_common *priv)
1195{
1196 wsm_cmd_lock(priv);
1197 if (atomic_add_return(1, &priv->tx_lock) == 1) {
1198 if (wsm_flush_tx(priv))
1199 pr_debug("[WSM] TX is locked.\n");
1200 }
1201 wsm_cmd_unlock(priv);
1202}
1203
1204void wsm_lock_tx_async(struct cw1200_common *priv)
1205{
1206 if (atomic_add_return(1, &priv->tx_lock) == 1)
1207 pr_debug("[WSM] TX is locked (async).\n");
1208}
1209
1210bool wsm_flush_tx(struct cw1200_common *priv)
1211{
1212 unsigned long timestamp = jiffies;
1213 bool pending = false;
1214 long timeout;
1215 int i;
1216
1217 /* Flush must be called with TX lock held. */
1218 BUG_ON(!atomic_read(&priv->tx_lock));
1219
1220 /* First check if we really need to do something.
1221 * It is safe to use unprotected access, as hw_bufs_used
1222 * can only decrements.
1223 */
1224 if (!priv->hw_bufs_used)
1225 return true;
1226
1227 if (priv->bh_error) {
1228 /* In case of failure do not wait for magic. */
1229 pr_err("[WSM] Fatal error occured, will not flush TX.\n");
1230 return false;
1231 } else {
1232 /* Get a timestamp of "oldest" frame */
1233 for (i = 0; i < 4; ++i)
1234 pending |= cw1200_queue_get_xmit_timestamp(
1235 &priv->tx_queue[i],
1236 &timestamp, 0xffffffff);
1237 /* If there's nothing pending, we're good */
1238 if (!pending)
1239 return true;
1240
1241 timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT - jiffies;
1242 if (timeout < 0 || wait_event_timeout(priv->bh_evt_wq,
1243 !priv->hw_bufs_used,
1244 timeout) <= 0) {
1245 /* Hmmm... Not good. Frame had stuck in firmware. */
1246 priv->bh_error = 1;
1247 wiphy_err(priv->hw->wiphy, "[WSM] TX Frames (%d) stuck in firmware, killing BH\n", priv->hw_bufs_used);
1248 wake_up(&priv->bh_wq);
1249 return false;
1250 }
1251
1252 /* Ok, everything is flushed. */
1253 return true;
1254 }
1255}
1256
1257void wsm_unlock_tx(struct cw1200_common *priv)
1258{
1259 int tx_lock;
1260 tx_lock = atomic_sub_return(1, &priv->tx_lock);
1261 BUG_ON(tx_lock < 0);
1262
1263 if (tx_lock == 0) {
1264 if (!priv->bh_error)
1265 cw1200_bh_wakeup(priv);
1266 pr_debug("[WSM] TX is unlocked.\n");
1267 }
1268}
1269
1270/* ******************************************************************** */
1271/* WSM RX */
1272
1273int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len)
1274{
1275 struct wsm_buf buf;
1276 u32 reason;
1277 u32 reg[18];
1278 char fname[48];
1279 unsigned int i;
1280
1281 static const char * const reason_str[] = {
1282 "undefined instruction",
1283 "prefetch abort",
1284 "data abort",
1285 "unknown error",
1286 };
1287
1288 buf.begin = buf.data = data;
1289 buf.end = &buf.begin[len];
1290
1291 reason = WSM_GET32(&buf);
1292 for (i = 0; i < ARRAY_SIZE(reg); ++i)
1293 reg[i] = WSM_GET32(&buf);
1294 WSM_GET(&buf, fname, sizeof(fname));
1295
1296 if (reason < 4)
1297 wiphy_err(priv->hw->wiphy,
1298 "Firmware exception: %s.\n",
1299 reason_str[reason]);
1300 else
1301 wiphy_err(priv->hw->wiphy,
1302 "Firmware assert at %.*s, line %d\n",
1303 (int) sizeof(fname), fname, reg[1]);
1304
1305 for (i = 0; i < 12; i += 4)
1306 wiphy_err(priv->hw->wiphy,
1307 "R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X,\n",
1308 i + 0, reg[i + 0], i + 1, reg[i + 1],
1309 i + 2, reg[i + 2], i + 3, reg[i + 3]);
1310 wiphy_err(priv->hw->wiphy,
1311 "R12: 0x%.8X, SP: 0x%.8X, LR: 0x%.8X, PC: 0x%.8X,\n",
1312 reg[i + 0], reg[i + 1], reg[i + 2], reg[i + 3]);
1313 i += 4;
1314 wiphy_err(priv->hw->wiphy,
1315 "CPSR: 0x%.8X, SPSR: 0x%.8X\n",
1316 reg[i + 0], reg[i + 1]);
1317
1318 print_hex_dump_bytes("R1: ", DUMP_PREFIX_NONE,
1319 fname, sizeof(fname));
1320 return 0;
1321
1322underflow:
1323 wiphy_err(priv->hw->wiphy, "Firmware exception.\n");
1324 print_hex_dump_bytes("Exception: ", DUMP_PREFIX_NONE,
1325 data, len);
1326 return -EINVAL;
1327}
1328
1329int wsm_handle_rx(struct cw1200_common *priv, u16 id,
1330 struct wsm_hdr *wsm, struct sk_buff **skb_p)
1331{
1332 int ret = 0;
1333 struct wsm_buf wsm_buf;
1334 int link_id = (id >> 6) & 0x0F;
1335
1336 /* Strip link id. */
1337 id &= ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
1338
1339 wsm_buf.begin = (u8 *)&wsm[0];
1340 wsm_buf.data = (u8 *)&wsm[1];
1341 wsm_buf.end = &wsm_buf.begin[__le32_to_cpu(wsm->len)];
1342
1343 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
1344 wsm_buf.end - wsm_buf.begin);
1345
1346#ifdef CONFIG_CW1200_ETF
1347 if (etf_mode) {
1348 struct sk_buff *skb = alloc_skb(wsm_buf.end - wsm_buf.begin, GFP_KERNEL);
1349
1350 /* Strip out Sequence num before passing up */
1351 wsm->id = __le16_to_cpu(wsm->id);
1352 wsm->id &= 0x0FFF;
1353 wsm->id = __cpu_to_le16(wsm->id);
1354
1355 memcpy(skb_put(skb, wsm_buf.end - wsm_buf.begin),
1356 wsm_buf.begin,
1357 wsm_buf.end - wsm_buf.begin);
1358 skb_queue_tail(&priv->etf_q, skb);
1359
1360 /* Special case for startup */
1361 if (id == WSM_STARTUP_IND_ID) {
1362 wsm_startup_indication(priv, &wsm_buf);
1363 } else if (id & 0x0400) {
1364 spin_lock(&priv->wsm_cmd.lock);
1365 priv->wsm_cmd.done = 1;
1366 spin_unlock(&priv->wsm_cmd.lock);
1367 wake_up(&priv->wsm_cmd_wq);
1368 }
1369
1370 goto out;
1371 }
1372#endif
1373
1374 if (id == WSM_TX_CONFIRM_IND_ID) {
1375 ret = wsm_tx_confirm(priv, &wsm_buf, link_id);
1376 } else if (id == WSM_MULTI_TX_CONFIRM_ID) {
1377 ret = wsm_multi_tx_confirm(priv, &wsm_buf, link_id);
1378 } else if (id & 0x0400) {
1379 void *wsm_arg;
1380 u16 wsm_cmd;
1381
1382 /* Do not trust FW too much. Protection against repeated
1383 * response and race condition removal (see above).
1384 */
1385 spin_lock(&priv->wsm_cmd.lock);
1386 wsm_arg = priv->wsm_cmd.arg;
1387 wsm_cmd = priv->wsm_cmd.cmd &
1388 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
1389 priv->wsm_cmd.cmd = 0xFFFF;
1390 spin_unlock(&priv->wsm_cmd.lock);
1391
1392 if (WARN_ON((id & ~0x0400) != wsm_cmd)) {
1393 /* Note that any non-zero is a fatal retcode. */
1394 ret = -EINVAL;
1395 goto out;
1396 }
1397
1398 /* Note that wsm_arg can be NULL in case of timeout in
1399 * wsm_cmd_send().
1400 */
1401
1402 switch (id) {
1403 case WSM_READ_MIB_RESP_ID:
1404 if (wsm_arg)
1405 ret = wsm_read_mib_confirm(priv, wsm_arg,
1406 &wsm_buf);
1407 break;
1408 case WSM_WRITE_MIB_RESP_ID:
1409 if (wsm_arg)
1410 ret = wsm_write_mib_confirm(priv, wsm_arg,
1411 &wsm_buf);
1412 break;
1413 case WSM_START_SCAN_RESP_ID:
1414 if (wsm_arg)
1415 ret = wsm_scan_started(priv, wsm_arg, &wsm_buf);
1416 break;
1417 case WSM_CONFIGURATION_RESP_ID:
1418 if (wsm_arg)
1419 ret = wsm_configuration_confirm(priv, wsm_arg,
1420 &wsm_buf);
1421 break;
1422 case WSM_JOIN_RESP_ID:
1423 if (wsm_arg)
1424 ret = wsm_join_confirm(priv, wsm_arg, &wsm_buf);
1425 break;
1426 case WSM_STOP_SCAN_RESP_ID:
1427 case WSM_RESET_RESP_ID:
1428 case WSM_ADD_KEY_RESP_ID:
1429 case WSM_REMOVE_KEY_RESP_ID:
1430 case WSM_SET_PM_RESP_ID:
1431 case WSM_SET_BSS_PARAMS_RESP_ID:
1432 case 0x0412: /* set_tx_queue_params */
1433 case WSM_EDCA_PARAMS_RESP_ID:
1434 case WSM_SWITCH_CHANNEL_RESP_ID:
1435 case WSM_START_RESP_ID:
1436 case WSM_BEACON_TRANSMIT_RESP_ID:
1437 case 0x0419: /* start_find */
1438 case 0x041A: /* stop_find */
1439 case 0x041B: /* update_ie */
1440 case 0x041C: /* map_link */
1441 WARN_ON(wsm_arg != NULL);
1442 ret = wsm_generic_confirm(priv, wsm_arg, &wsm_buf);
1443 if (ret) {
1444 wiphy_warn(priv->hw->wiphy,
1445 "wsm_generic_confirm failed for request 0x%04x.\n",
1446 id & ~0x0400);
1447
1448 /* often 0x407 and 0x410 occur, this means we're dead.. */
1449 if (priv->join_status >= CW1200_JOIN_STATUS_JOINING) {
1450 wsm_lock_tx(priv);
1451 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1452 wsm_unlock_tx(priv);
1453 }
1454 }
1455 break;
1456 default:
1457 wiphy_warn(priv->hw->wiphy,
1458 "Unrecognized confirmation 0x%04x\n",
1459 id & ~0x0400);
1460 }
1461
1462 spin_lock(&priv->wsm_cmd.lock);
1463 priv->wsm_cmd.ret = ret;
1464 priv->wsm_cmd.done = 1;
1465 spin_unlock(&priv->wsm_cmd.lock);
1466
1467 ret = 0; /* Error response from device should ne stop BH. */
1468
1469 wake_up(&priv->wsm_cmd_wq);
1470 } else if (id & 0x0800) {
1471 switch (id) {
1472 case WSM_STARTUP_IND_ID:
1473 ret = wsm_startup_indication(priv, &wsm_buf);
1474 break;
1475 case WSM_RECEIVE_IND_ID:
1476 ret = wsm_receive_indication(priv, link_id,
1477 &wsm_buf, skb_p);
1478 break;
1479 case 0x0805:
1480 ret = wsm_event_indication(priv, &wsm_buf);
1481 break;
1482 case WSM_SCAN_COMPLETE_IND_ID:
1483 ret = wsm_scan_complete_indication(priv, &wsm_buf);
1484 break;
1485 case 0x0808:
1486 ret = wsm_ba_timeout_indication(priv, &wsm_buf);
1487 break;
1488 case 0x0809:
1489 ret = wsm_set_pm_indication(priv, &wsm_buf);
1490 break;
1491 case 0x080A:
1492 ret = wsm_channel_switch_indication(priv, &wsm_buf);
1493 break;
1494 case 0x080B:
1495 ret = wsm_find_complete_indication(priv, &wsm_buf);
1496 break;
1497 case 0x080C:
1498 ret = wsm_suspend_resume_indication(priv,
1499 link_id, &wsm_buf);
1500 break;
1501 case 0x080F:
1502 ret = wsm_join_complete_indication(priv, &wsm_buf);
1503 break;
1504 default:
1505 pr_warn("Unrecognised WSM ID %04x\n", id);
1506 }
1507 } else {
1508 WARN_ON(1);
1509 ret = -EINVAL;
1510 }
1511out:
1512 return ret;
1513}
1514
1515static bool wsm_handle_tx_data(struct cw1200_common *priv,
1516 struct wsm_tx *wsm,
1517 const struct ieee80211_tx_info *tx_info,
1518 const struct cw1200_txpriv *txpriv,
1519 struct cw1200_queue *queue)
1520{
1521 bool handled = false;
1522 const struct ieee80211_hdr *frame =
1523 (struct ieee80211_hdr *)&((u8 *)wsm)[txpriv->offset];
1524 __le16 fctl = frame->frame_control;
1525 enum {
1526 do_probe,
1527 do_drop,
1528 do_wep,
1529 do_tx,
1530 } action = do_tx;
1531
1532 switch (priv->mode) {
1533 case NL80211_IFTYPE_STATION:
1534 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
1535 action = do_tx;
1536 else if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA)
1537 action = do_drop;
1538 break;
1539 case NL80211_IFTYPE_AP:
1540 if (!priv->join_status) {
1541 action = do_drop;
1542 } else if (!(BIT(txpriv->raw_link_id) &
1543 (BIT(0) | priv->link_id_map))) {
1544 wiphy_warn(priv->hw->wiphy,
1545 "A frame with expired link id is dropped.\n");
1546 action = do_drop;
1547 }
1548 if (cw1200_queue_get_generation(wsm->packet_id) >
1549 CW1200_MAX_REQUEUE_ATTEMPTS) {
1550 /* HACK!!! WSM324 firmware has tendency to requeue
1551 * multicast frames in a loop, causing performance
1552 * drop and high power consumption of the driver.
1553 * In this situation it is better just to drop
1554 * the problematic frame.
1555 */
1556 wiphy_warn(priv->hw->wiphy,
1557 "Too many attempts to requeue a frame; dropped.\n");
1558 action = do_drop;
1559 }
1560 break;
1561 case NL80211_IFTYPE_ADHOC:
1562 if (priv->join_status != CW1200_JOIN_STATUS_IBSS)
1563 action = do_drop;
1564 break;
1565 case NL80211_IFTYPE_MESH_POINT:
1566 action = do_tx; /* TODO: Test me! */
1567 break;
1568 case NL80211_IFTYPE_MONITOR:
1569 default:
1570 action = do_drop;
1571 break;
1572 }
1573
1574 if (action == do_tx) {
1575 if (ieee80211_is_nullfunc(fctl)) {
1576 spin_lock(&priv->bss_loss_lock);
1577 if (priv->bss_loss_state) {
1578 priv->bss_loss_confirm_id = wsm->packet_id;
1579 wsm->queue_id = WSM_QUEUE_VOICE;
1580 }
1581 spin_unlock(&priv->bss_loss_lock);
1582 } else if (ieee80211_is_probe_req(fctl)) {
1583 action = do_probe;
1584 } else if (ieee80211_is_deauth(fctl) &&
1585 priv->mode != NL80211_IFTYPE_AP) {
1586 pr_debug("[WSM] Issue unjoin command due to tx deauth.\n");
1587 wsm_lock_tx_async(priv);
1588 if (queue_work(priv->workqueue,
1589 &priv->unjoin_work) <= 0)
1590 wsm_unlock_tx(priv);
1591 } else if (ieee80211_has_protected(fctl) &&
1592 tx_info->control.hw_key &&
1593 tx_info->control.hw_key->keyidx != priv->wep_default_key_id &&
1594 (tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
1595 tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
1596 action = do_wep;
1597 }
1598 }
1599
1600 switch (action) {
1601 case do_probe:
1602 /* An interesting FW "feature". Device filters probe responses.
1603 * The easiest way to get it back is to convert
1604 * probe request into WSM start_scan command.
1605 */
1606 pr_debug("[WSM] Convert probe request to scan.\n");
1607 wsm_lock_tx_async(priv);
1608 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id);
1609 if (queue_delayed_work(priv->workqueue,
1610 &priv->scan.probe_work, 0) <= 0)
1611 wsm_unlock_tx(priv);
1612 handled = true;
1613 break;
1614 case do_drop:
1615 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl);
1616 BUG_ON(cw1200_queue_remove(queue,
1617 __le32_to_cpu(wsm->packet_id)));
1618 handled = true;
1619 break;
1620 case do_wep:
1621 pr_debug("[WSM] Issue set_default_wep_key.\n");
1622 wsm_lock_tx_async(priv);
1623 priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
1624 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id);
1625 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
1626 wsm_unlock_tx(priv);
1627 handled = true;
1628 break;
1629 case do_tx:
1630 pr_debug("[WSM] Transmit frame.\n");
1631 break;
1632 default:
1633 /* Do nothing */
1634 break;
1635 }
1636 return handled;
1637}
1638
1639static int cw1200_get_prio_queue(struct cw1200_common *priv,
1640 u32 link_id_map, int *total)
1641{
1642 static const int urgent = BIT(CW1200_LINK_ID_AFTER_DTIM) |
1643 BIT(CW1200_LINK_ID_UAPSD);
1644 struct wsm_edca_queue_params *edca;
1645 unsigned score, best = -1;
1646 int winner = -1;
1647 int queued;
1648 int i;
1649
1650 /* search for a winner using edca params */
1651 for (i = 0; i < 4; ++i) {
1652 queued = cw1200_queue_get_num_queued(&priv->tx_queue[i],
1653 link_id_map);
1654 if (!queued)
1655 continue;
1656 *total += queued;
1657 edca = &priv->edca.params[i];
1658 score = ((edca->aifns + edca->cwmin) << 16) +
1659 ((edca->cwmax - edca->cwmin) *
1660 (get_random_int() & 0xFFFF));
1661 if (score < best && (winner < 0 || i != 3)) {
1662 best = score;
1663 winner = i;
1664 }
1665 }
1666
1667 /* override winner if bursting */
1668 if (winner >= 0 && priv->tx_burst_idx >= 0 &&
1669 winner != priv->tx_burst_idx &&
1670 !cw1200_queue_get_num_queued(
1671 &priv->tx_queue[winner],
1672 link_id_map & urgent) &&
1673 cw1200_queue_get_num_queued(
1674 &priv->tx_queue[priv->tx_burst_idx],
1675 link_id_map))
1676 winner = priv->tx_burst_idx;
1677
1678 return winner;
1679}
1680
1681static int wsm_get_tx_queue_and_mask(struct cw1200_common *priv,
1682 struct cw1200_queue **queue_p,
1683 u32 *tx_allowed_mask_p,
1684 bool *more)
1685{
1686 int idx;
1687 u32 tx_allowed_mask;
1688 int total = 0;
1689
1690 /* Search for a queue with multicast frames buffered */
1691 if (priv->tx_multicast) {
1692 tx_allowed_mask = BIT(CW1200_LINK_ID_AFTER_DTIM);
1693 idx = cw1200_get_prio_queue(priv,
1694 tx_allowed_mask, &total);
1695 if (idx >= 0) {
1696 *more = total > 1;
1697 goto found;
1698 }
1699 }
1700
1701 /* Search for unicast traffic */
1702 tx_allowed_mask = ~priv->sta_asleep_mask;
1703 tx_allowed_mask |= BIT(CW1200_LINK_ID_UAPSD);
1704 if (priv->sta_asleep_mask) {
1705 tx_allowed_mask |= priv->pspoll_mask;
1706 tx_allowed_mask &= ~BIT(CW1200_LINK_ID_AFTER_DTIM);
1707 } else {
1708 tx_allowed_mask |= BIT(CW1200_LINK_ID_AFTER_DTIM);
1709 }
1710 idx = cw1200_get_prio_queue(priv,
1711 tx_allowed_mask, &total);
1712 if (idx < 0)
1713 return -ENOENT;
1714
1715found:
1716 *queue_p = &priv->tx_queue[idx];
1717 *tx_allowed_mask_p = tx_allowed_mask;
1718 return 0;
1719}
1720
1721int wsm_get_tx(struct cw1200_common *priv, u8 **data,
1722 size_t *tx_len, int *burst)
1723{
1724 struct wsm_tx *wsm = NULL;
1725 struct ieee80211_tx_info *tx_info;
1726 struct cw1200_queue *queue = NULL;
1727 int queue_num;
1728 u32 tx_allowed_mask = 0;
1729 const struct cw1200_txpriv *txpriv = NULL;
1730 int count = 0;
1731
1732 /* More is used only for broadcasts. */
1733 bool more = false;
1734
1735#ifdef CONFIG_CW1200_ITP
1736 count = cw1200_itp_get_tx(priv, data, tx_len, burst);
1737 if (count)
1738 return count;
1739#endif
1740
1741 if (priv->wsm_cmd.ptr) { /* CMD request */
1742 ++count;
1743 spin_lock(&priv->wsm_cmd.lock);
1744 BUG_ON(!priv->wsm_cmd.ptr);
1745 *data = priv->wsm_cmd.ptr;
1746 *tx_len = priv->wsm_cmd.len;
1747 *burst = 1;
1748 spin_unlock(&priv->wsm_cmd.lock);
1749 } else {
1750 for (;;) {
1751 int ret;
1752
1753 if (atomic_add_return(0, &priv->tx_lock))
1754 break;
1755
1756 spin_lock_bh(&priv->ps_state_lock);
1757
1758 ret = wsm_get_tx_queue_and_mask(priv, &queue,
1759 &tx_allowed_mask, &more);
1760 queue_num = queue - priv->tx_queue;
1761
1762 if (priv->buffered_multicasts &&
1763 (ret || !more) &&
1764 (priv->tx_multicast || !priv->sta_asleep_mask)) {
1765 priv->buffered_multicasts = false;
1766 if (priv->tx_multicast) {
1767 priv->tx_multicast = false;
1768 queue_work(priv->workqueue,
1769 &priv->multicast_stop_work);
1770 }
1771 }
1772
1773 spin_unlock_bh(&priv->ps_state_lock);
1774
1775 if (ret)
1776 break;
1777
1778 if (cw1200_queue_get(queue,
1779 tx_allowed_mask,
1780 &wsm, &tx_info, &txpriv))
1781 continue;
1782
1783 if (wsm_handle_tx_data(priv, wsm,
1784 tx_info, txpriv, queue))
1785 continue; /* Handled by WSM */
1786
1787 wsm->hdr.id &= __cpu_to_le16(
1788 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX));
1789 wsm->hdr.id |= cpu_to_le16(
1790 WSM_TX_LINK_ID(txpriv->raw_link_id));
1791 priv->pspoll_mask &= ~BIT(txpriv->raw_link_id);
1792
1793 *data = (u8 *)wsm;
1794 *tx_len = __le16_to_cpu(wsm->hdr.len);
1795
1796 /* allow bursting if txop is set */
1797 if (priv->edca.params[queue_num].txop_limit)
1798 *burst = min(*burst,
1799 (int)cw1200_queue_get_num_queued(queue, tx_allowed_mask) + 1);
1800 else
1801 *burst = 1;
1802
1803 /* store index of bursting queue */
1804 if (*burst > 1)
1805 priv->tx_burst_idx = queue_num;
1806 else
1807 priv->tx_burst_idx = -1;
1808
1809 if (more) {
1810 struct ieee80211_hdr *hdr =
1811 (struct ieee80211_hdr *)
1812 &((u8 *)wsm)[txpriv->offset];
1813 /* more buffered multicast/broadcast frames
1814 * ==> set MoreData flag in IEEE 802.11 header
1815 * to inform PS STAs
1816 */
1817 hdr->frame_control |=
1818 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1819 }
1820
1821 pr_debug("[WSM] >>> 0x%.4X (%zu) %p %c\n",
1822 0x0004, *tx_len, *data,
1823 wsm->more ? 'M' : ' ');
1824 ++count;
1825 break;
1826 }
1827 }
1828
1829 return count;
1830}
1831
1832void wsm_txed(struct cw1200_common *priv, u8 *data)
1833{
1834 if (data == priv->wsm_cmd.ptr) {
1835 spin_lock(&priv->wsm_cmd.lock);
1836 priv->wsm_cmd.ptr = NULL;
1837 spin_unlock(&priv->wsm_cmd.lock);
1838 }
1839}
1840
1841/* ******************************************************************** */
1842/* WSM buffer */
1843
1844void wsm_buf_init(struct wsm_buf *buf)
1845{
1846 BUG_ON(buf->begin);
1847 buf->begin = kmalloc(FWLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
1848 buf->end = buf->begin ? &buf->begin[FWLOAD_BLOCK_SIZE] : buf->begin;
1849 wsm_buf_reset(buf);
1850}
1851
1852void wsm_buf_deinit(struct wsm_buf *buf)
1853{
1854 kfree(buf->begin);
1855 buf->begin = buf->data = buf->end = NULL;
1856}
1857
1858static void wsm_buf_reset(struct wsm_buf *buf)
1859{
1860 if (buf->begin) {
1861 buf->data = &buf->begin[4];
1862 *(u32 *)buf->begin = 0;
1863 } else {
1864 buf->data = buf->begin;
1865 }
1866}
1867
1868static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size)
1869{
1870 size_t pos = buf->data - buf->begin;
1871 size_t size = pos + extra_size;
1872
1873 size = round_up(size, FWLOAD_BLOCK_SIZE);
1874
1875 buf->begin = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA);
1876 if (buf->begin) {
1877 buf->data = &buf->begin[pos];
1878 buf->end = &buf->begin[size];
1879 return 0;
1880 } else {
1881 buf->end = buf->data = buf->begin;
1882 return -ENOMEM;
1883 }
1884}
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
new file mode 100644
index 000000000000..8d902d6a7dc4
--- /dev/null
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -0,0 +1,1879 @@
1/*
2 * WSM host interface (HI) interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on CW1200 UMAC WSM API, which is
8 * Copyright (C) ST-Ericsson SA 2010
9 * Author: Stewart Mathers <stewart.mathers@stericsson.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef CW1200_WSM_H_INCLUDED
17#define CW1200_WSM_H_INCLUDED
18
19#include <linux/spinlock.h>
20
21struct cw1200_common;
22
23/* Bands */
24/* Radio band 2.412 -2.484 GHz. */
25#define WSM_PHY_BAND_2_4G (0)
26
27/* Radio band 4.9375-5.8250 GHz. */
28#define WSM_PHY_BAND_5G (1)
29
30/* Transmit rates */
31/* 1 Mbps ERP-DSSS */
32#define WSM_TRANSMIT_RATE_1 (0)
33
34/* 2 Mbps ERP-DSSS */
35#define WSM_TRANSMIT_RATE_2 (1)
36
37/* 5.5 Mbps ERP-CCK */
38#define WSM_TRANSMIT_RATE_5 (2)
39
40/* 11 Mbps ERP-CCK */
41#define WSM_TRANSMIT_RATE_11 (3)
42
43/* 22 Mbps ERP-PBCC (Not supported) */
44/* #define WSM_TRANSMIT_RATE_22 (4) */
45
46/* 33 Mbps ERP-PBCC (Not supported) */
47/* #define WSM_TRANSMIT_RATE_33 (5) */
48
49/* 6 Mbps (3 Mbps) ERP-OFDM, BPSK coding rate 1/2 */
50#define WSM_TRANSMIT_RATE_6 (6)
51
52/* 9 Mbps (4.5 Mbps) ERP-OFDM, BPSK coding rate 3/4 */
53#define WSM_TRANSMIT_RATE_9 (7)
54
55/* 12 Mbps (6 Mbps) ERP-OFDM, QPSK coding rate 1/2 */
56#define WSM_TRANSMIT_RATE_12 (8)
57
58/* 18 Mbps (9 Mbps) ERP-OFDM, QPSK coding rate 3/4 */
59#define WSM_TRANSMIT_RATE_18 (9)
60
61/* 24 Mbps (12 Mbps) ERP-OFDM, 16QAM coding rate 1/2 */
62#define WSM_TRANSMIT_RATE_24 (10)
63
64/* 36 Mbps (18 Mbps) ERP-OFDM, 16QAM coding rate 3/4 */
65#define WSM_TRANSMIT_RATE_36 (11)
66
67/* 48 Mbps (24 Mbps) ERP-OFDM, 64QAM coding rate 1/2 */
68#define WSM_TRANSMIT_RATE_48 (12)
69
70/* 54 Mbps (27 Mbps) ERP-OFDM, 64QAM coding rate 3/4 */
71#define WSM_TRANSMIT_RATE_54 (13)
72
73/* 6.5 Mbps HT-OFDM, BPSK coding rate 1/2 */
74#define WSM_TRANSMIT_RATE_HT_6 (14)
75
76/* 13 Mbps HT-OFDM, QPSK coding rate 1/2 */
77#define WSM_TRANSMIT_RATE_HT_13 (15)
78
79/* 19.5 Mbps HT-OFDM, QPSK coding rate 3/4 */
80#define WSM_TRANSMIT_RATE_HT_19 (16)
81
82/* 26 Mbps HT-OFDM, 16QAM coding rate 1/2 */
83#define WSM_TRANSMIT_RATE_HT_26 (17)
84
85/* 39 Mbps HT-OFDM, 16QAM coding rate 3/4 */
86#define WSM_TRANSMIT_RATE_HT_39 (18)
87
88/* 52 Mbps HT-OFDM, 64QAM coding rate 2/3 */
89#define WSM_TRANSMIT_RATE_HT_52 (19)
90
91/* 58.5 Mbps HT-OFDM, 64QAM coding rate 3/4 */
92#define WSM_TRANSMIT_RATE_HT_58 (20)
93
94/* 65 Mbps HT-OFDM, 64QAM coding rate 5/6 */
95#define WSM_TRANSMIT_RATE_HT_65 (21)
96
97/* Scan types */
98/* Foreground scan */
99#define WSM_SCAN_TYPE_FOREGROUND (0)
100
101/* Background scan */
102#define WSM_SCAN_TYPE_BACKGROUND (1)
103
104/* Auto scan */
105#define WSM_SCAN_TYPE_AUTO (2)
106
107/* Scan flags */
108/* Forced background scan means if the station cannot */
109/* enter the power-save mode, it shall force to perform a */
110/* background scan. Only valid when ScanType is */
111/* background scan. */
112#define WSM_SCAN_FLAG_FORCE_BACKGROUND (BIT(0))
113
114/* The WLAN device scans one channel at a time so */
115/* that disturbance to the data traffic is minimized. */
116#define WSM_SCAN_FLAG_SPLIT_METHOD (BIT(1))
117
118/* Preamble Type. Long if not set. */
119#define WSM_SCAN_FLAG_SHORT_PREAMBLE (BIT(2))
120
121/* 11n Tx Mode. Mixed if not set. */
122#define WSM_SCAN_FLAG_11N_GREENFIELD (BIT(3))
123
124/* Scan constraints */
125/* Maximum number of channels to be scanned. */
126#define WSM_SCAN_MAX_NUM_OF_CHANNELS (48)
127
128/* The maximum number of SSIDs that the device can scan for. */
129#define WSM_SCAN_MAX_NUM_OF_SSIDS (2)
130
131/* Power management modes */
132/* 802.11 Active mode */
133#define WSM_PSM_ACTIVE (0)
134
135/* 802.11 PS mode */
136#define WSM_PSM_PS BIT(0)
137
138/* Fast Power Save bit */
139#define WSM_PSM_FAST_PS_FLAG BIT(7)
140
141/* Dynamic aka Fast power save */
142#define WSM_PSM_FAST_PS (BIT(0) | BIT(7))
143
144/* Undetermined */
145/* Note : Undetermined status is reported when the */
146/* NULL data frame used to advertise the PM mode to */
147/* the AP at Pre or Post Background Scan is not Acknowledged */
148#define WSM_PSM_UNKNOWN BIT(1)
149
150/* Queue IDs */
151/* best effort/legacy */
152#define WSM_QUEUE_BEST_EFFORT (0)
153
154/* background */
155#define WSM_QUEUE_BACKGROUND (1)
156
157/* video */
158#define WSM_QUEUE_VIDEO (2)
159
160/* voice */
161#define WSM_QUEUE_VOICE (3)
162
163/* HT TX parameters */
164/* Non-HT */
165#define WSM_HT_TX_NON_HT (0)
166
167/* Mixed format */
168#define WSM_HT_TX_MIXED (1)
169
170/* Greenfield format */
171#define WSM_HT_TX_GREENFIELD (2)
172
173/* STBC allowed */
174#define WSM_HT_TX_STBC (BIT(7))
175
176/* EPTA prioirty flags for BT Coex */
177/* default epta priority */
178#define WSM_EPTA_PRIORITY_DEFAULT 4
179/* use for normal data */
180#define WSM_EPTA_PRIORITY_DATA 4
181/* use for connect/disconnect/roaming*/
182#define WSM_EPTA_PRIORITY_MGT 5
183/* use for action frames */
184#define WSM_EPTA_PRIORITY_ACTION 5
185/* use for AC_VI data */
186#define WSM_EPTA_PRIORITY_VIDEO 5
187/* use for AC_VO data */
188#define WSM_EPTA_PRIORITY_VOICE 6
189/* use for EAPOL exchange */
190#define WSM_EPTA_PRIORITY_EAPOL 7
191
192/* TX status */
193/* Frame was sent aggregated */
194/* Only valid for WSM_SUCCESS status. */
195#define WSM_TX_STATUS_AGGREGATION (BIT(0))
196
197/* Host should requeue this frame later. */
198/* Valid only when status is WSM_REQUEUE. */
199#define WSM_TX_STATUS_REQUEUE (BIT(1))
200
201/* Normal Ack */
202#define WSM_TX_STATUS_NORMAL_ACK (0<<2)
203
204/* No Ack */
205#define WSM_TX_STATUS_NO_ACK (1<<2)
206
207/* No explicit acknowledgement */
208#define WSM_TX_STATUS_NO_EXPLICIT_ACK (2<<2)
209
210/* Block Ack */
211/* Only valid for WSM_SUCCESS status. */
212#define WSM_TX_STATUS_BLOCK_ACK (3<<2)
213
214/* RX status */
215/* Unencrypted */
216#define WSM_RX_STATUS_UNENCRYPTED (0<<0)
217
218/* WEP */
219#define WSM_RX_STATUS_WEP (1<<0)
220
221/* TKIP */
222#define WSM_RX_STATUS_TKIP (2<<0)
223
224/* AES */
225#define WSM_RX_STATUS_AES (3<<0)
226
227/* WAPI */
228#define WSM_RX_STATUS_WAPI (4<<0)
229
230/* Macro to fetch encryption subfield. */
231#define WSM_RX_STATUS_ENCRYPTION(status) ((status) & 0x07)
232
233/* Frame was part of an aggregation */
234#define WSM_RX_STATUS_AGGREGATE (BIT(3))
235
236/* Frame was first in the aggregation */
237#define WSM_RX_STATUS_AGGREGATE_FIRST (BIT(4))
238
239/* Frame was last in the aggregation */
240#define WSM_RX_STATUS_AGGREGATE_LAST (BIT(5))
241
242/* Indicates a defragmented frame */
243#define WSM_RX_STATUS_DEFRAGMENTED (BIT(6))
244
245/* Indicates a Beacon frame */
246#define WSM_RX_STATUS_BEACON (BIT(7))
247
248/* Indicates STA bit beacon TIM field */
249#define WSM_RX_STATUS_TIM (BIT(8))
250
251/* Indicates Beacon frame's virtual bitmap contains multicast bit */
252#define WSM_RX_STATUS_MULTICAST (BIT(9))
253
254/* Indicates frame contains a matching SSID */
255#define WSM_RX_STATUS_MATCHING_SSID (BIT(10))
256
257/* Indicates frame contains a matching BSSI */
258#define WSM_RX_STATUS_MATCHING_BSSI (BIT(11))
259
260/* Indicates More bit set in Framectl field */
261#define WSM_RX_STATUS_MORE_DATA (BIT(12))
262
263/* Indicates frame received during a measurement process */
264#define WSM_RX_STATUS_MEASUREMENT (BIT(13))
265
266/* Indicates frame received as an HT packet */
267#define WSM_RX_STATUS_HT (BIT(14))
268
269/* Indicates frame received with STBC */
270#define WSM_RX_STATUS_STBC (BIT(15))
271
272/* Indicates Address 1 field matches dot11StationId */
273#define WSM_RX_STATUS_ADDRESS1 (BIT(16))
274
275/* Indicates Group address present in the Address 1 field */
276#define WSM_RX_STATUS_GROUP (BIT(17))
277
278/* Indicates Broadcast address present in the Address 1 field */
279#define WSM_RX_STATUS_BROADCAST (BIT(18))
280
281/* Indicates group key used with encrypted frames */
282#define WSM_RX_STATUS_GROUP_KEY (BIT(19))
283
284/* Macro to fetch encryption key index. */
285#define WSM_RX_STATUS_KEY_IDX(status) (((status >> 20)) & 0x0F)
286
287/* Indicates TSF inclusion after 802.11 frame body */
288#define WSM_RX_STATUS_TSF_INCLUDED (BIT(24))
289
290/* Frame Control field starts at Frame offset + 2 */
291#define WSM_TX_2BYTES_SHIFT (BIT(7))
292
293/* Join mode */
294/* IBSS */
295#define WSM_JOIN_MODE_IBSS (0)
296
297/* BSS */
298#define WSM_JOIN_MODE_BSS (1)
299
300/* PLCP preamble type */
301/* For long preamble */
302#define WSM_JOIN_PREAMBLE_LONG (0)
303
304/* For short preamble (Long for 1Mbps) */
305#define WSM_JOIN_PREAMBLE_SHORT (1)
306
307/* For short preamble (Long for 1 and 2Mbps) */
308#define WSM_JOIN_PREAMBLE_SHORT_2 (2)
309
310/* Join flags */
311/* Unsynchronized */
312#define WSM_JOIN_FLAGS_UNSYNCRONIZED BIT(0)
313/* The BSS owner is a P2P GO */
314#define WSM_JOIN_FLAGS_P2P_GO BIT(1)
315/* Force to join BSS with the BSSID and the
316 * SSID specified without waiting for beacons. The
317 * ProbeForJoin parameter is ignored. */
318#define WSM_JOIN_FLAGS_FORCE BIT(2)
319/* Give probe request/response higher
320 * priority over the BT traffic */
321#define WSM_JOIN_FLAGS_PRIO BIT(3)
322/* Issue immediate join confirmation and use
323 * join complete to notify about completion */
324#define WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND BIT(5)
325
326/* Key types */
327#define WSM_KEY_TYPE_WEP_DEFAULT (0)
328#define WSM_KEY_TYPE_WEP_PAIRWISE (1)
329#define WSM_KEY_TYPE_TKIP_GROUP (2)
330#define WSM_KEY_TYPE_TKIP_PAIRWISE (3)
331#define WSM_KEY_TYPE_AES_GROUP (4)
332#define WSM_KEY_TYPE_AES_PAIRWISE (5)
333#define WSM_KEY_TYPE_WAPI_GROUP (6)
334#define WSM_KEY_TYPE_WAPI_PAIRWISE (7)
335
336/* Key indexes */
337#define WSM_KEY_MAX_INDEX (10)
338
339/* ACK policy */
340#define WSM_ACK_POLICY_NORMAL (0)
341#define WSM_ACK_POLICY_NO_ACK (1)
342
343/* Start modes */
344#define WSM_START_MODE_AP (0) /* Mini AP */
345#define WSM_START_MODE_P2P_GO (1) /* P2P GO */
346#define WSM_START_MODE_P2P_DEV (2) /* P2P device */
347
348/* SetAssociationMode MIB flags */
349#define WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE (BIT(0))
350#define WSM_ASSOCIATION_MODE_USE_HT_MODE (BIT(1))
351#define WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET (BIT(2))
352#define WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING (BIT(3))
353#define WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES (BIT(4))
354
355/* RcpiRssiThreshold MIB flags */
356#define WSM_RCPI_RSSI_THRESHOLD_ENABLE (BIT(0))
357#define WSM_RCPI_RSSI_USE_RSSI (BIT(1))
358#define WSM_RCPI_RSSI_DONT_USE_UPPER (BIT(2))
359#define WSM_RCPI_RSSI_DONT_USE_LOWER (BIT(3))
360
361/* Update-ie constants */
362#define WSM_UPDATE_IE_BEACON (BIT(0))
363#define WSM_UPDATE_IE_PROBE_RESP (BIT(1))
364#define WSM_UPDATE_IE_PROBE_REQ (BIT(2))
365
366/* WSM events */
367/* Error */
368#define WSM_EVENT_ERROR (0)
369
370/* BSS lost */
371#define WSM_EVENT_BSS_LOST (1)
372
373/* BSS regained */
374#define WSM_EVENT_BSS_REGAINED (2)
375
376/* Radar detected */
377#define WSM_EVENT_RADAR_DETECTED (3)
378
379/* RCPI or RSSI threshold triggered */
380#define WSM_EVENT_RCPI_RSSI (4)
381
382/* BT inactive */
383#define WSM_EVENT_BT_INACTIVE (5)
384
385/* BT active */
386#define WSM_EVENT_BT_ACTIVE (6)
387
388/* MIB IDs */
389/* 4.1 dot11StationId */
390#define WSM_MIB_ID_DOT11_STATION_ID 0x0000
391
392/* 4.2 dot11MaxtransmitMsduLifeTime */
393#define WSM_MIB_ID_DOT11_MAX_TRANSMIT_LIFTIME 0x0001
394
395/* 4.3 dot11MaxReceiveLifeTime */
396#define WSM_MIB_ID_DOT11_MAX_RECEIVE_LIFETIME 0x0002
397
398/* 4.4 dot11SlotTime */
399#define WSM_MIB_ID_DOT11_SLOT_TIME 0x0003
400
401/* 4.5 dot11GroupAddressesTable */
402#define WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE 0x0004
403#define WSM_MAX_GRP_ADDRTABLE_ENTRIES 8
404
405/* 4.6 dot11WepDefaultKeyId */
406#define WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID 0x0005
407
408/* 4.7 dot11CurrentTxPowerLevel */
409#define WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL 0x0006
410
411/* 4.8 dot11RTSThreshold */
412#define WSM_MIB_ID_DOT11_RTS_THRESHOLD 0x0007
413
414/* 4.9 NonErpProtection */
415#define WSM_MIB_ID_NON_ERP_PROTECTION 0x1000
416
417/* 4.10 ArpIpAddressesTable */
418#define WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE 0x1001
419#define WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES 1
420
421/* 4.11 TemplateFrame */
422#define WSM_MIB_ID_TEMPLATE_FRAME 0x1002
423
424/* 4.12 RxFilter */
425#define WSM_MIB_ID_RX_FILTER 0x1003
426
427/* 4.13 BeaconFilterTable */
428#define WSM_MIB_ID_BEACON_FILTER_TABLE 0x1004
429
430/* 4.14 BeaconFilterEnable */
431#define WSM_MIB_ID_BEACON_FILTER_ENABLE 0x1005
432
433/* 4.15 OperationalPowerMode */
434#define WSM_MIB_ID_OPERATIONAL_POWER_MODE 0x1006
435
436/* 4.16 BeaconWakeUpPeriod */
437#define WSM_MIB_ID_BEACON_WAKEUP_PERIOD 0x1007
438
439/* 4.17 RcpiRssiThreshold */
440#define WSM_MIB_ID_RCPI_RSSI_THRESHOLD 0x1009
441
442/* 4.18 StatisticsTable */
443#define WSM_MIB_ID_STATISTICS_TABLE 0x100A
444
445/* 4.19 IbssPsConfig */
446#define WSM_MIB_ID_IBSS_PS_CONFIG 0x100B
447
448/* 4.20 CountersTable */
449#define WSM_MIB_ID_COUNTERS_TABLE 0x100C
450
451/* 4.21 BlockAckPolicy */
452#define WSM_MIB_ID_BLOCK_ACK_POLICY 0x100E
453
454/* 4.22 OverrideInternalTxRate */
455#define WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE 0x100F
456
457/* 4.23 SetAssociationMode */
458#define WSM_MIB_ID_SET_ASSOCIATION_MODE 0x1010
459
460/* 4.24 UpdateEptaConfigData */
461#define WSM_MIB_ID_UPDATE_EPTA_CONFIG_DATA 0x1011
462
463/* 4.25 SelectCcaMethod */
464#define WSM_MIB_ID_SELECT_CCA_METHOD 0x1012
465
466/* 4.26 SetUpasdInformation */
467#define WSM_MIB_ID_SET_UAPSD_INFORMATION 0x1013
468
469/* 4.27 SetAutoCalibrationMode WBF00004073 */
470#define WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE 0x1015
471
472/* 4.28 SetTxRateRetryPolicy */
473#define WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY 0x1016
474
475/* 4.29 SetHostMessageTypeFilter */
476#define WSM_MIB_ID_SET_HOST_MSG_TYPE_FILTER 0x1017
477
478/* 4.30 P2PFindInfo */
479#define WSM_MIB_ID_P2P_FIND_INFO 0x1018
480
481/* 4.31 P2PPsModeInfo */
482#define WSM_MIB_ID_P2P_PS_MODE_INFO 0x1019
483
484/* 4.32 SetEtherTypeDataFrameFilter */
485#define WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER 0x101A
486
487/* 4.33 SetUDPPortDataFrameFilter */
488#define WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER 0x101B
489
490/* 4.34 SetMagicDataFrameFilter */
491#define WSM_MIB_ID_SET_MAGIC_DATAFRAME_FILTER 0x101C
492
493/* 4.35 P2PDeviceInfo */
494#define WSM_MIB_ID_P2P_DEVICE_INFO 0x101D
495
496/* 4.36 SetWCDMABand */
497#define WSM_MIB_ID_SET_WCDMA_BAND 0x101E
498
499/* 4.37 GroupTxSequenceCounter */
500#define WSM_MIB_ID_GRP_SEQ_COUNTER 0x101F
501
502/* 4.38 ProtectedMgmtPolicy */
503#define WSM_MIB_ID_PROTECTED_MGMT_POLICY 0x1020
504
505/* 4.39 SetHtProtection */
506#define WSM_MIB_ID_SET_HT_PROTECTION 0x1021
507
508/* 4.40 GPIO Command */
509#define WSM_MIB_ID_GPIO_COMMAND 0x1022
510
511/* 4.41 TSF Counter Value */
512#define WSM_MIB_ID_TSF_COUNTER 0x1023
513
514/* Test Purposes Only */
515#define WSM_MIB_ID_BLOCK_ACK_INFO 0x100D
516
517/* 4.42 UseMultiTxConfMessage */
518#define WSM_MIB_USE_MULTI_TX_CONF 0x1024
519
520/* 4.43 Keep-alive period */
521#define WSM_MIB_ID_KEEP_ALIVE_PERIOD 0x1025
522
523/* 4.44 Disable BSSID filter */
524#define WSM_MIB_ID_DISABLE_BSSID_FILTER 0x1026
525
526/* Frame template types */
527#define WSM_FRAME_TYPE_PROBE_REQUEST (0)
528#define WSM_FRAME_TYPE_BEACON (1)
529#define WSM_FRAME_TYPE_NULL (2)
530#define WSM_FRAME_TYPE_QOS_NULL (3)
531#define WSM_FRAME_TYPE_PS_POLL (4)
532#define WSM_FRAME_TYPE_PROBE_RESPONSE (5)
533
534#define WSM_FRAME_GREENFIELD (0x80) /* See 4.11 */
535
536/* Status */
537/* The WSM firmware has completed a request */
538/* successfully. */
539#define WSM_STATUS_SUCCESS (0)
540
541/* This is a generic failure code if other error codes do */
542/* not apply. */
543#define WSM_STATUS_FAILURE (1)
544
545/* A request contains one or more invalid parameters. */
546#define WSM_INVALID_PARAMETER (2)
547
548/* The request cannot perform because the device is in */
549/* an inappropriate mode. */
550#define WSM_ACCESS_DENIED (3)
551
552/* The frame received includes a decryption error. */
553#define WSM_STATUS_DECRYPTFAILURE (4)
554
555/* A MIC failure is detected in the received packets. */
556#define WSM_STATUS_MICFAILURE (5)
557
558/* The transmit request failed due to retry limit being */
559/* exceeded. */
560#define WSM_STATUS_RETRY_EXCEEDED (6)
561
562/* The transmit request failed due to MSDU life time */
563/* being exceeded. */
564#define WSM_STATUS_TX_LIFETIME_EXCEEDED (7)
565
566/* The link to the AP is lost. */
567#define WSM_STATUS_LINK_LOST (8)
568
569/* No key was found for the encrypted frame */
570#define WSM_STATUS_NO_KEY_FOUND (9)
571
572/* Jammer was detected when transmitting this frame */
573#define WSM_STATUS_JAMMER_DETECTED (10)
574
575/* The message should be requeued later. */
576/* This is applicable only to Transmit */
577#define WSM_REQUEUE (11)
578
579/* Advanced filtering options */
580#define WSM_MAX_FILTER_ELEMENTS (4)
581
582#define WSM_FILTER_ACTION_IGNORE (0)
583#define WSM_FILTER_ACTION_FILTER_IN (1)
584#define WSM_FILTER_ACTION_FILTER_OUT (2)
585
586#define WSM_FILTER_PORT_TYPE_DST (0)
587#define WSM_FILTER_PORT_TYPE_SRC (1)
588
589/* Actual header of WSM messages */
590struct wsm_hdr {
591 __le16 len;
592 __le16 id;
593};
594
595#define WSM_TX_SEQ_MAX (7)
596#define WSM_TX_SEQ(seq) \
597 ((seq & WSM_TX_SEQ_MAX) << 13)
598#define WSM_TX_LINK_ID_MAX (0x0F)
599#define WSM_TX_LINK_ID(link_id) \
600 ((link_id & WSM_TX_LINK_ID_MAX) << 6)
601
602#define MAX_BEACON_SKIP_TIME_MS 1000
603
604#define WSM_CMD_LAST_CHANCE_TIMEOUT (HZ * 3 / 2)
605
606/* ******************************************************************** */
607/* WSM capability */
608
609#define WSM_STARTUP_IND_ID 0x0801
610
611struct wsm_startup_ind {
612 u16 input_buffers;
613 u16 input_buffer_size;
614 u16 status;
615 u16 hw_id;
616 u16 hw_subid;
617 u16 fw_cap;
618 u16 fw_type;
619 u16 fw_api;
620 u16 fw_build;
621 u16 fw_ver;
622 char fw_label[128];
623 u32 config[4];
624};
625
626/* ******************************************************************** */
627/* WSM commands */
628
629/* 3.1 */
630#define WSM_CONFIGURATION_REQ_ID 0x0009
631#define WSM_CONFIGURATION_RESP_ID 0x0409
632
633struct wsm_tx_power_range {
634 int min_power_level;
635 int max_power_level;
636 u32 stepping;
637};
638
639struct wsm_configuration {
640 /* [in] */ u32 dot11MaxTransmitMsduLifeTime;
641 /* [in] */ u32 dot11MaxReceiveLifeTime;
642 /* [in] */ u32 dot11RtsThreshold;
643 /* [in, out] */ u8 *dot11StationId;
644 /* [in] */ const void *dpdData;
645 /* [in] */ size_t dpdData_size;
646 /* [out] */ u8 dot11FrequencyBandsSupported;
647 /* [out] */ u32 supportedRateMask;
648 /* [out] */ struct wsm_tx_power_range txPowerRange[2];
649};
650
651int wsm_configuration(struct cw1200_common *priv,
652 struct wsm_configuration *arg);
653
654/* 3.3 */
655#define WSM_RESET_REQ_ID 0x000A
656#define WSM_RESET_RESP_ID 0x040A
657struct wsm_reset {
658 /* [in] */ int link_id;
659 /* [in] */ bool reset_statistics;
660};
661
662int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg);
663
664/* 3.5 */
665#define WSM_READ_MIB_REQ_ID 0x0005
666#define WSM_READ_MIB_RESP_ID 0x0405
667int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
668 size_t buf_size);
669
670/* 3.7 */
671#define WSM_WRITE_MIB_REQ_ID 0x0006
672#define WSM_WRITE_MIB_RESP_ID 0x0406
673int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
674 size_t buf_size);
675
676/* 3.9 */
677#define WSM_START_SCAN_REQ_ID 0x0007
678#define WSM_START_SCAN_RESP_ID 0x0407
679
680struct wsm_ssid {
681 u8 ssid[32];
682 u32 length;
683};
684
685struct wsm_scan_ch {
686 u16 number;
687 u32 min_chan_time;
688 u32 max_chan_time;
689 u32 tx_power_level;
690};
691
692struct wsm_scan {
693 /* WSM_PHY_BAND_... */
694 u8 band;
695
696 /* WSM_SCAN_TYPE_... */
697 u8 type;
698
699 /* WSM_SCAN_FLAG_... */
700 u8 flags;
701
702 /* WSM_TRANSMIT_RATE_... */
703 u8 max_tx_rate;
704
705 /* Interval period in TUs that the device shall the re- */
706 /* execute the requested scan. Max value supported by the device */
707 /* is 256s. */
708 u32 auto_scan_interval;
709
710 /* Number of probe requests (per SSID) sent to one (1) */
711 /* channel. Zero (0) means that none is send, which */
712 /* means that a passive scan is to be done. Value */
713 /* greater than zero (0) means that an active scan is to */
714 /* be done. */
715 u32 num_probes;
716
717 /* Number of channels to be scanned. */
718 /* Maximum value is WSM_SCAN_MAX_NUM_OF_CHANNELS. */
719 u8 num_channels;
720
721 /* Number of SSID provided in the scan command (this */
722 /* is zero (0) in broadcast scan) */
723 /* The maximum number of SSIDs is WSM_SCAN_MAX_NUM_OF_SSIDS. */
724 u8 num_ssids;
725
726 /* The delay time (in microseconds) period */
727 /* before sending a probe-request. */
728 u8 probe_delay;
729
730 /* SSIDs to be scanned [numOfSSIDs]; */
731 struct wsm_ssid *ssids;
732
733 /* Channels to be scanned [numOfChannels]; */
734 struct wsm_scan_ch *ch;
735};
736
737int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg);
738
739/* 3.11 */
740#define WSM_STOP_SCAN_REQ_ID 0x0008
741#define WSM_STOP_SCAN_RESP_ID 0x0408
742int wsm_stop_scan(struct cw1200_common *priv);
743
744/* 3.13 */
745#define WSM_SCAN_COMPLETE_IND_ID 0x0806
746struct wsm_scan_complete {
747 /* WSM_STATUS_... */
748 u32 status;
749
750 /* WSM_PSM_... */
751 u8 psm;
752
753 /* Number of channels that the scan operation completed. */
754 u8 num_channels;
755};
756
757/* 3.14 */
758#define WSM_TX_CONFIRM_IND_ID 0x0404
759#define WSM_MULTI_TX_CONFIRM_ID 0x041E
760
761struct wsm_tx_confirm {
762 /* Packet identifier used in wsm_tx. */
763 u32 packet_id;
764
765 /* WSM_STATUS_... */
766 u32 status;
767
768 /* WSM_TRANSMIT_RATE_... */
769 u8 tx_rate;
770
771 /* The number of times the frame was transmitted */
772 /* without receiving an acknowledgement. */
773 u8 ack_failures;
774
775 /* WSM_TX_STATUS_... */
776 u16 flags;
777
778 /* The total time in microseconds that the frame spent in */
779 /* the WLAN device before transmission as completed. */
780 u32 media_delay;
781
782 /* The total time in microseconds that the frame spent in */
783 /* the WLAN device before transmission was started. */
784 u32 tx_queue_delay;
785};
786
787/* 3.15 */
788typedef void (*wsm_tx_confirm_cb) (struct cw1200_common *priv,
789 struct wsm_tx_confirm *arg);
790
791/* Note that ideology of wsm_tx struct is different against the rest of
792 * WSM API. wsm_hdr is /not/ a caller-adapted struct to be used as an input
793 * argument for WSM call, but a prepared bytestream to be sent to firmware.
794 * It is filled partly in cw1200_tx, partly in low-level WSM code.
795 * Please pay attention once again: ideology is different.
796 *
797 * Legend:
798 * - [in]: cw1200_tx must fill this field.
799 * - [wsm]: the field is filled by low-level WSM.
800 */
801struct wsm_tx {
802 /* common WSM header */
803 struct wsm_hdr hdr;
804
805 /* Packet identifier that meant to be used in completion. */
806 __le32 packet_id;
807
808 /* WSM_TRANSMIT_RATE_... */
809 u8 max_tx_rate;
810
811 /* WSM_QUEUE_... */
812 u8 queue_id;
813
814 /* True: another packet is pending on the host for transmission. */
815 u8 more;
816
817 /* Bit 0 = 0 - Start expiry time from first Tx attempt (default) */
818 /* Bit 0 = 1 - Start expiry time from receipt of Tx Request */
819 /* Bits 3:1 - PTA Priority */
820 /* Bits 6:4 - Tx Rate Retry Policy */
821 /* Bit 7 - Reserved */
822 u8 flags;
823
824 /* Should be 0. */
825 __le32 reserved;
826
827 /* The elapsed time in TUs, after the initial transmission */
828 /* of an MSDU, after which further attempts to transmit */
829 /* the MSDU shall be terminated. Overrides the global */
830 /* dot11MaxTransmitMsduLifeTime setting [optional] */
831 /* Device will set the default value if this is 0. */
832 __le32 expire_time;
833
834 /* WSM_HT_TX_... */
835 __le32 ht_tx_parameters;
836};
837
838/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */
839#define WSM_TX_EXTRA_HEADROOM (28)
840
841/* 3.16 */
842#define WSM_RECEIVE_IND_ID 0x0804
843
844struct wsm_rx {
845 /* WSM_STATUS_... */
846 __le32 status;
847
848 /* Specifies the channel of the received packet. */
849 __le16 channel_number;
850
851 /* WSM_TRANSMIT_RATE_... */
852 u8 rx_rate;
853
854 /* This value is expressed in signed Q8.0 format for */
855 /* RSSI and unsigned Q7.1 format for RCPI. */
856 u8 rcpi_rssi;
857
858 /* WSM_RX_STATUS_... */
859 __le32 flags;
860
861 /* Payload */
862 u8 data[0];
863} __packed;
864
865/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */
866#define WSM_RX_EXTRA_HEADROOM (16)
867
868typedef void (*wsm_rx_cb) (struct cw1200_common *priv, struct wsm_rx *arg,
869 struct sk_buff **skb_p);
870
871/* 3.17 */
872struct wsm_event {
873 /* WSM_STATUS_... */
874 /* [out] */ u32 id;
875
876 /* Indication parameters. */
877 /* For error indication, this shall be a 32-bit WSM status. */
878 /* For RCPI or RSSI indication, this should be an 8-bit */
879 /* RCPI or RSSI value. */
880 /* [out] */ u32 data;
881};
882
883struct cw1200_wsm_event {
884 struct list_head link;
885 struct wsm_event evt;
886};
887
888/* 3.18 - 3.22 */
889/* Measurement. Skipped for now. Irrelevent. */
890
891typedef void (*wsm_event_cb) (struct cw1200_common *priv,
892 struct wsm_event *arg);
893
894/* 3.23 */
895#define WSM_JOIN_REQ_ID 0x000B
896#define WSM_JOIN_RESP_ID 0x040B
897
898struct wsm_join {
899 /* WSM_JOIN_MODE_... */
900 u8 mode;
901
902 /* WSM_PHY_BAND_... */
903 u8 band;
904
905 /* Specifies the channel number to join. The channel */
906 /* number will be mapped to an actual frequency */
907 /* according to the band */
908 u16 channel_number;
909
910 /* Specifies the BSSID of the BSS or IBSS to be joined */
911 /* or the IBSS to be started. */
912 u8 bssid[6];
913
914 /* ATIM window of IBSS */
915 /* When ATIM window is zero the initiated IBSS does */
916 /* not support power saving. */
917 u16 atim_window;
918
919 /* WSM_JOIN_PREAMBLE_... */
920 u8 preamble_type;
921
922 /* Specifies if a probe request should be send with the */
923 /* specified SSID when joining to the network. */
924 u8 probe_for_join;
925
926 /* DTIM Period (In multiples of beacon interval) */
927 u8 dtim_period;
928
929 /* WSM_JOIN_FLAGS_... */
930 u8 flags;
931
932 /* Length of the SSID */
933 u32 ssid_len;
934
935 /* Specifies the SSID of the IBSS to join or start */
936 u8 ssid[32];
937
938 /* Specifies the time between TBTTs in TUs */
939 u32 beacon_interval;
940
941 /* A bit mask that defines the BSS basic rate set. */
942 u32 basic_rate_set;
943};
944
945struct wsm_join_cnf {
946 u32 status;
947
948 /* Minimum transmission power level in units of 0.1dBm */
949 u32 min_power_level;
950
951 /* Maximum transmission power level in units of 0.1dBm */
952 u32 max_power_level;
953};
954
955int wsm_join(struct cw1200_common *priv, struct wsm_join *arg);
956
957/* 3.24 */
958struct wsm_join_complete {
959 /* WSM_STATUS_... */
960 u32 status;
961};
962
963/* 3.25 */
964#define WSM_SET_PM_REQ_ID 0x0010
965#define WSM_SET_PM_RESP_ID 0x0410
966struct wsm_set_pm {
967 /* WSM_PSM_... */
968 u8 mode;
969
970 /* in unit of 500us; 0 to use default */
971 u8 fast_psm_idle_period;
972
973 /* in unit of 500us; 0 to use default */
974 u8 ap_psm_change_period;
975
976 /* in unit of 500us; 0 to disable auto-pspoll */
977 u8 min_auto_pspoll_period;
978};
979
980int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
981
982/* 3.27 */
983struct wsm_set_pm_complete {
984 u8 psm; /* WSM_PSM_... */
985};
986
987/* 3.28 */
988#define WSM_SET_BSS_PARAMS_REQ_ID 0x0011
989#define WSM_SET_BSS_PARAMS_RESP_ID 0x0411
990struct wsm_set_bss_params {
991 /* This resets the beacon loss counters only */
992 u8 reset_beacon_loss;
993
994 /* The number of lost consecutive beacons after which */
995 /* the WLAN device should indicate the BSS-Lost event */
996 /* to the WLAN host driver. */
997 u8 beacon_lost_count;
998
999 /* The AID received during the association process. */
1000 u16 aid;
1001
1002 /* The operational rate set mask */
1003 u32 operational_rate_set;
1004};
1005
1006int wsm_set_bss_params(struct cw1200_common *priv,
1007 const struct wsm_set_bss_params *arg);
1008
1009/* 3.30 */
1010#define WSM_ADD_KEY_REQ_ID 0x000C
1011#define WSM_ADD_KEY_RESP_ID 0x040C
1012struct wsm_add_key {
1013 u8 type; /* WSM_KEY_TYPE_... */
1014 u8 index; /* Key entry index: 0 -- WSM_KEY_MAX_INDEX */
1015 u16 reserved;
1016 union {
1017 struct {
1018 u8 peer[6]; /* MAC address of the
1019 * peer station */
1020 u8 reserved;
1021 u8 keylen; /* Key length in bytes */
1022 u8 keydata[16]; /* Key data */
1023 } __packed wep_pairwise;
1024 struct {
1025 u8 keyid; /* Unique per key identifier
1026 * (0..3) */
1027 u8 keylen; /* Key length in bytes */
1028 u16 reserved;
1029 u8 keydata[16]; /* Key data */
1030 } __packed wep_group;
1031 struct {
1032 u8 peer[6]; /* MAC address of the
1033 * peer station */
1034 u16 reserved;
1035 u8 keydata[16]; /* TKIP key data */
1036 u8 rx_mic_key[8]; /* Rx MIC key */
1037 u8 tx_mic_key[8]; /* Tx MIC key */
1038 } __packed tkip_pairwise;
1039 struct {
1040 u8 keydata[16]; /* TKIP key data */
1041 u8 rx_mic_key[8]; /* Rx MIC key */
1042 u8 keyid; /* Key ID */
1043 u8 reserved[3];
1044 u8 rx_seqnum[8]; /* Receive Sequence Counter */
1045 } __packed tkip_group;
1046 struct {
1047 u8 peer[6]; /* MAC address of the
1048 * peer station */
1049 u16 reserved;
1050 u8 keydata[16]; /* AES key data */
1051 } __packed aes_pairwise;
1052 struct {
1053 u8 keydata[16]; /* AES key data */
1054 u8 keyid; /* Key ID */
1055 u8 reserved[3];
1056 u8 rx_seqnum[8]; /* Receive Sequence Counter */
1057 } __packed aes_group;
1058 struct {
1059 u8 peer[6]; /* MAC address of the
1060 * peer station */
1061 u8 keyid; /* Key ID */
1062 u8 reserved;
1063 u8 keydata[16]; /* WAPI key data */
1064 u8 mic_key[16]; /* MIC key data */
1065 } __packed wapi_pairwise;
1066 struct {
1067 u8 keydata[16]; /* WAPI key data */
1068 u8 mic_key[16]; /* MIC key data */
1069 u8 keyid; /* Key ID */
1070 u8 reserved[3];
1071 } __packed wapi_group;
1072 } __packed;
1073} __packed;
1074
1075int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg);
1076
1077/* 3.32 */
1078#define WSM_REMOVE_KEY_REQ_ID 0x000D
1079#define WSM_REMOVE_KEY_RESP_ID 0x040D
1080struct wsm_remove_key {
1081 u8 index; /* Key entry index : 0-10 */
1082};
1083
1084int wsm_remove_key(struct cw1200_common *priv,
1085 const struct wsm_remove_key *arg);
1086
1087/* 3.34 */
1088struct wsm_set_tx_queue_params {
1089 /* WSM_ACK_POLICY_... */
1090 u8 ackPolicy;
1091
1092 /* Medium Time of TSPEC (in 32us units) allowed per */
1093 /* One Second Averaging Period for this queue. */
1094 u16 allowedMediumTime;
1095
1096 /* dot11MaxTransmitMsduLifetime to be used for the */
1097 /* specified queue. */
1098 u32 maxTransmitLifetime;
1099};
1100
1101struct wsm_tx_queue_params {
1102 /* NOTE: index is a linux queue id. */
1103 struct wsm_set_tx_queue_params params[4];
1104};
1105
1106
1107#define WSM_TX_QUEUE_SET(queue_params, queue, ack_policy, allowed_time,\
1108 max_life_time) \
1109do { \
1110 struct wsm_set_tx_queue_params *p = &(queue_params)->params[queue]; \
1111 p->ackPolicy = (ack_policy); \
1112 p->allowedMediumTime = (allowed_time); \
1113 p->maxTransmitLifetime = (max_life_time); \
1114} while (0)
1115
1116int wsm_set_tx_queue_params(struct cw1200_common *priv,
1117 const struct wsm_set_tx_queue_params *arg, u8 id);
1118
1119/* 3.36 */
1120#define WSM_EDCA_PARAMS_REQ_ID 0x0013
1121#define WSM_EDCA_PARAMS_RESP_ID 0x0413
1122struct wsm_edca_queue_params {
1123 /* CWmin (in slots) for the access class. */
1124 __le16 cwmin;
1125
1126 /* CWmax (in slots) for the access class. */
1127 __le16 cwmax;
1128
1129 /* AIFS (in slots) for the access class. */
1130 __le16 aifns;
1131
1132 /* TX OP Limit (in microseconds) for the access class. */
1133 __le16 txop_limit;
1134
1135 /* dot11MaxReceiveLifetime to be used for the specified */
1136 /* the access class. Overrides the global */
1137 /* dot11MaxReceiveLifetime value */
1138 __le32 max_rx_lifetime;
1139} __packed;
1140
1141struct wsm_edca_params {
1142 /* NOTE: index is a linux queue id. */
1143 struct wsm_edca_queue_params params[4];
1144 bool uapsd_enable[4];
1145};
1146
1147#define TXOP_UNIT 32
1148#define WSM_EDCA_SET(__edca, __queue, __aifs, __cw_min, __cw_max, __txop, __lifetime,\
1149 __uapsd) \
1150 do { \
1151 struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \
1152 p->cwmin = (__cw_min); \
1153 p->cwmax = (__cw_max); \
1154 p->aifns = (__aifs); \
1155 p->txop_limit = ((__txop) * TXOP_UNIT); \
1156 p->max_rx_lifetime = (__lifetime); \
1157 (__edca)->uapsd_enable[__queue] = (__uapsd); \
1158 } while (0)
1159
1160int wsm_set_edca_params(struct cw1200_common *priv,
1161 const struct wsm_edca_params *arg);
1162
1163int wsm_set_uapsd_param(struct cw1200_common *priv,
1164 const struct wsm_edca_params *arg);
1165
1166/* 3.38 */
1167/* Set-System info. Skipped for now. Irrelevent. */
1168
1169/* 3.40 */
1170#define WSM_SWITCH_CHANNEL_REQ_ID 0x0016
1171#define WSM_SWITCH_CHANNEL_RESP_ID 0x0416
1172
1173struct wsm_switch_channel {
1174 /* 1 - means the STA shall not transmit any further */
1175 /* frames until the channel switch has completed */
1176 u8 mode;
1177
1178 /* Number of TBTTs until channel switch occurs. */
1179 /* 0 - indicates switch shall occur at any time */
1180 /* 1 - occurs immediately before the next TBTT */
1181 u8 switch_count;
1182
1183 /* The new channel number to switch to. */
1184 /* Note this is defined as per section 2.7. */
1185 u16 channel_number;
1186};
1187
1188int wsm_switch_channel(struct cw1200_common *priv,
1189 const struct wsm_switch_channel *arg);
1190
1191typedef void (*wsm_channel_switch_cb) (struct cw1200_common *priv);
1192
1193#define WSM_START_REQ_ID 0x0017
1194#define WSM_START_RESP_ID 0x0417
1195
1196struct wsm_start {
1197 /* WSM_START_MODE_... */
1198 /* [in] */ u8 mode;
1199
1200 /* WSM_PHY_BAND_... */
1201 /* [in] */ u8 band;
1202
1203 /* Channel number */
1204 /* [in] */ u16 channel_number;
1205
1206 /* Client Traffic window in units of TU */
1207 /* Valid only when mode == ..._P2P */
1208 /* [in] */ u32 ct_window;
1209
1210 /* Interval between two consecutive */
1211 /* beacon transmissions in TU. */
1212 /* [in] */ u32 beacon_interval;
1213
1214 /* DTIM period in terms of beacon intervals */
1215 /* [in] */ u8 dtim_period;
1216
1217 /* WSM_JOIN_PREAMBLE_... */
1218 /* [in] */ u8 preamble;
1219
1220 /* The delay time (in microseconds) period */
1221 /* before sending a probe-request. */
1222 /* [in] */ u8 probe_delay;
1223
1224 /* Length of the SSID */
1225 /* [in] */ u8 ssid_len;
1226
1227 /* SSID of the BSS or P2P_GO to be started now. */
1228 /* [in] */ u8 ssid[32];
1229
1230 /* The basic supported rates for the MiniAP. */
1231 /* [in] */ u32 basic_rate_set;
1232};
1233
1234int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg);
1235
1236#define WSM_BEACON_TRANSMIT_REQ_ID 0x0018
1237#define WSM_BEACON_TRANSMIT_RESP_ID 0x0418
1238
1239struct wsm_beacon_transmit {
1240 /* 1: enable; 0: disable */
1241 /* [in] */ u8 enable_beaconing;
1242};
1243
1244int wsm_beacon_transmit(struct cw1200_common *priv,
1245 const struct wsm_beacon_transmit *arg);
1246
1247int wsm_start_find(struct cw1200_common *priv);
1248
1249int wsm_stop_find(struct cw1200_common *priv);
1250
1251typedef void (*wsm_find_complete_cb) (struct cw1200_common *priv, u32 status);
1252
1253struct wsm_suspend_resume {
1254 /* See 3.52 */
1255 /* Link ID */
1256 /* [out] */ int link_id;
1257 /* Stop sending further Tx requests down to device for this link */
1258 /* [out] */ bool stop;
1259 /* Transmit multicast Frames */
1260 /* [out] */ bool multicast;
1261 /* The AC on which Tx to be suspended /resumed. */
1262 /* This is applicable only for U-APSD */
1263 /* WSM_QUEUE_... */
1264 /* [out] */ int queue;
1265};
1266
1267typedef void (*wsm_suspend_resume_cb) (struct cw1200_common *priv,
1268 struct wsm_suspend_resume *arg);
1269
1270/* 3.54 Update-IE request. */
1271struct wsm_update_ie {
1272 /* WSM_UPDATE_IE_... */
1273 /* [in] */ u16 what;
1274 /* [in] */ u16 count;
1275 /* [in] */ u8 *ies;
1276 /* [in] */ size_t length;
1277};
1278
1279int wsm_update_ie(struct cw1200_common *priv,
1280 const struct wsm_update_ie *arg);
1281
1282/* 3.56 */
1283struct wsm_map_link {
1284 /* MAC address of the remote device */
1285 /* [in] */ u8 mac_addr[6];
1286 /* [in] */ u8 link_id;
1287};
1288
1289int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg);
1290
1291/* ******************************************************************** */
1292/* MIB shortcats */
1293
1294static inline int wsm_set_output_power(struct cw1200_common *priv,
1295 int power_level)
1296{
1297 __le32 val = __cpu_to_le32(power_level);
1298 return wsm_write_mib(priv, WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL,
1299 &val, sizeof(val));
1300}
1301
1302static inline int wsm_set_beacon_wakeup_period(struct cw1200_common *priv,
1303 unsigned dtim_interval,
1304 unsigned listen_interval)
1305{
1306 struct {
1307 u8 numBeaconPeriods;
1308 u8 reserved;
1309 __le16 listenInterval;
1310 } val = {
1311 dtim_interval, 0, __cpu_to_le16(listen_interval)
1312 };
1313
1314 if (dtim_interval > 0xFF || listen_interval > 0xFFFF)
1315 return -EINVAL;
1316 else
1317 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_WAKEUP_PERIOD,
1318 &val, sizeof(val));
1319}
1320
1321struct wsm_rcpi_rssi_threshold {
1322 u8 rssiRcpiMode; /* WSM_RCPI_RSSI_... */
1323 u8 lowerThreshold;
1324 u8 upperThreshold;
1325 u8 rollingAverageCount;
1326};
1327
1328static inline int wsm_set_rcpi_rssi_threshold(struct cw1200_common *priv,
1329 struct wsm_rcpi_rssi_threshold *arg)
1330{
1331 return wsm_write_mib(priv, WSM_MIB_ID_RCPI_RSSI_THRESHOLD, arg,
1332 sizeof(*arg));
1333}
1334
1335struct wsm_mib_counters_table {
1336 __le32 plcp_errors;
1337 __le32 fcs_errors;
1338 __le32 tx_packets;
1339 __le32 rx_packets;
1340 __le32 rx_packet_errors;
1341 __le32 rx_decryption_failures;
1342 __le32 rx_mic_failures;
1343 __le32 rx_no_key_failures;
1344 __le32 tx_multicast_frames;
1345 __le32 tx_frames_success;
1346 __le32 tx_frame_failures;
1347 __le32 tx_frames_retried;
1348 __le32 tx_frames_multi_retried;
1349 __le32 rx_frame_duplicates;
1350 __le32 rts_success;
1351 __le32 rts_failures;
1352 __le32 ack_failures;
1353 __le32 rx_multicast_frames;
1354 __le32 rx_frames_success;
1355 __le32 rx_cmac_icv_errors;
1356 __le32 rx_cmac_replays;
1357 __le32 rx_mgmt_ccmp_replays;
1358} __packed;
1359
1360static inline int wsm_get_counters_table(struct cw1200_common *priv,
1361 struct wsm_mib_counters_table *arg)
1362{
1363 return wsm_read_mib(priv, WSM_MIB_ID_COUNTERS_TABLE,
1364 arg, sizeof(*arg));
1365}
1366
1367static inline int wsm_get_station_id(struct cw1200_common *priv, u8 *mac)
1368{
1369 return wsm_read_mib(priv, WSM_MIB_ID_DOT11_STATION_ID, mac, ETH_ALEN);
1370}
1371
1372struct wsm_rx_filter {
1373 bool promiscuous;
1374 bool bssid;
1375 bool fcs;
1376 bool probeResponder;
1377};
1378
1379static inline int wsm_set_rx_filter(struct cw1200_common *priv,
1380 const struct wsm_rx_filter *arg)
1381{
1382 __le32 val = 0;
1383 if (arg->promiscuous)
1384 val |= __cpu_to_le32(BIT(0));
1385 if (arg->bssid)
1386 val |= __cpu_to_le32(BIT(1));
1387 if (arg->fcs)
1388 val |= __cpu_to_le32(BIT(2));
1389 if (arg->probeResponder)
1390 val |= __cpu_to_le32(BIT(3));
1391 return wsm_write_mib(priv, WSM_MIB_ID_RX_FILTER, &val, sizeof(val));
1392}
1393
1394int wsm_set_probe_responder(struct cw1200_common *priv, bool enable);
1395
1396#define WSM_BEACON_FILTER_IE_HAS_CHANGED BIT(0)
1397#define WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT BIT(1)
1398#define WSM_BEACON_FILTER_IE_HAS_APPEARED BIT(2)
1399
1400struct wsm_beacon_filter_table_entry {
1401 u8 ie_id;
1402 u8 flags;
1403 u8 oui[3];
1404 u8 match_data[3];
1405} __packed;
1406
1407struct wsm_mib_beacon_filter_table {
1408 __le32 num;
1409 struct wsm_beacon_filter_table_entry entry[10];
1410} __packed;
1411
1412static inline int wsm_set_beacon_filter_table(struct cw1200_common *priv,
1413 struct wsm_mib_beacon_filter_table *ft)
1414{
1415 size_t size = __le32_to_cpu(ft->num) *
1416 sizeof(struct wsm_beacon_filter_table_entry) +
1417 sizeof(__le32);
1418
1419 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_TABLE, ft, size);
1420}
1421
1422#define WSM_BEACON_FILTER_ENABLE BIT(0) /* Enable/disable beacon filtering */
1423#define WSM_BEACON_FILTER_AUTO_ERP BIT(1) /* If 1 FW will handle ERP IE changes internally */
1424
1425struct wsm_beacon_filter_control {
1426 int enabled;
1427 int bcn_count;
1428};
1429
1430static inline int wsm_beacon_filter_control(struct cw1200_common *priv,
1431 struct wsm_beacon_filter_control *arg)
1432{
1433 struct {
1434 __le32 enabled;
1435 __le32 bcn_count;
1436 } val;
1437 val.enabled = __cpu_to_le32(arg->enabled);
1438 val.bcn_count = __cpu_to_le32(arg->bcn_count);
1439 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_ENABLE, &val,
1440 sizeof(val));
1441}
1442
1443enum wsm_power_mode {
1444 wsm_power_mode_active = 0,
1445 wsm_power_mode_doze = 1,
1446 wsm_power_mode_quiescent = 2,
1447};
1448
1449struct wsm_operational_mode {
1450 enum wsm_power_mode power_mode;
1451 int disable_more_flag_usage;
1452 int perform_ant_diversity;
1453};
1454
1455static inline int wsm_set_operational_mode(struct cw1200_common *priv,
1456 const struct wsm_operational_mode *arg)
1457{
1458 u8 val = arg->power_mode;
1459 if (arg->disable_more_flag_usage)
1460 val |= BIT(4);
1461 if (arg->perform_ant_diversity)
1462 val |= BIT(5);
1463 return wsm_write_mib(priv, WSM_MIB_ID_OPERATIONAL_POWER_MODE, &val,
1464 sizeof(val));
1465}
1466
1467struct wsm_template_frame {
1468 u8 frame_type;
1469 u8 rate;
1470 struct sk_buff *skb;
1471};
1472
1473static inline int wsm_set_template_frame(struct cw1200_common *priv,
1474 struct wsm_template_frame *arg)
1475{
1476 int ret;
1477 u8 *p = skb_push(arg->skb, 4);
1478 p[0] = arg->frame_type;
1479 p[1] = arg->rate;
1480 ((u16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4);
1481 ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len);
1482 skb_pull(arg->skb, 4);
1483 return ret;
1484}
1485
1486
1487struct wsm_protected_mgmt_policy {
1488 bool protectedMgmtEnable;
1489 bool unprotectedMgmtFramesAllowed;
1490 bool encryptionForAuthFrame;
1491};
1492
1493static inline int wsm_set_protected_mgmt_policy(struct cw1200_common *priv,
1494 struct wsm_protected_mgmt_policy *arg)
1495{
1496 __le32 val = 0;
1497 int ret;
1498 if (arg->protectedMgmtEnable)
1499 val |= __cpu_to_le32(BIT(0));
1500 if (arg->unprotectedMgmtFramesAllowed)
1501 val |= __cpu_to_le32(BIT(1));
1502 if (arg->encryptionForAuthFrame)
1503 val |= __cpu_to_le32(BIT(2));
1504 ret = wsm_write_mib(priv, WSM_MIB_ID_PROTECTED_MGMT_POLICY,
1505 &val, sizeof(val));
1506 return ret;
1507}
1508
1509struct wsm_mib_block_ack_policy {
1510 u8 tx_tid;
1511 u8 reserved1;
1512 u8 rx_tid;
1513 u8 reserved2;
1514} __packed;
1515
1516static inline int wsm_set_block_ack_policy(struct cw1200_common *priv,
1517 u8 tx_tid_policy,
1518 u8 rx_tid_policy)
1519{
1520 struct wsm_mib_block_ack_policy val = {
1521 .tx_tid = tx_tid_policy,
1522 .rx_tid = rx_tid_policy,
1523 };
1524 return wsm_write_mib(priv, WSM_MIB_ID_BLOCK_ACK_POLICY, &val,
1525 sizeof(val));
1526}
1527
1528struct wsm_mib_association_mode {
1529 u8 flags; /* WSM_ASSOCIATION_MODE_... */
1530 u8 preamble; /* WSM_JOIN_PREAMBLE_... */
1531 u8 greenfield; /* 1 for greenfield */
1532 u8 mpdu_start_spacing;
1533 __le32 basic_rate_set;
1534} __packed;
1535
1536static inline int wsm_set_association_mode(struct cw1200_common *priv,
1537 struct wsm_mib_association_mode *arg)
1538{
1539 return wsm_write_mib(priv, WSM_MIB_ID_SET_ASSOCIATION_MODE, arg,
1540 sizeof(*arg));
1541}
1542
1543#define WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED BIT(2)
1544#define WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT BIT(3)
1545struct wsm_tx_rate_retry_policy {
1546 u8 index;
1547 u8 short_retries;
1548 u8 long_retries;
1549 /* BIT(2) - Terminate retries when Tx rate retry policy
1550 * finishes.
1551 * BIT(3) - Count initial frame transmission as part of
1552 * rate retry counting but not as a retry
1553 * attempt */
1554 u8 flags;
1555 u8 rate_recoveries;
1556 u8 reserved[3];
1557 __le32 rate_count_indices[3];
1558} __packed;
1559
1560struct wsm_set_tx_rate_retry_policy {
1561 u8 num;
1562 u8 reserved[3];
1563 struct wsm_tx_rate_retry_policy tbl[8];
1564} __packed;
1565
1566static inline int wsm_set_tx_rate_retry_policy(struct cw1200_common *priv,
1567 struct wsm_set_tx_rate_retry_policy *arg)
1568{
1569 size_t size = 4 + arg->num * sizeof(struct wsm_tx_rate_retry_policy);
1570 return wsm_write_mib(priv, WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg,
1571 size);
1572}
1573
1574/* 4.32 SetEtherTypeDataFrameFilter */
1575struct wsm_ether_type_filter_hdr {
1576 u8 num; /* Up to WSM_MAX_FILTER_ELEMENTS */
1577 u8 reserved[3];
1578} __packed;
1579
1580struct wsm_ether_type_filter {
1581 u8 action; /* WSM_FILTER_ACTION_XXX */
1582 u8 reserved;
1583 __le16 type; /* Type of ethernet frame */
1584} __packed;
1585
1586static inline int wsm_set_ether_type_filter(struct cw1200_common *priv,
1587 struct wsm_ether_type_filter_hdr *arg)
1588{
1589 size_t size = sizeof(struct wsm_ether_type_filter_hdr) +
1590 arg->num * sizeof(struct wsm_ether_type_filter);
1591 return wsm_write_mib(priv, WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER,
1592 arg, size);
1593}
1594
1595/* 4.33 SetUDPPortDataFrameFilter */
1596struct wsm_udp_port_filter_hdr {
1597 u8 num; /* Up to WSM_MAX_FILTER_ELEMENTS */
1598 u8 reserved[3];
1599} __packed;
1600
1601struct wsm_udp_port_filter {
1602 u8 action; /* WSM_FILTER_ACTION_XXX */
1603 u8 type; /* WSM_FILTER_PORT_TYPE_XXX */
1604 __le16 port; /* Port number */
1605} __packed;
1606
1607static inline int wsm_set_udp_port_filter(struct cw1200_common *priv,
1608 struct wsm_udp_port_filter_hdr *arg)
1609{
1610 size_t size = sizeof(struct wsm_udp_port_filter_hdr) +
1611 arg->num * sizeof(struct wsm_udp_port_filter);
1612 return wsm_write_mib(priv, WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER,
1613 arg, size);
1614}
1615
1616/* Undocumented MIBs: */
1617/* 4.35 P2PDeviceInfo */
1618#define D11_MAX_SSID_LEN (32)
1619
1620struct wsm_p2p_device_type {
1621 __le16 categoryId;
1622 u8 oui[4];
1623 __le16 subCategoryId;
1624} __packed;
1625
1626struct wsm_p2p_device_info {
1627 struct wsm_p2p_device_type primaryDevice;
1628 u8 reserved1[3];
1629 u8 devNameSize;
1630 u8 localDevName[D11_MAX_SSID_LEN];
1631 u8 reserved2[3];
1632 u8 numSecDevSupported;
1633 struct wsm_p2p_device_type secondaryDevices[0];
1634} __packed;
1635
1636/* 4.36 SetWCDMABand - WO */
1637struct wsm_cdma_band {
1638 u8 WCDMA_Band;
1639 u8 reserved[3];
1640} __packed;
1641
1642/* 4.37 GroupTxSequenceCounter - RO */
1643struct wsm_group_tx_seq {
1644 __le32 bits_47_16;
1645 __le16 bits_15_00;
1646 __le16 reserved;
1647} __packed;
1648
1649/* 4.39 SetHtProtection - WO */
1650#define WSM_DUAL_CTS_PROT_ENB (1 << 0)
1651#define WSM_NON_GREENFIELD_STA_PRESENT (1 << 1)
1652#define WSM_HT_PROT_MODE__NO_PROT (0 << 2)
1653#define WSM_HT_PROT_MODE__NON_MEMBER (1 << 2)
1654#define WSM_HT_PROT_MODE__20_MHZ (2 << 2)
1655#define WSM_HT_PROT_MODE__NON_HT_MIXED (3 << 2)
1656#define WSM_LSIG_TXOP_PROT_FULL (1 << 4)
1657#define WSM_LARGE_L_LENGTH_PROT (1 << 5)
1658
1659struct wsm_ht_protection {
1660 __le32 flags;
1661} __packed;
1662
1663/* 4.40 GPIO Command - R/W */
1664#define WSM_GPIO_COMMAND_SETUP 0
1665#define WSM_GPIO_COMMAND_READ 1
1666#define WSM_GPIO_COMMAND_WRITE 2
1667#define WSM_GPIO_COMMAND_RESET 3
1668#define WSM_GPIO_ALL_PINS 0xFF
1669
1670struct wsm_gpio_command {
1671 u8 GPIO_Command;
1672 u8 pin;
1673 __le16 config;
1674} __packed;
1675
1676/* 4.41 TSFCounter - RO */
1677struct wsm_tsf_counter {
1678 __le64 TSF_Counter;
1679} __packed;
1680
1681/* 4.43 Keep alive period */
1682struct wsm_keep_alive_period {
1683 __le16 keepAlivePeriod;
1684 u8 reserved[2];
1685} __packed;
1686
1687static inline int wsm_keep_alive_period(struct cw1200_common *priv,
1688 int period)
1689{
1690 struct wsm_keep_alive_period arg = {
1691 .keepAlivePeriod = __cpu_to_le16(period),
1692 };
1693 return wsm_write_mib(priv, WSM_MIB_ID_KEEP_ALIVE_PERIOD,
1694 &arg, sizeof(arg));
1695};
1696
1697/* BSSID filtering */
1698struct wsm_set_bssid_filtering {
1699 u8 filter;
1700 u8 reserved[3];
1701} __packed;
1702
1703static inline int wsm_set_bssid_filtering(struct cw1200_common *priv,
1704 bool enabled)
1705{
1706 struct wsm_set_bssid_filtering arg = {
1707 .filter = !enabled,
1708 };
1709 return wsm_write_mib(priv, WSM_MIB_ID_DISABLE_BSSID_FILTER,
1710 &arg, sizeof(arg));
1711}
1712
1713/* Multicast filtering - 4.5 */
1714struct wsm_mib_multicast_filter {
1715 __le32 enable;
1716 __le32 num_addrs;
1717 u8 macaddrs[WSM_MAX_GRP_ADDRTABLE_ENTRIES][ETH_ALEN];
1718} __packed;
1719
1720static inline int wsm_set_multicast_filter(struct cw1200_common *priv,
1721 struct wsm_mib_multicast_filter *fp)
1722{
1723 return wsm_write_mib(priv, WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE,
1724 fp, sizeof(*fp));
1725}
1726
1727/* ARP IPv4 filtering - 4.10 */
1728struct wsm_mib_arp_ipv4_filter {
1729 __le32 enable;
1730 __be32 ipv4addrs[WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES];
1731} __packed;
1732
1733static inline int wsm_set_arp_ipv4_filter(struct cw1200_common *priv,
1734 struct wsm_mib_arp_ipv4_filter *fp)
1735{
1736 return wsm_write_mib(priv, WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE,
1737 fp, sizeof(*fp));
1738}
1739
1740/* P2P Power Save Mode Info - 4.31 */
1741struct wsm_p2p_ps_modeinfo {
1742 u8 oppPsCTWindow;
1743 u8 count;
1744 u8 reserved;
1745 u8 dtimCount;
1746 __le32 duration;
1747 __le32 interval;
1748 __le32 startTime;
1749} __packed;
1750
1751static inline int wsm_set_p2p_ps_modeinfo(struct cw1200_common *priv,
1752 struct wsm_p2p_ps_modeinfo *mi)
1753{
1754 return wsm_write_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
1755 mi, sizeof(*mi));
1756}
1757
1758static inline int wsm_get_p2p_ps_modeinfo(struct cw1200_common *priv,
1759 struct wsm_p2p_ps_modeinfo *mi)
1760{
1761 return wsm_read_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
1762 mi, sizeof(*mi));
1763}
1764
1765/* UseMultiTxConfMessage */
1766
1767static inline int wsm_use_multi_tx_conf(struct cw1200_common *priv,
1768 bool enabled)
1769{
1770 __le32 arg = enabled ? __cpu_to_le32(1) : 0;
1771
1772 return wsm_write_mib(priv, WSM_MIB_USE_MULTI_TX_CONF,
1773 &arg, sizeof(arg));
1774}
1775
1776
1777/* 4.26 SetUpasdInformation */
1778struct wsm_uapsd_info {
1779 __le16 uapsd_flags;
1780 __le16 min_auto_trigger_interval;
1781 __le16 max_auto_trigger_interval;
1782 __le16 auto_trigger_step;
1783};
1784
1785static inline int wsm_set_uapsd_info(struct cw1200_common *priv,
1786 struct wsm_uapsd_info *arg)
1787{
1788 return wsm_write_mib(priv, WSM_MIB_ID_SET_UAPSD_INFORMATION,
1789 arg, sizeof(*arg));
1790}
1791
1792/* 4.22 OverrideInternalTxRate */
1793struct wsm_override_internal_txrate {
1794 u8 internalTxRate;
1795 u8 nonErpInternalTxRate;
1796 u8 reserved[2];
1797} __packed;
1798
1799static inline int wsm_set_override_internal_txrate(struct cw1200_common *priv,
1800 struct wsm_override_internal_txrate *arg)
1801{
1802 return wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
1803 arg, sizeof(*arg));
1804}
1805
1806/* ******************************************************************** */
1807/* WSM TX port control */
1808
1809void wsm_lock_tx(struct cw1200_common *priv);
1810void wsm_lock_tx_async(struct cw1200_common *priv);
1811bool wsm_flush_tx(struct cw1200_common *priv);
1812void wsm_unlock_tx(struct cw1200_common *priv);
1813
1814/* ******************************************************************** */
1815/* WSM / BH API */
1816
1817int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len);
1818int wsm_handle_rx(struct cw1200_common *priv, u16 id, struct wsm_hdr *wsm,
1819 struct sk_buff **skb_p);
1820
1821/* ******************************************************************** */
1822/* wsm_buf API */
1823
1824struct wsm_buf {
1825 u8 *begin;
1826 u8 *data;
1827 u8 *end;
1828};
1829
1830void wsm_buf_init(struct wsm_buf *buf);
1831void wsm_buf_deinit(struct wsm_buf *buf);
1832
1833/* ******************************************************************** */
1834/* wsm_cmd API */
1835
1836struct wsm_cmd {
1837 spinlock_t lock; /* Protect structure from multiple access */
1838 int done;
1839 u8 *ptr;
1840 size_t len;
1841 void *arg;
1842 int ret;
1843 u16 cmd;
1844};
1845
1846/* ******************************************************************** */
1847/* WSM TX buffer access */
1848
1849int wsm_get_tx(struct cw1200_common *priv, u8 **data,
1850 size_t *tx_len, int *burst);
1851void wsm_txed(struct cw1200_common *priv, u8 *data);
1852
1853/* ******************************************************************** */
1854/* Queue mapping: WSM <---> linux */
1855/* Linux: VO VI BE BK */
1856/* WSM: BE BK VI VO */
1857
1858static inline u8 wsm_queue_id_to_linux(u8 queue_id)
1859{
1860 static const u8 queue_mapping[] = {
1861 2, 3, 1, 0
1862 };
1863 return queue_mapping[queue_id];
1864}
1865
1866static inline u8 wsm_queue_id_to_wsm(u8 queue_id)
1867{
1868 static const u8 queue_mapping[] = {
1869 3, 2, 0, 1
1870 };
1871 return queue_mapping[queue_id];
1872}
1873
1874
1875#ifdef CONFIG_CW1200_ETF
1876int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len);
1877#endif
1878
1879#endif /* CW1200_HWIO_H_INCLUDED */
diff --git a/include/linux/cw1200_platform.h b/include/linux/cw1200_platform.h
new file mode 100644
index 000000000000..c168fa512347
--- /dev/null
+++ b/include/linux/cw1200_platform.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2011
3 *
4 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
5 * License terms: GNU General Public License (GPL) version 2
6 */
7
8#ifndef CW1200_PLAT_H_INCLUDED
9#define CW1200_PLAT_H_INCLUDED
10
11struct cw1200_platform_data_spi {
12 u8 spi_bits_per_word; /* REQUIRED */
13 u16 ref_clk; /* REQUIRED (in KHz) */
14
15 /* All others are optional */
16 bool have_5ghz;
17 const struct resource *reset; /* GPIO to RSTn signal */
18 const struct resource *powerup; /* GPIO to POWERUP signal */
19 int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
20 bool enable); /* Control 3v3 / 1v8 supply */
21 int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
22 bool enable); /* Control CLK32K */
23 const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
24 const char *sdd_file; /* if NULL, will use default for detected hw type */
25};
26
27struct cw1200_platform_data_sdio {
28 u16 ref_clk; /* REQUIRED (in KHz) */
29
30 /* All others are optional */
31 const struct resource *irq; /* if using GPIO for IRQ */
32 bool have_5ghz;
33 bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
34 const struct resource *reset; /* GPIO to RSTn signal */
35 const struct resource *powerup; /* GPIO to POWERUP signal */
36 int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
37 bool enable); /* Control 3v3 / 1v8 supply */
38 int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
39 bool enable); /* Control CLK32K */
40 const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
41 const char *sdd_file; /* if NULL, will use default for detected hw type */
42};
43
44const void *cw1200_get_platform_data(void);
45
46#endif /* CW1200_PLAT_H_INCLUDED */