]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/net/wireless/wl12xx/wl1271_acx.c
wl1271: Add structure for firmware configuration values
[net-next-2.6.git] / drivers / net / wireless / wl12xx / wl1271_acx.c
CommitLineData
f5fc0f86
LC
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 "wl1271_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
31#include "wl1271.h"
32#include "wl12xx_80211.h"
33#include "wl1271_reg.h"
34#include "wl1271_spi.h"
35#include "wl1271_ps.h"
36
37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
38 u8 listen_interval)
39{
40 struct acx_wake_up_condition *wake_up;
41 int ret;
42
43 wl1271_debug(DEBUG_ACX, "acx wake up conditions");
44
45 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
46 if (!wake_up) {
47 ret = -ENOMEM;
48 goto out;
49 }
50
51 wake_up->wake_up_event = wake_up_event;
52 wake_up->listen_interval = listen_interval;
53
54 ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
55 wake_up, sizeof(*wake_up));
56 if (ret < 0) {
57 wl1271_warning("could not set wake up conditions: %d", ret);
58 goto out;
59 }
60
61out:
62 kfree(wake_up);
63 return ret;
64}
65
66int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
67{
68 struct acx_sleep_auth *auth;
69 int ret;
70
71 wl1271_debug(DEBUG_ACX, "acx sleep auth");
72
73 auth = kzalloc(sizeof(*auth), GFP_KERNEL);
74 if (!auth) {
75 ret = -ENOMEM;
76 goto out;
77 }
78
79 auth->sleep_auth = sleep_auth;
80
81 ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
82 if (ret < 0)
83 return ret;
84
85out:
86 kfree(auth);
87 return ret;
88}
89
90int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
91{
92 struct acx_revision *rev;
93 int ret;
94
95 wl1271_debug(DEBUG_ACX, "acx fw rev");
96
97 rev = kzalloc(sizeof(*rev), GFP_KERNEL);
98 if (!rev) {
99 ret = -ENOMEM;
100 goto out;
101 }
102
103 ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
104 if (ret < 0) {
105 wl1271_warning("ACX_FW_REV interrogate failed");
106 goto out;
107 }
108
109 /* be careful with the buffer sizes */
110 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
111
112 /*
113 * if the firmware version string is exactly
114 * sizeof(rev->fw_version) long or fw_len is less than
115 * sizeof(rev->fw_version) it won't be null terminated
116 */
117 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
118
119out:
120 kfree(rev);
121 return ret;
122}
123
124int wl1271_acx_tx_power(struct wl1271 *wl, int power)
125{
126 struct acx_current_tx_power *acx;
127 int ret;
128
129 wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
130
131 if (power < 0 || power > 25)
132 return -EINVAL;
133
134 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
135 if (!acx) {
136 ret = -ENOMEM;
137 goto out;
138 }
139
ac78403e
LC
140 /*
141 * FIXME: This is a workaround needed while we don't the correct
142 * calibration, to avoid distortions
143 */
144 /* acx->current_tx_power = power * 10; */
145 acx->current_tx_power = 70;
f5fc0f86
LC
146
147 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
148 if (ret < 0) {
149 wl1271_warning("configure of tx power failed: %d", ret);
150 goto out;
151 }
152
153out:
154 kfree(acx);
155 return ret;
156}
157
158int wl1271_acx_feature_cfg(struct wl1271 *wl)
159{
160 struct acx_feature_config *feature;
161 int ret;
162
163 wl1271_debug(DEBUG_ACX, "acx feature cfg");
164
165 feature = kzalloc(sizeof(*feature), GFP_KERNEL);
166 if (!feature) {
167 ret = -ENOMEM;
168 goto out;
169 }
170
171 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
172 feature->data_flow_options = 0;
173 feature->options = 0;
174
175 ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
176 feature, sizeof(*feature));
177 if (ret < 0) {
178 wl1271_error("Couldnt set HW encryption");
179 goto out;
180 }
181
182out:
183 kfree(feature);
184 return ret;
185}
186
187int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
188 size_t len)
189{
190 int ret;
191
192 wl1271_debug(DEBUG_ACX, "acx mem map");
193
194 ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
195 if (ret < 0)
196 return ret;
197
198 return 0;
199}
200
201int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time)
202{
203 struct acx_rx_msdu_lifetime *acx;
204 int ret;
205
206 wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
207
208 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
209 if (!acx) {
210 ret = -ENOMEM;
211 goto out;
212 }
213
214 acx->lifetime = life_time;
215 ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
216 acx, sizeof(*acx));
217 if (ret < 0) {
218 wl1271_warning("failed to set rx msdu life time: %d", ret);
219 goto out;
220 }
221
222out:
223 kfree(acx);
224 return ret;
225}
226
227int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter)
228{
229 struct acx_rx_config *rx_config;
230 int ret;
231
232 wl1271_debug(DEBUG_ACX, "acx rx config");
233
234 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
235 if (!rx_config) {
236 ret = -ENOMEM;
237 goto out;
238 }
239
240 rx_config->config_options = config;
241 rx_config->filter_options = filter;
242
243 ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
244 rx_config, sizeof(*rx_config));
245 if (ret < 0) {
246 wl1271_warning("failed to set rx config: %d", ret);
247 goto out;
248 }
249
250out:
251 kfree(rx_config);
252 return ret;
253}
254
255int wl1271_acx_pd_threshold(struct wl1271 *wl)
256{
257 struct acx_packet_detection *pd;
258 int ret;
259
260 wl1271_debug(DEBUG_ACX, "acx data pd threshold");
261
262 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
263 if (!pd) {
264 ret = -ENOMEM;
265 goto out;
266 }
267
268 /* FIXME: threshold value not set */
269
270 ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
271 if (ret < 0) {
272 wl1271_warning("failed to set pd threshold: %d", ret);
273 goto out;
274 }
275
276out:
277 kfree(pd);
278 return 0;
279}
280
281int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
282{
283 struct acx_slot *slot;
284 int ret;
285
286 wl1271_debug(DEBUG_ACX, "acx slot");
287
288 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
289 if (!slot) {
290 ret = -ENOMEM;
291 goto out;
292 }
293
294 slot->wone_index = STATION_WONE_INDEX;
295 slot->slot_time = slot_time;
296
297 ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
298 if (ret < 0) {
299 wl1271_warning("failed to set slot time: %d", ret);
300 goto out;
301 }
302
303out:
304 kfree(slot);
305 return ret;
306}
307
c87dec9f
JO
308int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
309 void *mc_list, u32 mc_list_len)
f5fc0f86
LC
310{
311 struct acx_dot11_grp_addr_tbl *acx;
312 int ret;
313
314 wl1271_debug(DEBUG_ACX, "acx group address tbl");
315
316 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
317 if (!acx) {
318 ret = -ENOMEM;
319 goto out;
320 }
321
322 /* MAC filtering */
c87dec9f
JO
323 acx->enabled = enable;
324 acx->num_groups = mc_list_len;
325 memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
f5fc0f86
LC
326
327 ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
328 acx, sizeof(*acx));
329 if (ret < 0) {
330 wl1271_warning("failed to set group addr table: %d", ret);
331 goto out;
332 }
333
334out:
335 kfree(acx);
336 return ret;
337}
338
339int wl1271_acx_service_period_timeout(struct wl1271 *wl)
340{
341 struct acx_rx_timeout *rx_timeout;
342 int ret;
343
344 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
345 if (!rx_timeout) {
346 ret = -ENOMEM;
347 goto out;
348 }
349
350 wl1271_debug(DEBUG_ACX, "acx service period timeout");
351
352 rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
353 rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
354
355 ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
356 rx_timeout, sizeof(*rx_timeout));
357 if (ret < 0) {
358 wl1271_warning("failed to set service period timeout: %d",
359 ret);
360 goto out;
361 }
362
363out:
364 kfree(rx_timeout);
365 return ret;
366}
367
368int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
369{
370 struct acx_rts_threshold *rts;
371 int ret;
372
373 wl1271_debug(DEBUG_ACX, "acx rts threshold");
374
375 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
376 if (!rts) {
377 ret = -ENOMEM;
378 goto out;
379 }
380
381 rts->threshold = rts_threshold;
382
383 ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
384 if (ret < 0) {
385 wl1271_warning("failed to set rts threshold: %d", ret);
386 goto out;
387 }
388
389out:
390 kfree(rts);
391 return ret;
392}
393
1922167b 394int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
f5fc0f86
LC
395{
396 struct acx_beacon_filter_option *beacon_filter;
397 int ret;
398
399 wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
400
401 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
402 if (!beacon_filter) {
403 ret = -ENOMEM;
404 goto out;
405 }
406
1922167b 407 beacon_filter->enable = enable_filter;
f5fc0f86
LC
408 beacon_filter->max_num_beacons = 0;
409
410 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
411 beacon_filter, sizeof(*beacon_filter));
412 if (ret < 0) {
413 wl1271_warning("failed to set beacon filter opt: %d", ret);
414 goto out;
415 }
416
417out:
418 kfree(beacon_filter);
419 return ret;
420}
421
422int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
423{
424 struct acx_beacon_filter_ie_table *ie_table;
1922167b 425 int idx = 0;
f5fc0f86
LC
426 int ret;
427
428 wl1271_debug(DEBUG_ACX, "acx beacon filter table");
429
430 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
431 if (!ie_table) {
432 ret = -ENOMEM;
433 goto out;
434 }
435
1922167b
JO
436 /* configure default beacon pass-through rules */
437 ie_table->num_ie = 1;
438 ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
439 ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
f5fc0f86
LC
440
441 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
442 ie_table, sizeof(*ie_table));
443 if (ret < 0) {
444 wl1271_warning("failed to set beacon filter table: %d", ret);
445 goto out;
446 }
447
448out:
449 kfree(ie_table);
450 return ret;
451}
452
34415236
JO
453int wl1271_acx_conn_monit_params(struct wl1271 *wl)
454{
455 struct acx_conn_monit_params *acx;
456 int ret;
457
458 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters");
459
460 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
461 if (!acx) {
462 ret = -ENOMEM;
463 goto out;
464 }
465
466 acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
467 acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
468
469 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
470 acx, sizeof(*acx));
471 if (ret < 0) {
472 wl1271_warning("failed to set connection monitor "
473 "parameters: %d", ret);
474 goto out;
475 }
476
477out:
478 kfree(acx);
479 return ret;
480}
481
482
f5fc0f86
LC
483int wl1271_acx_sg_enable(struct wl1271 *wl)
484{
485 struct acx_bt_wlan_coex *pta;
486 int ret;
487
488 wl1271_debug(DEBUG_ACX, "acx sg enable");
489
490 pta = kzalloc(sizeof(*pta), GFP_KERNEL);
491 if (!pta) {
492 ret = -ENOMEM;
493 goto out;
494 }
495
496 pta->enable = SG_ENABLE;
497
498 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
499 if (ret < 0) {
500 wl1271_warning("failed to set softgemini enable: %d", ret);
501 goto out;
502 }
503
504out:
505 kfree(pta);
506 return ret;
507}
508
509int wl1271_acx_sg_cfg(struct wl1271 *wl)
510{
511 struct acx_bt_wlan_coex_param *param;
2b60100b 512 struct conf_sg_settings *c = &wl->conf.sg;
f5fc0f86
LC
513 int ret;
514
515 wl1271_debug(DEBUG_ACX, "acx sg cfg");
516
517 param = kzalloc(sizeof(*param), GFP_KERNEL);
518 if (!param) {
519 ret = -ENOMEM;
520 goto out;
521 }
522
523 /* BT-WLAN coext parameters */
2b60100b
JO
524 param->per_threshold = c->per_threshold;
525 param->max_scan_compensation_time = c->max_scan_compensation_time;
526 param->nfs_sample_interval = c->nfs_sample_interval;
527 param->load_ratio = c->load_ratio;
528 param->auto_ps_mode = c->auto_ps_mode;
529 param->probe_req_compensation = c->probe_req_compensation;
530 param->scan_window_compensation = c->scan_window_compensation;
531 param->antenna_config = c->antenna_config;
532 param->beacon_miss_threshold = c->beacon_miss_threshold;
533 param->rate_adaptation_threshold = c->rate_adaptation_threshold;
534 param->rate_adaptation_snr = c->rate_adaptation_snr;
f5fc0f86
LC
535
536 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
537 if (ret < 0) {
538 wl1271_warning("failed to set sg config: %d", ret);
539 goto out;
540 }
541
542out:
543 kfree(param);
544 return ret;
545}
546
547int wl1271_acx_cca_threshold(struct wl1271 *wl)
548{
549 struct acx_energy_detection *detection;
550 int ret;
551
552 wl1271_debug(DEBUG_ACX, "acx cca threshold");
553
554 detection = kzalloc(sizeof(*detection), GFP_KERNEL);
555 if (!detection) {
556 ret = -ENOMEM;
557 goto out;
558 }
559
560 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
561 detection->tx_energy_detection = 0;
562
563 ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
564 detection, sizeof(*detection));
565 if (ret < 0) {
566 wl1271_warning("failed to set cca threshold: %d", ret);
567 return ret;
568 }
569
570out:
571 kfree(detection);
572 return ret;
573}
574
575int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
576{
577 struct acx_beacon_broadcast *bb;
578 int ret;
579
580 wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
581
582 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
583 if (!bb) {
584 ret = -ENOMEM;
585 goto out;
586 }
587
588 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
589 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
590 bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
591 bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
592
593 ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
594 if (ret < 0) {
595 wl1271_warning("failed to set rx config: %d", ret);
596 goto out;
597 }
598
599out:
600 kfree(bb);
601 return ret;
602}
603
604int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
605{
606 struct acx_aid *acx_aid;
607 int ret;
608
609 wl1271_debug(DEBUG_ACX, "acx aid");
610
611 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
612 if (!acx_aid) {
613 ret = -ENOMEM;
614 goto out;
615 }
616
617 acx_aid->aid = aid;
618
619 ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
620 if (ret < 0) {
621 wl1271_warning("failed to set aid: %d", ret);
622 goto out;
623 }
624
625out:
626 kfree(acx_aid);
627 return ret;
628}
629
630int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
631{
632 struct acx_event_mask *mask;
633 int ret;
634
635 wl1271_debug(DEBUG_ACX, "acx event mbox mask");
636
637 mask = kzalloc(sizeof(*mask), GFP_KERNEL);
638 if (!mask) {
639 ret = -ENOMEM;
640 goto out;
641 }
642
643 /* high event mask is unused */
644 mask->high_event_mask = 0xffffffff;
645
646 mask->event_mask = event_mask;
647
648 ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
649 mask, sizeof(*mask));
650 if (ret < 0) {
651 wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
652 goto out;
653 }
654
655out:
656 kfree(mask);
657 return ret;
658}
659
660int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
661{
662 struct acx_preamble *acx;
663 int ret;
664
665 wl1271_debug(DEBUG_ACX, "acx_set_preamble");
666
667 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
668 if (!acx) {
669 ret = -ENOMEM;
670 goto out;
671 }
672
673 acx->preamble = preamble;
674
675 ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
676 if (ret < 0) {
677 wl1271_warning("Setting of preamble failed: %d", ret);
678 goto out;
679 }
680
681out:
682 kfree(acx);
683 return ret;
684}
685
686int wl1271_acx_cts_protect(struct wl1271 *wl,
687 enum acx_ctsprotect_type ctsprotect)
688{
689 struct acx_ctsprotect *acx;
690 int ret;
691
692 wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
693
694 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
695 if (!acx) {
696 ret = -ENOMEM;
697 goto out;
698 }
699
700 acx->ctsprotect = ctsprotect;
701
702 ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
703 if (ret < 0) {
704 wl1271_warning("Setting of ctsprotect failed: %d", ret);
705 goto out;
706 }
707
708out:
709 kfree(acx);
710 return ret;
711}
712
713int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
714{
715 int ret;
716
717 wl1271_debug(DEBUG_ACX, "acx statistics");
718
719 ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
720 sizeof(*stats));
721 if (ret < 0) {
722 wl1271_warning("acx statistics failed: %d", ret);
723 return -ENOMEM;
724 }
725
726 return 0;
727}
728
8a5a37a6 729int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates)
f5fc0f86
LC
730{
731 struct acx_rate_policy *acx;
732 int ret = 0;
733
734 wl1271_debug(DEBUG_ACX, "acx rate policies");
735
736 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
737
738 if (!acx) {
739 ret = -ENOMEM;
740 goto out;
741 }
742
743 /* configure one default (one-size-fits-all) rate class */
744 acx->rate_class_cnt = 1;
8a5a37a6 745 acx->rate_class[0].enabled_rates = enabled_rates;
f5fc0f86
LC
746 acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
747 acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
748 acx->rate_class[0].aflags = 0;
749
750 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
751 if (ret < 0) {
752 wl1271_warning("Setting of rate policies failed: %d", ret);
753 goto out;
754 }
755
756out:
757 kfree(acx);
758 return ret;
759}
760
761int wl1271_acx_ac_cfg(struct wl1271 *wl)
762{
763 struct acx_ac_cfg *acx;
764 int i, ret = 0;
765
766 wl1271_debug(DEBUG_ACX, "acx access category config");
767
768 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
769
770 if (!acx) {
771 ret = -ENOMEM;
772 goto out;
773 }
774
775 /*
776 * FIXME: Configure each AC with appropriate values (most suitable
777 * values will probably be different for each AC.
778 */
779 for (i = 0; i < WL1271_ACX_AC_COUNT; i++) {
780 acx->ac = i;
781
782 /*
783 * FIXME: The following default values originate from
784 * the TI reference driver. What do they mean?
785 */
786 acx->cw_min = 15;
787 acx->cw_max = 63;
788 acx->aifsn = 3;
789 acx->reserved = 0;
790 acx->tx_op_limit = 0;
791
792 ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
793 if (ret < 0) {
794 wl1271_warning("Setting of access category "
795 "config: %d", ret);
796 goto out;
797 }
798 }
799
800out:
801 kfree(acx);
802 return ret;
803}
804
805int wl1271_acx_tid_cfg(struct wl1271 *wl)
806{
807 struct acx_tid_config *acx;
808 int i, ret = 0;
809
810 wl1271_debug(DEBUG_ACX, "acx tid config");
811
812 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
813
814 if (!acx) {
815 ret = -ENOMEM;
816 goto out;
817 }
818
819 /* FIXME: configure each TID with a different AC reference */
820 for (i = 0; i < WL1271_ACX_TID_COUNT; i++) {
821 acx->queue_id = i;
822 acx->tsid = WL1271_ACX_AC_BE;
823 acx->ps_scheme = WL1271_ACX_PS_SCHEME_LEGACY;
824 acx->ack_policy = WL1271_ACX_ACK_POLICY_LEGACY;
825
826 ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
827 if (ret < 0) {
828 wl1271_warning("Setting of tid config failed: %d", ret);
829 goto out;
830 }
831 }
832
833out:
834 kfree(acx);
835 return ret;
836}
837
838int wl1271_acx_frag_threshold(struct wl1271 *wl)
839{
840 struct acx_frag_threshold *acx;
841 int ret = 0;
842
843 wl1271_debug(DEBUG_ACX, "acx frag threshold");
844
845 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
846
847 if (!acx) {
848 ret = -ENOMEM;
849 goto out;
850 }
851
852 acx->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
853 ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
854 if (ret < 0) {
855 wl1271_warning("Setting of frag threshold failed: %d", ret);
856 goto out;
857 }
858
859out:
860 kfree(acx);
861 return ret;
862}
863
864int wl1271_acx_tx_config_options(struct wl1271 *wl)
865{
866 struct acx_tx_config_options *acx;
867 int ret = 0;
868
869 wl1271_debug(DEBUG_ACX, "acx tx config options");
870
871 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
872
873 if (!acx) {
874 ret = -ENOMEM;
875 goto out;
876 }
877
878 acx->tx_compl_timeout = WL1271_ACX_TX_COMPL_TIMEOUT;
879 acx->tx_compl_threshold = WL1271_ACX_TX_COMPL_THRESHOLD;
880 ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
881 if (ret < 0) {
882 wl1271_warning("Setting of tx options failed: %d", ret);
883 goto out;
884 }
885
886out:
887 kfree(acx);
888 return ret;
889}
890
891int wl1271_acx_mem_cfg(struct wl1271 *wl)
892{
893 struct wl1271_acx_config_memory *mem_conf;
894 int ret;
895
896 wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
897
898 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
899 if (!mem_conf) {
900 ret = -ENOMEM;
901 goto out;
902 }
903
904 /* memory config */
905 mem_conf->num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
906 mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
907 mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
908 mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
909 mem_conf->total_tx_descriptors = ACX_TX_DESCRIPTORS;
910
911 ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
912 sizeof(*mem_conf));
913 if (ret < 0) {
914 wl1271_warning("wl1271 mem config failed: %d", ret);
915 goto out;
916 }
917
918out:
919 kfree(mem_conf);
920 return ret;
921}
922
923int wl1271_acx_init_mem_config(struct wl1271 *wl)
924{
925 int ret;
926
927 ret = wl1271_acx_mem_cfg(wl);
928 if (ret < 0)
929 return ret;
930
931 wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
932 GFP_KERNEL);
933 if (!wl->target_mem_map) {
934 wl1271_error("couldn't allocate target memory map");
935 return -ENOMEM;
936 }
937
938 /* we now ask for the firmware built memory map */
939 ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
940 sizeof(struct wl1271_acx_mem_map));
941 if (ret < 0) {
942 wl1271_error("couldn't retrieve firmware memory map");
943 kfree(wl->target_mem_map);
944 wl->target_mem_map = NULL;
945 return ret;
946 }
947
948 /* initialize TX block book keeping */
949 wl->tx_blocks_available = wl->target_mem_map->num_tx_mem_blocks;
950 wl1271_debug(DEBUG_TX, "available tx blocks: %d",
951 wl->tx_blocks_available);
952
953 return 0;
954}
955
956int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
957{
958 struct wl1271_acx_rx_config_opt *rx_conf;
959 int ret;
960
961 wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
962
963 rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
964 if (!rx_conf) {
965 ret = -ENOMEM;
966 goto out;
967 }
968
969 rx_conf->threshold = WL1271_RX_INTR_THRESHOLD_DEF;
970 rx_conf->timeout = WL1271_RX_INTR_TIMEOUT_DEF;
971 rx_conf->mblk_threshold = USHORT_MAX; /* Disabled */
972 rx_conf->queue_type = RX_QUEUE_TYPE_RX_LOW_PRIORITY;
973
974 ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
975 sizeof(*rx_conf));
976 if (ret < 0) {
977 wl1271_warning("wl1271 rx config opt failed: %d", ret);
978 goto out;
979 }
980
981out:
982 kfree(rx_conf);
983 return ret;
984}
3cfd6cf9
JO
985
986int wl1271_acx_smart_reflex(struct wl1271 *wl)
987{
988 struct acx_smart_reflex_state *sr_state = NULL;
989 struct acx_smart_reflex_config_params *sr_param = NULL;
990 int ret;
991
992 wl1271_debug(DEBUG_ACX, "acx smart reflex");
993
994 sr_param = kzalloc(sizeof(*sr_param), GFP_KERNEL);
995 if (!sr_param) {
996 ret = -ENOMEM;
997 goto out;
998 }
999
1000 /* set cryptic smart reflex parameters - source TI reference code */
1001 sr_param->error_table[0].len = 0x07;
1002 sr_param->error_table[0].upper_limit = 0x03;
1003 sr_param->error_table[0].values[0] = 0x18;
1004 sr_param->error_table[0].values[1] = 0x10;
1005 sr_param->error_table[0].values[2] = 0x05;
1006 sr_param->error_table[0].values[3] = 0xfb;
1007 sr_param->error_table[0].values[4] = 0xf0;
1008 sr_param->error_table[0].values[5] = 0xe8;
1009
1010 sr_param->error_table[1].len = 0x07;
1011 sr_param->error_table[1].upper_limit = 0x03;
1012 sr_param->error_table[1].values[0] = 0x18;
1013 sr_param->error_table[1].values[1] = 0x10;
1014 sr_param->error_table[1].values[2] = 0x05;
1015 sr_param->error_table[1].values[3] = 0xf6;
1016 sr_param->error_table[1].values[4] = 0xf0;
1017 sr_param->error_table[1].values[5] = 0xe8;
1018
1019 sr_param->error_table[2].len = 0x07;
1020 sr_param->error_table[2].upper_limit = 0x03;
1021 sr_param->error_table[2].values[0] = 0x18;
1022 sr_param->error_table[2].values[1] = 0x10;
1023 sr_param->error_table[2].values[2] = 0x05;
1024 sr_param->error_table[2].values[3] = 0xfb;
1025 sr_param->error_table[2].values[4] = 0xf0;
1026 sr_param->error_table[2].values[5] = 0xe8;
1027
1028 ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_PARAMS,
1029 sr_param, sizeof(*sr_param));
1030 if (ret < 0) {
1031 wl1271_warning("failed to set smart reflex params: %d", ret);
1032 goto out;
1033 }
1034
1035 sr_state = kzalloc(sizeof(*sr_state), GFP_KERNEL);
1036 if (!sr_state) {
1037 ret = -ENOMEM;
1038 goto out;
1039 }
1040
1041 /* enable smart reflex */
1042 sr_state->enable = 1;
1043
1044 ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_STATE,
1045 sr_state, sizeof(*sr_state));
1046 if (ret < 0) {
1047 wl1271_warning("failed to set smart reflex params: %d", ret);
1048 goto out;
1049 }
1050
1051out:
1052 kfree(sr_state);
1053 kfree(sr_param);
1054 return ret;
1055
1056}