aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_acx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_acx.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c414
1 files changed, 299 insertions, 115 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index f622a4092615..308782421fce 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -27,6 +27,7 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/crc7.h> 28#include <linux/crc7.h>
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/slab.h>
30 31
31#include "wl1271.h" 32#include "wl1271.h"
32#include "wl12xx_80211.h" 33#include "wl12xx_80211.h"
@@ -34,8 +35,7 @@
34#include "wl1271_spi.h" 35#include "wl1271_spi.h"
35#include "wl1271_ps.h" 36#include "wl1271_ps.h"
36 37
37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event, 38int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
38 u8 listen_interval)
39{ 39{
40 struct acx_wake_up_condition *wake_up; 40 struct acx_wake_up_condition *wake_up;
41 int ret; 41 int ret;
@@ -48,8 +48,8 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
48 goto out; 48 goto out;
49 } 49 }
50 50
51 wake_up->wake_up_event = wake_up_event; 51 wake_up->wake_up_event = wl->conf.conn.wake_up_event;
52 wake_up->listen_interval = listen_interval; 52 wake_up->listen_interval = wl->conf.conn.listen_interval;
53 53
54 ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, 54 ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
55 wake_up, sizeof(*wake_up)); 55 wake_up, sizeof(*wake_up));
@@ -137,7 +137,12 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
137 goto out; 137 goto out;
138 } 138 }
139 139
140 acx->current_tx_power = power * 10; 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 = 120;
141 146
142 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); 147 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
143 if (ret < 0) { 148 if (ret < 0) {
@@ -193,7 +198,7 @@ int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
193 return 0; 198 return 0;
194} 199}
195 200
196int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time) 201int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
197{ 202{
198 struct acx_rx_msdu_lifetime *acx; 203 struct acx_rx_msdu_lifetime *acx;
199 int ret; 204 int ret;
@@ -206,7 +211,7 @@ int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time)
206 goto out; 211 goto out;
207 } 212 }
208 213
209 acx->lifetime = life_time; 214 acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time);
210 ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, 215 ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
211 acx, sizeof(*acx)); 216 acx, sizeof(*acx));
212 if (ret < 0) { 217 if (ret < 0) {
@@ -232,8 +237,8 @@ int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter)
232 goto out; 237 goto out;
233 } 238 }
234 239
235 rx_config->config_options = config; 240 rx_config->config_options = cpu_to_le32(config);
236 rx_config->filter_options = filter; 241 rx_config->filter_options = cpu_to_le32(filter);
237 242
238 ret = wl1271_cmd_configure(wl, ACX_RX_CFG, 243 ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
239 rx_config, sizeof(*rx_config)); 244 rx_config, sizeof(*rx_config));
@@ -260,7 +265,7 @@ int wl1271_acx_pd_threshold(struct wl1271 *wl)
260 goto out; 265 goto out;
261 } 266 }
262 267
263 /* FIXME: threshold value not set */ 268 pd->threshold = cpu_to_le32(wl->conf.rx.packet_detection_threshold);
264 269
265 ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd)); 270 ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
266 if (ret < 0) { 271 if (ret < 0) {
@@ -300,7 +305,8 @@ out:
300 return ret; 305 return ret;
301} 306}
302 307
303int wl1271_acx_group_address_tbl(struct wl1271 *wl) 308int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
309 void *mc_list, u32 mc_list_len)
304{ 310{
305 struct acx_dot11_grp_addr_tbl *acx; 311 struct acx_dot11_grp_addr_tbl *acx;
306 int ret; 312 int ret;
@@ -314,9 +320,9 @@ int wl1271_acx_group_address_tbl(struct wl1271 *wl)
314 } 320 }
315 321
316 /* MAC filtering */ 322 /* MAC filtering */
317 acx->enabled = 0; 323 acx->enabled = enable;
318 acx->num_groups = 0; 324 acx->num_groups = mc_list_len;
319 memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN); 325 memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
320 326
321 ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, 327 ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
322 acx, sizeof(*acx)); 328 acx, sizeof(*acx));
@@ -343,8 +349,8 @@ int wl1271_acx_service_period_timeout(struct wl1271 *wl)
343 349
344 wl1271_debug(DEBUG_ACX, "acx service period timeout"); 350 wl1271_debug(DEBUG_ACX, "acx service period timeout");
345 351
346 rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF; 352 rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout);
347 rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF; 353 rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout);
348 354
349 ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT, 355 ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
350 rx_timeout, sizeof(*rx_timeout)); 356 rx_timeout, sizeof(*rx_timeout));
@@ -372,7 +378,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
372 goto out; 378 goto out;
373 } 379 }
374 380
375 rts->threshold = rts_threshold; 381 rts->threshold = cpu_to_le16(rts_threshold);
376 382
377 ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); 383 ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
378 if (ret < 0) { 384 if (ret < 0) {
@@ -385,20 +391,58 @@ out:
385 return ret; 391 return ret;
386} 392}
387 393
388int wl1271_acx_beacon_filter_opt(struct wl1271 *wl) 394int wl1271_acx_dco_itrim_params(struct wl1271 *wl)
389{ 395{
390 struct acx_beacon_filter_option *beacon_filter; 396 struct acx_dco_itrim_params *dco;
397 struct conf_itrim_settings *c = &wl->conf.itrim;
391 int ret; 398 int ret;
392 399
400 wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
401
402 dco = kzalloc(sizeof(*dco), GFP_KERNEL);
403 if (!dco) {
404 ret = -ENOMEM;
405 goto out;
406 }
407
408 dco->enable = c->enable;
409 dco->timeout = cpu_to_le32(c->timeout);
410
411 ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
412 dco, sizeof(*dco));
413 if (ret < 0) {
414 wl1271_warning("failed to set dco itrim parameters: %d", ret);
415 goto out;
416 }
417
418out:
419 kfree(dco);
420 return ret;
421}
422
423int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
424{
425 struct acx_beacon_filter_option *beacon_filter = NULL;
426 int ret = 0;
427
393 wl1271_debug(DEBUG_ACX, "acx beacon filter opt"); 428 wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
394 429
430 if (enable_filter &&
431 wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
432 goto out;
433
395 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); 434 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
396 if (!beacon_filter) { 435 if (!beacon_filter) {
397 ret = -ENOMEM; 436 ret = -ENOMEM;
398 goto out; 437 goto out;
399 } 438 }
400 439
401 beacon_filter->enable = 0; 440 beacon_filter->enable = enable_filter;
441
442 /*
443 * When set to zero, and the filter is enabled, beacons
444 * without the unicast TIM bit set are dropped.
445 */
402 beacon_filter->max_num_beacons = 0; 446 beacon_filter->max_num_beacons = 0;
403 447
404 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT, 448 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
@@ -416,7 +460,9 @@ out:
416int wl1271_acx_beacon_filter_table(struct wl1271 *wl) 460int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
417{ 461{
418 struct acx_beacon_filter_ie_table *ie_table; 462 struct acx_beacon_filter_ie_table *ie_table;
463 int i, idx = 0;
419 int ret; 464 int ret;
465 bool vendor_spec = false;
420 466
421 wl1271_debug(DEBUG_ACX, "acx beacon filter table"); 467 wl1271_debug(DEBUG_ACX, "acx beacon filter table");
422 468
@@ -426,8 +472,32 @@ int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
426 goto out; 472 goto out;
427 } 473 }
428 474
475 /* configure default beacon pass-through rules */
429 ie_table->num_ie = 0; 476 ie_table->num_ie = 0;
430 memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE); 477 for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) {
478 struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]);
479 ie_table->table[idx++] = r->ie;
480 ie_table->table[idx++] = r->rule;
481
482 if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
483 /* only one vendor specific ie allowed */
484 if (vendor_spec)
485 continue;
486
487 /* for vendor specific rules configure the
488 additional fields */
489 memcpy(&(ie_table->table[idx]), r->oui,
490 CONF_BCN_IE_OUI_LEN);
491 idx += CONF_BCN_IE_OUI_LEN;
492 ie_table->table[idx++] = r->type;
493 memcpy(&(ie_table->table[idx]), r->version,
494 CONF_BCN_IE_VER_LEN);
495 idx += CONF_BCN_IE_VER_LEN;
496 vendor_spec = true;
497 }
498
499 ie_table->num_ie++;
500 }
431 501
432 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, 502 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
433 ie_table, sizeof(*ie_table)); 503 ie_table, sizeof(*ie_table));
@@ -441,6 +511,36 @@ out:
441 return ret; 511 return ret;
442} 512}
443 513
514int wl1271_acx_conn_monit_params(struct wl1271 *wl)
515{
516 struct acx_conn_monit_params *acx;
517 int ret;
518
519 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters");
520
521 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
522 if (!acx) {
523 ret = -ENOMEM;
524 goto out;
525 }
526
527 acx->synch_fail_thold = cpu_to_le32(wl->conf.conn.synch_fail_thold);
528 acx->bss_lose_timeout = cpu_to_le32(wl->conf.conn.bss_lose_timeout);
529
530 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
531 acx, sizeof(*acx));
532 if (ret < 0) {
533 wl1271_warning("failed to set connection monitor "
534 "parameters: %d", ret);
535 goto out;
536 }
537
538out:
539 kfree(acx);
540 return ret;
541}
542
543
444int wl1271_acx_sg_enable(struct wl1271 *wl) 544int wl1271_acx_sg_enable(struct wl1271 *wl)
445{ 545{
446 struct acx_bt_wlan_coex *pta; 546 struct acx_bt_wlan_coex *pta;
@@ -470,6 +570,7 @@ out:
470int wl1271_acx_sg_cfg(struct wl1271 *wl) 570int wl1271_acx_sg_cfg(struct wl1271 *wl)
471{ 571{
472 struct acx_bt_wlan_coex_param *param; 572 struct acx_bt_wlan_coex_param *param;
573 struct conf_sg_settings *c = &wl->conf.sg;
473 int ret; 574 int ret;
474 575
475 wl1271_debug(DEBUG_ACX, "acx sg cfg"); 576 wl1271_debug(DEBUG_ACX, "acx sg cfg");
@@ -481,34 +582,19 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
481 } 582 }
482 583
483 /* BT-WLAN coext parameters */ 584 /* BT-WLAN coext parameters */
484 param->min_rate = RATE_INDEX_24MBPS; 585 param->per_threshold = cpu_to_le32(c->per_threshold);
485 param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF; 586 param->max_scan_compensation_time =
486 param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF; 587 cpu_to_le32(c->max_scan_compensation_time);
487 param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF; 588 param->nfs_sample_interval = cpu_to_le16(c->nfs_sample_interval);
488 param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF; 589 param->load_ratio = c->load_ratio;
489 param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF; 590 param->auto_ps_mode = c->auto_ps_mode;
490 param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF; 591 param->probe_req_compensation = c->probe_req_compensation;
491 param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF; 592 param->scan_window_compensation = c->scan_window_compensation;
492 param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF; 593 param->antenna_config = c->antenna_config;
493 param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF; 594 param->beacon_miss_threshold = c->beacon_miss_threshold;
494 param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF; 595 param->rate_adaptation_threshold =
495 param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF; 596 cpu_to_le32(c->rate_adaptation_threshold);
496 param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF; 597 param->rate_adaptation_snr = c->rate_adaptation_snr;
497 param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
498 param->antenna_type = PTA_ANTENNA_TYPE_DEF;
499 param->signal_type = PTA_SIGNALING_TYPE_DEF;
500 param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
501 param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
502 param->max_cts = PTA_MAX_NUM_CTS_DEF;
503 param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
504 param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
505 param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
506 param->wlan_elp_hp = PTA_ELP_HP_DEF;
507 param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
508 param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
509 param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
510 param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
511 param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
512 598
513 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); 599 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
514 if (ret < 0) { 600 if (ret < 0) {
@@ -534,8 +620,8 @@ int wl1271_acx_cca_threshold(struct wl1271 *wl)
534 goto out; 620 goto out;
535 } 621 }
536 622
537 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; 623 detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold);
538 detection->tx_energy_detection = 0; 624 detection->tx_energy_detection = wl->conf.tx.tx_energy_detection;
539 625
540 ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD, 626 ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
541 detection, sizeof(*detection)); 627 detection, sizeof(*detection));
@@ -562,10 +648,10 @@ int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
562 goto out; 648 goto out;
563 } 649 }
564 650
565 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; 651 bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout);
566 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; 652 bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout);
567 bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE; 653 bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps;
568 bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF; 654 bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold;
569 655
570 ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb)); 656 ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
571 if (ret < 0) { 657 if (ret < 0) {
@@ -591,7 +677,7 @@ int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
591 goto out; 677 goto out;
592 } 678 }
593 679
594 acx_aid->aid = aid; 680 acx_aid->aid = cpu_to_le16(aid);
595 681
596 ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid)); 682 ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
597 if (ret < 0) { 683 if (ret < 0) {
@@ -618,9 +704,8 @@ int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
618 } 704 }
619 705
620 /* high event mask is unused */ 706 /* high event mask is unused */
621 mask->high_event_mask = 0xffffffff; 707 mask->high_event_mask = cpu_to_le32(0xffffffff);
622 708 mask->event_mask = cpu_to_le32(event_mask);
623 mask->event_mask = event_mask;
624 709
625 ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK, 710 ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
626 mask, sizeof(*mask)); 711 mask, sizeof(*mask));
@@ -706,6 +791,8 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
706int wl1271_acx_rate_policies(struct wl1271 *wl) 791int wl1271_acx_rate_policies(struct wl1271 *wl)
707{ 792{
708 struct acx_rate_policy *acx; 793 struct acx_rate_policy *acx;
794 struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf;
795 int idx = 0;
709 int ret = 0; 796 int ret = 0;
710 797
711 wl1271_debug(DEBUG_ACX, "acx rate policies"); 798 wl1271_debug(DEBUG_ACX, "acx rate policies");
@@ -717,12 +804,21 @@ int wl1271_acx_rate_policies(struct wl1271 *wl)
717 goto out; 804 goto out;
718 } 805 }
719 806
720 /* configure one default (one-size-fits-all) rate class */ 807 /* configure one basic rate class */
721 acx->rate_class_cnt = 1; 808 idx = ACX_TX_BASIC_RATE;
722 acx->rate_class[0].enabled_rates = ACX_RATE_MASK_ALL; 809 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set);
723 acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT; 810 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
724 acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT; 811 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
725 acx->rate_class[0].aflags = 0; 812 acx->rate_class[idx].aflags = c->aflags;
813
814 /* configure one AP supported rate class */
815 idx = ACX_TX_AP_FULL_RATE;
816 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set);
817 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
818 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
819 acx->rate_class[idx].aflags = c->aflags;
820
821 acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
726 822
727 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 823 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
728 if (ret < 0) { 824 if (ret < 0) {
@@ -735,12 +831,14 @@ out:
735 return ret; 831 return ret;
736} 832}
737 833
738int wl1271_acx_ac_cfg(struct wl1271 *wl) 834int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
835 u8 aifsn, u16 txop)
739{ 836{
740 struct acx_ac_cfg *acx; 837 struct acx_ac_cfg *acx;
741 int i, ret = 0; 838 int ret = 0;
742 839
743 wl1271_debug(DEBUG_ACX, "acx access category config"); 840 wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
841 "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
744 842
745 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 843 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
746 844
@@ -749,29 +847,16 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl)
749 goto out; 847 goto out;
750 } 848 }
751 849
752 /* 850 acx->ac = ac;
753 * FIXME: Configure each AC with appropriate values (most suitable 851 acx->cw_min = cw_min;
754 * values will probably be different for each AC. 852 acx->cw_max = cpu_to_le16(cw_max);
755 */ 853 acx->aifsn = aifsn;
756 for (i = 0; i < WL1271_ACX_AC_COUNT; i++) { 854 acx->tx_op_limit = cpu_to_le16(txop);
757 acx->ac = i; 855
758 856 ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
759 /* 857 if (ret < 0) {
760 * FIXME: The following default values originate from 858 wl1271_warning("acx ac cfg failed: %d", ret);
761 * the TI reference driver. What do they mean? 859 goto out;
762 */
763 acx->cw_min = 15;
764 acx->cw_max = 63;
765 acx->aifsn = 3;
766 acx->reserved = 0;
767 acx->tx_op_limit = 0;
768
769 ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
770 if (ret < 0) {
771 wl1271_warning("Setting of access category "
772 "config: %d", ret);
773 goto out;
774 }
775 } 860 }
776 861
777out: 862out:
@@ -779,10 +864,12 @@ out:
779 return ret; 864 return ret;
780} 865}
781 866
782int wl1271_acx_tid_cfg(struct wl1271 *wl) 867int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
868 u8 tsid, u8 ps_scheme, u8 ack_policy,
869 u32 apsd_conf0, u32 apsd_conf1)
783{ 870{
784 struct acx_tid_config *acx; 871 struct acx_tid_config *acx;
785 int i, ret = 0; 872 int ret = 0;
786 873
787 wl1271_debug(DEBUG_ACX, "acx tid config"); 874 wl1271_debug(DEBUG_ACX, "acx tid config");
788 875
@@ -793,18 +880,18 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl)
793 goto out; 880 goto out;
794 } 881 }
795 882
796 /* FIXME: configure each TID with a different AC reference */ 883 acx->queue_id = queue_id;
797 for (i = 0; i < WL1271_ACX_TID_COUNT; i++) { 884 acx->channel_type = channel_type;
798 acx->queue_id = i; 885 acx->tsid = tsid;
799 acx->tsid = WL1271_ACX_AC_BE; 886 acx->ps_scheme = ps_scheme;
800 acx->ps_scheme = WL1271_ACX_PS_SCHEME_LEGACY; 887 acx->ack_policy = ack_policy;
801 acx->ack_policy = WL1271_ACX_ACK_POLICY_LEGACY; 888 acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
889 acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
802 890
803 ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); 891 ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
804 if (ret < 0) { 892 if (ret < 0) {
805 wl1271_warning("Setting of tid config failed: %d", ret); 893 wl1271_warning("Setting of tid config failed: %d", ret);
806 goto out; 894 goto out;
807 }
808 } 895 }
809 896
810out: 897out:
@@ -826,7 +913,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl)
826 goto out; 913 goto out;
827 } 914 }
828 915
829 acx->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 916 acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold);
830 ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx)); 917 ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
831 if (ret < 0) { 918 if (ret < 0) {
832 wl1271_warning("Setting of frag threshold failed: %d", ret); 919 wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -852,8 +939,8 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl)
852 goto out; 939 goto out;
853 } 940 }
854 941
855 acx->tx_compl_timeout = WL1271_ACX_TX_COMPL_TIMEOUT; 942 acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout);
856 acx->tx_compl_threshold = WL1271_ACX_TX_COMPL_THRESHOLD; 943 acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold);
857 ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx)); 944 ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
858 if (ret < 0) { 945 if (ret < 0) {
859 wl1271_warning("Setting of tx options failed: %d", ret); 946 wl1271_warning("Setting of tx options failed: %d", ret);
@@ -879,11 +966,11 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl)
879 } 966 }
880 967
881 /* memory config */ 968 /* memory config */
882 mem_conf->num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS); 969 mem_conf->num_stations = DEFAULT_NUM_STATIONS;
883 mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; 970 mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
884 mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; 971 mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
885 mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; 972 mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
886 mem_conf->total_tx_descriptors = ACX_TX_DESCRIPTORS; 973 mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
887 974
888 ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, 975 ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
889 sizeof(*mem_conf)); 976 sizeof(*mem_conf));
@@ -906,7 +993,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl)
906 return ret; 993 return ret;
907 994
908 wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), 995 wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
909 GFP_KERNEL); 996 GFP_KERNEL);
910 if (!wl->target_mem_map) { 997 if (!wl->target_mem_map) {
911 wl1271_error("couldn't allocate target memory map"); 998 wl1271_error("couldn't allocate target memory map");
912 return -ENOMEM; 999 return -ENOMEM;
@@ -923,7 +1010,8 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl)
923 } 1010 }
924 1011
925 /* initialize TX block book keeping */ 1012 /* initialize TX block book keeping */
926 wl->tx_blocks_available = wl->target_mem_map->num_tx_mem_blocks; 1013 wl->tx_blocks_available =
1014 le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks);
927 wl1271_debug(DEBUG_TX, "available tx blocks: %d", 1015 wl1271_debug(DEBUG_TX, "available tx blocks: %d",
928 wl->tx_blocks_available); 1016 wl->tx_blocks_available);
929 1017
@@ -943,10 +1031,10 @@ int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
943 goto out; 1031 goto out;
944 } 1032 }
945 1033
946 rx_conf->threshold = WL1271_RX_INTR_THRESHOLD_DEF; 1034 rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold);
947 rx_conf->timeout = WL1271_RX_INTR_TIMEOUT_DEF; 1035 rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout);
948 rx_conf->mblk_threshold = USHORT_MAX; /* Disabled */ 1036 rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold);
949 rx_conf->queue_type = RX_QUEUE_TYPE_RX_LOW_PRIORITY; 1037 rx_conf->queue_type = wl->conf.rx.queue_type;
950 1038
951 ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf, 1039 ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
952 sizeof(*rx_conf)); 1040 sizeof(*rx_conf));
@@ -959,3 +1047,99 @@ out:
959 kfree(rx_conf); 1047 kfree(rx_conf);
960 return ret; 1048 return ret;
961} 1049}
1050
1051int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
1052{
1053 struct wl1271_acx_bet_enable *acx = NULL;
1054 int ret = 0;
1055
1056 wl1271_debug(DEBUG_ACX, "acx bet enable");
1057
1058 if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
1059 goto out;
1060
1061 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1062 if (!acx) {
1063 ret = -ENOMEM;
1064 goto out;
1065 }
1066
1067 acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
1068 acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
1069
1070 ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
1071 if (ret < 0) {
1072 wl1271_warning("acx bet enable failed: %d", ret);
1073 goto out;
1074 }
1075
1076out:
1077 kfree(acx);
1078 return ret;
1079}
1080
1081int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
1082 u8 version)
1083{
1084 struct wl1271_acx_arp_filter *acx;
1085 int ret;
1086
1087 wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
1088
1089 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1090 if (!acx) {
1091 ret = -ENOMEM;
1092 goto out;
1093 }
1094
1095 acx->version = version;
1096 acx->enable = enable;
1097
1098 if (enable == true) {
1099 if (version == ACX_IPV4_VERSION)
1100 memcpy(acx->address, address, ACX_IPV4_ADDR_SIZE);
1101 else if (version == ACX_IPV6_VERSION)
1102 memcpy(acx->address, address, sizeof(acx->address));
1103 else
1104 wl1271_error("Invalid IP version");
1105 }
1106
1107 ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
1108 acx, sizeof(*acx));
1109 if (ret < 0) {
1110 wl1271_warning("failed to set arp ip filter: %d", ret);
1111 goto out;
1112 }
1113
1114out:
1115 kfree(acx);
1116 return ret;
1117}
1118
1119int wl1271_acx_pm_config(struct wl1271 *wl)
1120{
1121 struct wl1271_acx_pm_config *acx = NULL;
1122 struct conf_pm_config_settings *c = &wl->conf.pm_config;
1123 int ret = 0;
1124
1125 wl1271_debug(DEBUG_ACX, "acx pm config");
1126
1127 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1128 if (!acx) {
1129 ret = -ENOMEM;
1130 goto out;
1131 }
1132
1133 acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
1134 acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
1135
1136 ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
1137 if (ret < 0) {
1138 wl1271_warning("acx pm config failed: %d", ret);
1139 goto out;
1140 }
1141
1142out:
1143 kfree(acx);
1144 return ret;
1145}