aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/acx.c
diff options
context:
space:
mode:
authorShahar Levi <shahar_levi@ti.com>2010-11-08 06:20:10 -0500
committerLuciano Coelho <luciano.coelho@nokia.com>2010-11-22 09:45:09 -0500
commit00d201001bd4e8a46e3d03c970abcb72256c368b (patch)
tree2d3d6b971c9e0ac68ffd5edca1c596eeab247451 /drivers/net/wireless/wl12xx/acx.c
parenta76a574ca9ce7c05791cee42f000f2a42c687837 (diff)
wl1271: Change wl12xx Files Names
All files name prefix removed due to the fact that wl12xx driver supports wl1271 and wl1273. Also the definition in Kconfig and header files changed respectively. Signed-off-by: Shahar Levi <shahar_levi@ti.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/acx.c')
-rw-r--r--drivers/net/wireless/wl12xx/acx.c1336
1 files changed, 1336 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
new file mode 100644
index 000000000000..bc1085bb6cfb
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -0,0 +1,1336 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include "acx.h"
25
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/crc7.h>
29#include <linux/spi/spi.h>
30#include <linux/slab.h>
31
32#include "wl12xx.h"
33#include "wl12xx_80211.h"
34#include "reg.h"
35#include "ps.h"
36
37int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
38{
39 struct acx_wake_up_condition *wake_up;
40 int ret;
41
42 wl1271_debug(DEBUG_ACX, "acx wake up conditions");
43
44 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
45 if (!wake_up) {
46 ret = -ENOMEM;
47 goto out;
48 }
49
50 wake_up->wake_up_event = wl->conf.conn.wake_up_event;
51 wake_up->listen_interval = wl->conf.conn.listen_interval;
52
53 ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
54 wake_up, sizeof(*wake_up));
55 if (ret < 0) {
56 wl1271_warning("could not set wake up conditions: %d", ret);
57 goto out;
58 }
59
60out:
61 kfree(wake_up);
62 return ret;
63}
64
65int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
66{
67 struct acx_sleep_auth *auth;
68 int ret;
69
70 wl1271_debug(DEBUG_ACX, "acx sleep auth");
71
72 auth = kzalloc(sizeof(*auth), GFP_KERNEL);
73 if (!auth) {
74 ret = -ENOMEM;
75 goto out;
76 }
77
78 auth->sleep_auth = sleep_auth;
79
80 ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
81 if (ret < 0)
82 return ret;
83
84out:
85 kfree(auth);
86 return ret;
87}
88
89int wl1271_acx_tx_power(struct wl1271 *wl, int power)
90{
91 struct acx_current_tx_power *acx;
92 int ret;
93
94 wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
95
96 if (power < 0 || power > 25)
97 return -EINVAL;
98
99 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
100 if (!acx) {
101 ret = -ENOMEM;
102 goto out;
103 }
104
105 acx->current_tx_power = power * 10;
106
107 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
108 if (ret < 0) {
109 wl1271_warning("configure of tx power failed: %d", ret);
110 goto out;
111 }
112
113out:
114 kfree(acx);
115 return ret;
116}
117
118int wl1271_acx_feature_cfg(struct wl1271 *wl)
119{
120 struct acx_feature_config *feature;
121 int ret;
122
123 wl1271_debug(DEBUG_ACX, "acx feature cfg");
124
125 feature = kzalloc(sizeof(*feature), GFP_KERNEL);
126 if (!feature) {
127 ret = -ENOMEM;
128 goto out;
129 }
130
131 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
132 feature->data_flow_options = 0;
133 feature->options = 0;
134
135 ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
136 feature, sizeof(*feature));
137 if (ret < 0) {
138 wl1271_error("Couldnt set HW encryption");
139 goto out;
140 }
141
142out:
143 kfree(feature);
144 return ret;
145}
146
147int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
148 size_t len)
149{
150 int ret;
151
152 wl1271_debug(DEBUG_ACX, "acx mem map");
153
154 ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
155 if (ret < 0)
156 return ret;
157
158 return 0;
159}
160
161int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
162{
163 struct acx_rx_msdu_lifetime *acx;
164 int ret;
165
166 wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
167
168 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
169 if (!acx) {
170 ret = -ENOMEM;
171 goto out;
172 }
173
174 acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time);
175 ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
176 acx, sizeof(*acx));
177 if (ret < 0) {
178 wl1271_warning("failed to set rx msdu life time: %d", ret);
179 goto out;
180 }
181
182out:
183 kfree(acx);
184 return ret;
185}
186
187int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter)
188{
189 struct acx_rx_config *rx_config;
190 int ret;
191
192 wl1271_debug(DEBUG_ACX, "acx rx config");
193
194 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
195 if (!rx_config) {
196 ret = -ENOMEM;
197 goto out;
198 }
199
200 rx_config->config_options = cpu_to_le32(config);
201 rx_config->filter_options = cpu_to_le32(filter);
202
203 ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
204 rx_config, sizeof(*rx_config));
205 if (ret < 0) {
206 wl1271_warning("failed to set rx config: %d", ret);
207 goto out;
208 }
209
210out:
211 kfree(rx_config);
212 return ret;
213}
214
215int wl1271_acx_pd_threshold(struct wl1271 *wl)
216{
217 struct acx_packet_detection *pd;
218 int ret;
219
220 wl1271_debug(DEBUG_ACX, "acx data pd threshold");
221
222 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
223 if (!pd) {
224 ret = -ENOMEM;
225 goto out;
226 }
227
228 pd->threshold = cpu_to_le32(wl->conf.rx.packet_detection_threshold);
229
230 ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
231 if (ret < 0) {
232 wl1271_warning("failed to set pd threshold: %d", ret);
233 goto out;
234 }
235
236out:
237 kfree(pd);
238 return ret;
239}
240
241int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
242{
243 struct acx_slot *slot;
244 int ret;
245
246 wl1271_debug(DEBUG_ACX, "acx slot");
247
248 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
249 if (!slot) {
250 ret = -ENOMEM;
251 goto out;
252 }
253
254 slot->wone_index = STATION_WONE_INDEX;
255 slot->slot_time = slot_time;
256
257 ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
258 if (ret < 0) {
259 wl1271_warning("failed to set slot time: %d", ret);
260 goto out;
261 }
262
263out:
264 kfree(slot);
265 return ret;
266}
267
268int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
269 void *mc_list, u32 mc_list_len)
270{
271 struct acx_dot11_grp_addr_tbl *acx;
272 int ret;
273
274 wl1271_debug(DEBUG_ACX, "acx group address tbl");
275
276 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
277 if (!acx) {
278 ret = -ENOMEM;
279 goto out;
280 }
281
282 /* MAC filtering */
283 acx->enabled = enable;
284 acx->num_groups = mc_list_len;
285 memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
286
287 ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
288 acx, sizeof(*acx));
289 if (ret < 0) {
290 wl1271_warning("failed to set group addr table: %d", ret);
291 goto out;
292 }
293
294out:
295 kfree(acx);
296 return ret;
297}
298
299int wl1271_acx_service_period_timeout(struct wl1271 *wl)
300{
301 struct acx_rx_timeout *rx_timeout;
302 int ret;
303
304 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
305 if (!rx_timeout) {
306 ret = -ENOMEM;
307 goto out;
308 }
309
310 wl1271_debug(DEBUG_ACX, "acx service period timeout");
311
312 rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout);
313 rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout);
314
315 ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
316 rx_timeout, sizeof(*rx_timeout));
317 if (ret < 0) {
318 wl1271_warning("failed to set service period timeout: %d",
319 ret);
320 goto out;
321 }
322
323out:
324 kfree(rx_timeout);
325 return ret;
326}
327
328int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
329{
330 struct acx_rts_threshold *rts;
331 int ret;
332
333 wl1271_debug(DEBUG_ACX, "acx rts threshold");
334
335 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
336 if (!rts) {
337 ret = -ENOMEM;
338 goto out;
339 }
340
341 rts->threshold = cpu_to_le16(rts_threshold);
342
343 ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
344 if (ret < 0) {
345 wl1271_warning("failed to set rts threshold: %d", ret);
346 goto out;
347 }
348
349out:
350 kfree(rts);
351 return ret;
352}
353
354int wl1271_acx_dco_itrim_params(struct wl1271 *wl)
355{
356 struct acx_dco_itrim_params *dco;
357 struct conf_itrim_settings *c = &wl->conf.itrim;
358 int ret;
359
360 wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
361
362 dco = kzalloc(sizeof(*dco), GFP_KERNEL);
363 if (!dco) {
364 ret = -ENOMEM;
365 goto out;
366 }
367
368 dco->enable = c->enable;
369 dco->timeout = cpu_to_le32(c->timeout);
370
371 ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
372 dco, sizeof(*dco));
373 if (ret < 0) {
374 wl1271_warning("failed to set dco itrim parameters: %d", ret);
375 goto out;
376 }
377
378out:
379 kfree(dco);
380 return ret;
381}
382
383int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
384{
385 struct acx_beacon_filter_option *beacon_filter = NULL;
386 int ret = 0;
387
388 wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
389
390 if (enable_filter &&
391 wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
392 goto out;
393
394 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
395 if (!beacon_filter) {
396 ret = -ENOMEM;
397 goto out;
398 }
399
400 beacon_filter->enable = enable_filter;
401
402 /*
403 * When set to zero, and the filter is enabled, beacons
404 * without the unicast TIM bit set are dropped.
405 */
406 beacon_filter->max_num_beacons = 0;
407
408 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
409 beacon_filter, sizeof(*beacon_filter));
410 if (ret < 0) {
411 wl1271_warning("failed to set beacon filter opt: %d", ret);
412 goto out;
413 }
414
415out:
416 kfree(beacon_filter);
417 return ret;
418}
419
420int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
421{
422 struct acx_beacon_filter_ie_table *ie_table;
423 int i, idx = 0;
424 int ret;
425 bool vendor_spec = false;
426
427 wl1271_debug(DEBUG_ACX, "acx beacon filter table");
428
429 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
430 if (!ie_table) {
431 ret = -ENOMEM;
432 goto out;
433 }
434
435 /* configure default beacon pass-through rules */
436 ie_table->num_ie = 0;
437 for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) {
438 struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]);
439 ie_table->table[idx++] = r->ie;
440 ie_table->table[idx++] = r->rule;
441
442 if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
443 /* only one vendor specific ie allowed */
444 if (vendor_spec)
445 continue;
446
447 /* for vendor specific rules configure the
448 additional fields */
449 memcpy(&(ie_table->table[idx]), r->oui,
450 CONF_BCN_IE_OUI_LEN);
451 idx += CONF_BCN_IE_OUI_LEN;
452 ie_table->table[idx++] = r->type;
453 memcpy(&(ie_table->table[idx]), r->version,
454 CONF_BCN_IE_VER_LEN);
455 idx += CONF_BCN_IE_VER_LEN;
456 vendor_spec = true;
457 }
458
459 ie_table->num_ie++;
460 }
461
462 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
463 ie_table, sizeof(*ie_table));
464 if (ret < 0) {
465 wl1271_warning("failed to set beacon filter table: %d", ret);
466 goto out;
467 }
468
469out:
470 kfree(ie_table);
471 return ret;
472}
473
474#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff
475
476int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
477{
478 struct acx_conn_monit_params *acx;
479 u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
480 u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
481 int ret;
482
483 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
484 enable ? "enabled" : "disabled");
485
486 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
487 if (!acx) {
488 ret = -ENOMEM;
489 goto out;
490 }
491
492 if (enable) {
493 threshold = wl->conf.conn.synch_fail_thold;
494 timeout = wl->conf.conn.bss_lose_timeout;
495 }
496
497 acx->synch_fail_thold = cpu_to_le32(threshold);
498 acx->bss_lose_timeout = cpu_to_le32(timeout);
499
500 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
501 acx, sizeof(*acx));
502 if (ret < 0) {
503 wl1271_warning("failed to set connection monitor "
504 "parameters: %d", ret);
505 goto out;
506 }
507
508out:
509 kfree(acx);
510 return ret;
511}
512
513
514int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
515{
516 struct acx_bt_wlan_coex *pta;
517 int ret;
518
519 wl1271_debug(DEBUG_ACX, "acx sg enable");
520
521 pta = kzalloc(sizeof(*pta), GFP_KERNEL);
522 if (!pta) {
523 ret = -ENOMEM;
524 goto out;
525 }
526
527 if (enable)
528 pta->enable = wl->conf.sg.state;
529 else
530 pta->enable = CONF_SG_DISABLE;
531
532 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
533 if (ret < 0) {
534 wl1271_warning("failed to set softgemini enable: %d", ret);
535 goto out;
536 }
537
538out:
539 kfree(pta);
540 return ret;
541}
542
543int wl1271_acx_sg_cfg(struct wl1271 *wl)
544{
545 struct acx_bt_wlan_coex_param *param;
546 struct conf_sg_settings *c = &wl->conf.sg;
547 int i, ret;
548
549 wl1271_debug(DEBUG_ACX, "acx sg cfg");
550
551 param = kzalloc(sizeof(*param), GFP_KERNEL);
552 if (!param) {
553 ret = -ENOMEM;
554 goto out;
555 }
556
557 /* BT-WLAN coext parameters */
558 for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
559 param->params[i] = cpu_to_le32(c->params[i]);
560 param->param_idx = CONF_SG_PARAMS_ALL;
561
562 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
563 if (ret < 0) {
564 wl1271_warning("failed to set sg config: %d", ret);
565 goto out;
566 }
567
568out:
569 kfree(param);
570 return ret;
571}
572
573int wl1271_acx_cca_threshold(struct wl1271 *wl)
574{
575 struct acx_energy_detection *detection;
576 int ret;
577
578 wl1271_debug(DEBUG_ACX, "acx cca threshold");
579
580 detection = kzalloc(sizeof(*detection), GFP_KERNEL);
581 if (!detection) {
582 ret = -ENOMEM;
583 goto out;
584 }
585
586 detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold);
587 detection->tx_energy_detection = wl->conf.tx.tx_energy_detection;
588
589 ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
590 detection, sizeof(*detection));
591 if (ret < 0) {
592 wl1271_warning("failed to set cca threshold: %d", ret);
593 return ret;
594 }
595
596out:
597 kfree(detection);
598 return ret;
599}
600
601int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
602{
603 struct acx_beacon_broadcast *bb;
604 int ret;
605
606 wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
607
608 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
609 if (!bb) {
610 ret = -ENOMEM;
611 goto out;
612 }
613
614 bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout);
615 bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout);
616 bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps;
617 bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold;
618
619 ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
620 if (ret < 0) {
621 wl1271_warning("failed to set rx config: %d", ret);
622 goto out;
623 }
624
625out:
626 kfree(bb);
627 return ret;
628}
629
630int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
631{
632 struct acx_aid *acx_aid;
633 int ret;
634
635 wl1271_debug(DEBUG_ACX, "acx aid");
636
637 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
638 if (!acx_aid) {
639 ret = -ENOMEM;
640 goto out;
641 }
642
643 acx_aid->aid = cpu_to_le16(aid);
644
645 ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
646 if (ret < 0) {
647 wl1271_warning("failed to set aid: %d", ret);
648 goto out;
649 }
650
651out:
652 kfree(acx_aid);
653 return ret;
654}
655
656int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
657{
658 struct acx_event_mask *mask;
659 int ret;
660
661 wl1271_debug(DEBUG_ACX, "acx event mbox mask");
662
663 mask = kzalloc(sizeof(*mask), GFP_KERNEL);
664 if (!mask) {
665 ret = -ENOMEM;
666 goto out;
667 }
668
669 /* high event mask is unused */
670 mask->high_event_mask = cpu_to_le32(0xffffffff);
671 mask->event_mask = cpu_to_le32(event_mask);
672
673 ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
674 mask, sizeof(*mask));
675 if (ret < 0) {
676 wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
677 goto out;
678 }
679
680out:
681 kfree(mask);
682 return ret;
683}
684
685int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
686{
687 struct acx_preamble *acx;
688 int ret;
689
690 wl1271_debug(DEBUG_ACX, "acx_set_preamble");
691
692 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
693 if (!acx) {
694 ret = -ENOMEM;
695 goto out;
696 }
697
698 acx->preamble = preamble;
699
700 ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
701 if (ret < 0) {
702 wl1271_warning("Setting of preamble failed: %d", ret);
703 goto out;
704 }
705
706out:
707 kfree(acx);
708 return ret;
709}
710
711int wl1271_acx_cts_protect(struct wl1271 *wl,
712 enum acx_ctsprotect_type ctsprotect)
713{
714 struct acx_ctsprotect *acx;
715 int ret;
716
717 wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
718
719 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
720 if (!acx) {
721 ret = -ENOMEM;
722 goto out;
723 }
724
725 acx->ctsprotect = ctsprotect;
726
727 ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
728 if (ret < 0) {
729 wl1271_warning("Setting of ctsprotect failed: %d", ret);
730 goto out;
731 }
732
733out:
734 kfree(acx);
735 return ret;
736}
737
738int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
739{
740 int ret;
741
742 wl1271_debug(DEBUG_ACX, "acx statistics");
743
744 ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
745 sizeof(*stats));
746 if (ret < 0) {
747 wl1271_warning("acx statistics failed: %d", ret);
748 return -ENOMEM;
749 }
750
751 return 0;
752}
753
754int wl1271_acx_rate_policies(struct wl1271 *wl)
755{
756 struct acx_rate_policy *acx;
757 struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf;
758 int idx = 0;
759 int ret = 0;
760
761 wl1271_debug(DEBUG_ACX, "acx rate policies");
762
763 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
764
765 if (!acx) {
766 ret = -ENOMEM;
767 goto out;
768 }
769
770 /* configure one basic rate class */
771 idx = ACX_TX_BASIC_RATE;
772 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate);
773 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
774 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
775 acx->rate_class[idx].aflags = c->aflags;
776
777 /* configure one AP supported rate class */
778 idx = ACX_TX_AP_FULL_RATE;
779 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set);
780 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
781 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
782 acx->rate_class[idx].aflags = c->aflags;
783
784 acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
785
786 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
787 if (ret < 0) {
788 wl1271_warning("Setting of rate policies failed: %d", ret);
789 goto out;
790 }
791
792out:
793 kfree(acx);
794 return ret;
795}
796
797int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
798 u8 aifsn, u16 txop)
799{
800 struct acx_ac_cfg *acx;
801 int ret = 0;
802
803 wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
804 "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
805
806 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
807
808 if (!acx) {
809 ret = -ENOMEM;
810 goto out;
811 }
812
813 acx->ac = ac;
814 acx->cw_min = cw_min;
815 acx->cw_max = cpu_to_le16(cw_max);
816 acx->aifsn = aifsn;
817 acx->tx_op_limit = cpu_to_le16(txop);
818
819 ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
820 if (ret < 0) {
821 wl1271_warning("acx ac cfg failed: %d", ret);
822 goto out;
823 }
824
825out:
826 kfree(acx);
827 return ret;
828}
829
830int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
831 u8 tsid, u8 ps_scheme, u8 ack_policy,
832 u32 apsd_conf0, u32 apsd_conf1)
833{
834 struct acx_tid_config *acx;
835 int ret = 0;
836
837 wl1271_debug(DEBUG_ACX, "acx tid config");
838
839 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
840
841 if (!acx) {
842 ret = -ENOMEM;
843 goto out;
844 }
845
846 acx->queue_id = queue_id;
847 acx->channel_type = channel_type;
848 acx->tsid = tsid;
849 acx->ps_scheme = ps_scheme;
850 acx->ack_policy = ack_policy;
851 acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
852 acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
853
854 ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
855 if (ret < 0) {
856 wl1271_warning("Setting of tid config failed: %d", ret);
857 goto out;
858 }
859
860out:
861 kfree(acx);
862 return ret;
863}
864
865int wl1271_acx_frag_threshold(struct wl1271 *wl)
866{
867 struct acx_frag_threshold *acx;
868 int ret = 0;
869
870 wl1271_debug(DEBUG_ACX, "acx frag threshold");
871
872 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
873
874 if (!acx) {
875 ret = -ENOMEM;
876 goto out;
877 }
878
879 acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold);
880 ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
881 if (ret < 0) {
882 wl1271_warning("Setting of frag threshold failed: %d", ret);
883 goto out;
884 }
885
886out:
887 kfree(acx);
888 return ret;
889}
890
891int wl1271_acx_tx_config_options(struct wl1271 *wl)
892{
893 struct acx_tx_config_options *acx;
894 int ret = 0;
895
896 wl1271_debug(DEBUG_ACX, "acx tx config options");
897
898 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
899
900 if (!acx) {
901 ret = -ENOMEM;
902 goto out;
903 }
904
905 acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout);
906 acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold);
907 ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
908 if (ret < 0) {
909 wl1271_warning("Setting of tx options failed: %d", ret);
910 goto out;
911 }
912
913out:
914 kfree(acx);
915 return ret;
916}
917
918int wl1271_acx_mem_cfg(struct wl1271 *wl)
919{
920 struct wl1271_acx_config_memory *mem_conf;
921 int ret;
922
923 wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
924
925 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
926 if (!mem_conf) {
927 ret = -ENOMEM;
928 goto out;
929 }
930
931 /* memory config */
932 mem_conf->num_stations = DEFAULT_NUM_STATIONS;
933 mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
934 mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
935 mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
936 mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
937
938 ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
939 sizeof(*mem_conf));
940 if (ret < 0) {
941 wl1271_warning("wl1271 mem config failed: %d", ret);
942 goto out;
943 }
944
945out:
946 kfree(mem_conf);
947 return ret;
948}
949
950int wl1271_acx_init_mem_config(struct wl1271 *wl)
951{
952 int ret;
953
954 ret = wl1271_acx_mem_cfg(wl);
955 if (ret < 0)
956 return ret;
957
958 wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
959 GFP_KERNEL);
960 if (!wl->target_mem_map) {
961 wl1271_error("couldn't allocate target memory map");
962 return -ENOMEM;
963 }
964
965 /* we now ask for the firmware built memory map */
966 ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
967 sizeof(struct wl1271_acx_mem_map));
968 if (ret < 0) {
969 wl1271_error("couldn't retrieve firmware memory map");
970 kfree(wl->target_mem_map);
971 wl->target_mem_map = NULL;
972 return ret;
973 }
974
975 /* initialize TX block book keeping */
976 wl->tx_blocks_available =
977 le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks);
978 wl1271_debug(DEBUG_TX, "available tx blocks: %d",
979 wl->tx_blocks_available);
980
981 return 0;
982}
983
984int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
985{
986 struct wl1271_acx_rx_config_opt *rx_conf;
987 int ret;
988
989 wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
990
991 rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
992 if (!rx_conf) {
993 ret = -ENOMEM;
994 goto out;
995 }
996
997 rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold);
998 rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout);
999 rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold);
1000 rx_conf->queue_type = wl->conf.rx.queue_type;
1001
1002 ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
1003 sizeof(*rx_conf));
1004 if (ret < 0) {
1005 wl1271_warning("wl1271 rx config opt failed: %d", ret);
1006 goto out;
1007 }
1008
1009out:
1010 kfree(rx_conf);
1011 return ret;
1012}
1013
1014int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
1015{
1016 struct wl1271_acx_bet_enable *acx = NULL;
1017 int ret = 0;
1018
1019 wl1271_debug(DEBUG_ACX, "acx bet enable");
1020
1021 if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
1022 goto out;
1023
1024 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1025 if (!acx) {
1026 ret = -ENOMEM;
1027 goto out;
1028 }
1029
1030 acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
1031 acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
1032
1033 ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
1034 if (ret < 0) {
1035 wl1271_warning("acx bet enable failed: %d", ret);
1036 goto out;
1037 }
1038
1039out:
1040 kfree(acx);
1041 return ret;
1042}
1043
1044int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address)
1045{
1046 struct wl1271_acx_arp_filter *acx;
1047 int ret;
1048
1049 wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
1050
1051 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1052 if (!acx) {
1053 ret = -ENOMEM;
1054 goto out;
1055 }
1056
1057 acx->version = ACX_IPV4_VERSION;
1058 acx->enable = enable;
1059
1060 if (enable == true)
1061 memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
1062
1063 ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
1064 acx, sizeof(*acx));
1065 if (ret < 0) {
1066 wl1271_warning("failed to set arp ip filter: %d", ret);
1067 goto out;
1068 }
1069
1070out:
1071 kfree(acx);
1072 return ret;
1073}
1074
1075int wl1271_acx_pm_config(struct wl1271 *wl)
1076{
1077 struct wl1271_acx_pm_config *acx = NULL;
1078 struct conf_pm_config_settings *c = &wl->conf.pm_config;
1079 int ret = 0;
1080
1081 wl1271_debug(DEBUG_ACX, "acx pm config");
1082
1083 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1084 if (!acx) {
1085 ret = -ENOMEM;
1086 goto out;
1087 }
1088
1089 acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
1090 acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
1091
1092 ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
1093 if (ret < 0) {
1094 wl1271_warning("acx pm config failed: %d", ret);
1095 goto out;
1096 }
1097
1098out:
1099 kfree(acx);
1100 return ret;
1101}
1102
1103int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
1104{
1105 struct wl1271_acx_keep_alive_mode *acx = NULL;
1106 int ret = 0;
1107
1108 wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
1109
1110 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1111 if (!acx) {
1112 ret = -ENOMEM;
1113 goto out;
1114 }
1115
1116 acx->enabled = enable;
1117
1118 ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
1119 if (ret < 0) {
1120 wl1271_warning("acx keep alive mode failed: %d", ret);
1121 goto out;
1122 }
1123
1124out:
1125 kfree(acx);
1126 return ret;
1127}
1128
1129int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
1130{
1131 struct wl1271_acx_keep_alive_config *acx = NULL;
1132 int ret = 0;
1133
1134 wl1271_debug(DEBUG_ACX, "acx keep alive config");
1135
1136 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1137 if (!acx) {
1138 ret = -ENOMEM;
1139 goto out;
1140 }
1141
1142 acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
1143 acx->index = index;
1144 acx->tpl_validation = tpl_valid;
1145 acx->trigger = ACX_KEEP_ALIVE_NO_TX;
1146
1147 ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
1148 acx, sizeof(*acx));
1149 if (ret < 0) {
1150 wl1271_warning("acx keep alive config failed: %d", ret);
1151 goto out;
1152 }
1153
1154out:
1155 kfree(acx);
1156 return ret;
1157}
1158
1159int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1160 s16 thold, u8 hyst)
1161{
1162 struct wl1271_acx_rssi_snr_trigger *acx = NULL;
1163 int ret = 0;
1164
1165 wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
1166
1167 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1168 if (!acx) {
1169 ret = -ENOMEM;
1170 goto out;
1171 }
1172
1173 wl->last_rssi_event = -1;
1174
1175 acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
1176 acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
1177 acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
1178 if (enable)
1179 acx->enable = WL1271_ACX_TRIG_ENABLE;
1180 else
1181 acx->enable = WL1271_ACX_TRIG_DISABLE;
1182
1183 acx->index = WL1271_ACX_TRIG_IDX_RSSI;
1184 acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
1185 acx->threshold = cpu_to_le16(thold);
1186 acx->hysteresis = hyst;
1187
1188 ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
1189 if (ret < 0) {
1190 wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
1191 goto out;
1192 }
1193
1194out:
1195 kfree(acx);
1196 return ret;
1197}
1198
1199int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
1200{
1201 struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
1202 struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
1203 int ret = 0;
1204
1205 wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
1206
1207 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1208 if (!acx) {
1209 ret = -ENOMEM;
1210 goto out;
1211 }
1212
1213 acx->rssi_beacon = c->avg_weight_rssi_beacon;
1214 acx->rssi_data = c->avg_weight_rssi_data;
1215 acx->snr_beacon = c->avg_weight_snr_beacon;
1216 acx->snr_data = c->avg_weight_snr_data;
1217
1218 ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
1219 if (ret < 0) {
1220 wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
1221 goto out;
1222 }
1223
1224out:
1225 kfree(acx);
1226 return ret;
1227}
1228
1229int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1230 struct ieee80211_sta_ht_cap *ht_cap,
1231 bool allow_ht_operation)
1232{
1233 struct wl1271_acx_ht_capabilities *acx;
1234 u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1235 int ret = 0;
1236
1237 wl1271_debug(DEBUG_ACX, "acx ht capabilities setting");
1238
1239 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1240 if (!acx) {
1241 ret = -ENOMEM;
1242 goto out;
1243 }
1244
1245 /* Allow HT Operation ? */
1246 if (allow_ht_operation) {
1247 acx->ht_capabilites =
1248 WL1271_ACX_FW_CAP_HT_OPERATION;
1249 if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD)
1250 acx->ht_capabilites |=
1251 WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT;
1252 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
1253 acx->ht_capabilites |=
1254 WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS;
1255 if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT)
1256 acx->ht_capabilites |=
1257 WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION;
1258
1259 /* get data from A-MPDU parameters field */
1260 acx->ampdu_max_length = ht_cap->ampdu_factor;
1261 acx->ampdu_min_spacing = ht_cap->ampdu_density;
1262
1263 memcpy(acx->mac_address, mac_address, ETH_ALEN);
1264 } else { /* HT operations are not allowed */
1265 acx->ht_capabilites = 0;
1266 }
1267
1268 ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
1269 if (ret < 0) {
1270 wl1271_warning("acx ht capabilities setting failed: %d", ret);
1271 goto out;
1272 }
1273
1274out:
1275 kfree(acx);
1276 return ret;
1277}
1278
1279int wl1271_acx_set_ht_information(struct wl1271 *wl,
1280 u16 ht_operation_mode)
1281{
1282 struct wl1271_acx_ht_information *acx;
1283 int ret = 0;
1284
1285 wl1271_debug(DEBUG_ACX, "acx ht information setting");
1286
1287 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1288 if (!acx) {
1289 ret = -ENOMEM;
1290 goto out;
1291 }
1292
1293 acx->ht_protection =
1294 (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
1295 acx->rifs_mode = 0;
1296 acx->gf_protection = 0;
1297 acx->ht_tx_burst_limit = 0;
1298 acx->dual_cts_protection = 0;
1299
1300 ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
1301
1302 if (ret < 0) {
1303 wl1271_warning("acx ht information setting failed: %d", ret);
1304 goto out;
1305 }
1306
1307out:
1308 kfree(acx);
1309 return ret;
1310}
1311
1312int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
1313{
1314 struct wl1271_acx_fw_tsf_information *tsf_info;
1315 int ret;
1316
1317 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
1318 if (!tsf_info) {
1319 ret = -ENOMEM;
1320 goto out;
1321 }
1322
1323 ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
1324 tsf_info, sizeof(*tsf_info));
1325 if (ret < 0) {
1326 wl1271_warning("acx tsf info interrogate failed");
1327 goto out;
1328 }
1329
1330 *mactime = le32_to_cpu(tsf_info->current_tsf_low) |
1331 ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32);
1332
1333out:
1334 kfree(tsf_info);
1335 return ret;
1336}