Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
   1#include "acx.h"
   2
   3#include <linux/module.h>
   4#include <linux/slab.h>
   5#include <linux/crc7.h>
   6
   7#include "wl1251.h"
   8#include "reg.h"
   9#include "cmd.h"
  10#include "ps.h"
  11
  12int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
  13			   u8 mgt_rate, u8 mgt_mod)
  14{
  15	struct acx_fw_gen_frame_rates *rates;
  16	int ret;
  17
  18	wl1251_debug(DEBUG_ACX, "acx frame rates");
  19
  20	rates = kzalloc(sizeof(*rates), GFP_KERNEL);
  21	if (!rates) {
  22		ret = -ENOMEM;
  23		goto out;
  24	}
  25
  26	rates->tx_ctrl_frame_rate = ctrl_rate;
  27	rates->tx_ctrl_frame_mod = ctrl_mod;
  28	rates->tx_mgt_frame_rate = mgt_rate;
  29	rates->tx_mgt_frame_mod = mgt_mod;
  30
  31	ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
  32				   rates, sizeof(*rates));
  33	if (ret < 0) {
  34		wl1251_error("Failed to set FW rates and modulation");
  35		goto out;
  36	}
  37
  38out:
  39	kfree(rates);
  40	return ret;
  41}
  42
  43
  44int wl1251_acx_station_id(struct wl1251 *wl)
  45{
  46	struct acx_dot11_station_id *mac;
  47	int ret, i;
  48
  49	wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
  50
  51	mac = kzalloc(sizeof(*mac), GFP_KERNEL);
  52	if (!mac) {
  53		ret = -ENOMEM;
  54		goto out;
  55	}
  56
  57	for (i = 0; i < ETH_ALEN; i++)
  58		mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
  59
  60	ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
  61	if (ret < 0)
  62		goto out;
  63
  64out:
  65	kfree(mac);
  66	return ret;
  67}
  68
  69int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
  70{
  71	struct acx_dot11_default_key *default_key;
  72	int ret;
  73
  74	wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
  75
  76	default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
  77	if (!default_key) {
  78		ret = -ENOMEM;
  79		goto out;
  80	}
  81
  82	default_key->id = key_id;
  83
  84	ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
  85				   default_key, sizeof(*default_key));
  86	if (ret < 0) {
  87		wl1251_error("Couldn't set default key");
  88		goto out;
  89	}
  90
  91	wl->default_key = key_id;
  92
  93out:
  94	kfree(default_key);
  95	return ret;
  96}
  97
  98int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
  99				  u8 listen_interval)
 100{
 101	struct acx_wake_up_condition *wake_up;
 102	int ret;
 103
 104	wl1251_debug(DEBUG_ACX, "acx wake up conditions");
 105
 106	wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
 107	if (!wake_up) {
 108		ret = -ENOMEM;
 109		goto out;
 110	}
 111
 112	wake_up->wake_up_event = wake_up_event;
 113	wake_up->listen_interval = listen_interval;
 114
 115	ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
 116				   wake_up, sizeof(*wake_up));
 117	if (ret < 0) {
 118		wl1251_warning("could not set wake up conditions: %d", ret);
 119		goto out;
 120	}
 121
 122out:
 123	kfree(wake_up);
 124	return ret;
 125}
 126
 127int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
 128{
 129	struct acx_sleep_auth *auth;
 130	int ret;
 131
 132	wl1251_debug(DEBUG_ACX, "acx sleep auth");
 133
 134	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
 135	if (!auth) {
 136		ret = -ENOMEM;
 137		goto out;
 138	}
 139
 140	auth->sleep_auth = sleep_auth;
 141
 142	ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
 143
 144out:
 145	kfree(auth);
 146	return ret;
 147}
 148
 149int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
 150{
 151	struct acx_revision *rev;
 152	int ret;
 153
 154	wl1251_debug(DEBUG_ACX, "acx fw rev");
 155
 156	rev = kzalloc(sizeof(*rev), GFP_KERNEL);
 157	if (!rev) {
 158		ret = -ENOMEM;
 159		goto out;
 160	}
 161
 162	ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
 163	if (ret < 0) {
 164		wl1251_warning("ACX_FW_REV interrogate failed");
 165		goto out;
 166	}
 167
 168	/* be careful with the buffer sizes */
 169	strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
 170
 171	/*
 172	 * if the firmware version string is exactly
 173	 * sizeof(rev->fw_version) long or fw_len is less than
 174	 * sizeof(rev->fw_version) it won't be null terminated
 175	 */
 176	buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
 177
 178out:
 179	kfree(rev);
 180	return ret;
 181}
 182
 183int wl1251_acx_tx_power(struct wl1251 *wl, int power)
 184{
 185	struct acx_current_tx_power *acx;
 186	int ret;
 187
 188	wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
 189
 190	if (power < 0 || power > 25)
 191		return -EINVAL;
 192
 193	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 194	if (!acx) {
 195		ret = -ENOMEM;
 196		goto out;
 197	}
 198
 199	acx->current_tx_power = power * 10;
 200
 201	ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
 202	if (ret < 0) {
 203		wl1251_warning("configure of tx power failed: %d", ret);
 204		goto out;
 205	}
 206
 207out:
 208	kfree(acx);
 209	return ret;
 210}
 211
 212int wl1251_acx_feature_cfg(struct wl1251 *wl)
 213{
 214	struct acx_feature_config *feature;
 215	int ret;
 216
 217	wl1251_debug(DEBUG_ACX, "acx feature cfg");
 218
 219	feature = kzalloc(sizeof(*feature), GFP_KERNEL);
 220	if (!feature) {
 221		ret = -ENOMEM;
 222		goto out;
 223	}
 224
 225	/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
 226	feature->data_flow_options = 0;
 227	feature->options = 0;
 228
 229	ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
 230				   feature, sizeof(*feature));
 231	if (ret < 0) {
 232		wl1251_error("Couldn't set HW encryption");
 233		goto out;
 234	}
 235
 236out:
 237	kfree(feature);
 238	return ret;
 239}
 240
 241int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
 242		       size_t len)
 243{
 244	int ret;
 245
 246	wl1251_debug(DEBUG_ACX, "acx mem map");
 247
 248	ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
 249	if (ret < 0)
 250		return ret;
 251
 252	return 0;
 253}
 254
 255int wl1251_acx_data_path_params(struct wl1251 *wl,
 256				struct acx_data_path_params_resp *resp)
 257{
 258	struct acx_data_path_params *params;
 259	int ret;
 260
 261	wl1251_debug(DEBUG_ACX, "acx data path params");
 262
 263	params = kzalloc(sizeof(*params), GFP_KERNEL);
 264	if (!params) {
 265		ret = -ENOMEM;
 266		goto out;
 267	}
 268
 269	params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
 270	params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
 271
 272	params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
 273	params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
 274
 275	params->tx_complete_threshold = 1;
 276
 277	params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
 278
 279	params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
 280
 281	ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
 282				   params, sizeof(*params));
 283	if (ret < 0)
 284		goto out;
 285
 286	/* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
 287	ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
 288				     resp, sizeof(*resp));
 289
 290	if (ret < 0) {
 291		wl1251_warning("failed to read data path parameters: %d", ret);
 292		goto out;
 293	} else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
 294		wl1251_warning("data path parameter acx status failed");
 295		ret = -EIO;
 296		goto out;
 297	}
 298
 299out:
 300	kfree(params);
 301	return ret;
 302}
 303
 304int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
 305{
 306	struct acx_rx_msdu_lifetime *acx;
 307	int ret;
 308
 309	wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
 310
 311	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 312	if (!acx) {
 313		ret = -ENOMEM;
 314		goto out;
 315	}
 316
 317	acx->lifetime = life_time;
 318	ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
 319				   acx, sizeof(*acx));
 320	if (ret < 0) {
 321		wl1251_warning("failed to set rx msdu life time: %d", ret);
 322		goto out;
 323	}
 324
 325out:
 326	kfree(acx);
 327	return ret;
 328}
 329
 330int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
 331{
 332	struct acx_rx_config *rx_config;
 333	int ret;
 334
 335	wl1251_debug(DEBUG_ACX, "acx rx config");
 336
 337	rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
 338	if (!rx_config) {
 339		ret = -ENOMEM;
 340		goto out;
 341	}
 342
 343	rx_config->config_options = config;
 344	rx_config->filter_options = filter;
 345
 346	ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
 347				   rx_config, sizeof(*rx_config));
 348	if (ret < 0) {
 349		wl1251_warning("failed to set rx config: %d", ret);
 350		goto out;
 351	}
 352
 353out:
 354	kfree(rx_config);
 355	return ret;
 356}
 357
 358int wl1251_acx_pd_threshold(struct wl1251 *wl)
 359{
 360	struct acx_packet_detection *pd;
 361	int ret;
 362
 363	wl1251_debug(DEBUG_ACX, "acx data pd threshold");
 364
 365	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 366	if (!pd) {
 367		ret = -ENOMEM;
 368		goto out;
 369	}
 370
 371	/* FIXME: threshold value not set */
 372
 373	ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
 374	if (ret < 0) {
 375		wl1251_warning("failed to set pd threshold: %d", ret);
 376		goto out;
 377	}
 378
 379out:
 380	kfree(pd);
 381	return ret;
 382}
 383
 384int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
 385{
 386	struct acx_slot *slot;
 387	int ret;
 388
 389	wl1251_debug(DEBUG_ACX, "acx slot");
 390
 391	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
 392	if (!slot) {
 393		ret = -ENOMEM;
 394		goto out;
 395	}
 396
 397	slot->wone_index = STATION_WONE_INDEX;
 398	slot->slot_time = slot_time;
 399
 400	ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
 401	if (ret < 0) {
 402		wl1251_warning("failed to set slot time: %d", ret);
 403		goto out;
 404	}
 405
 406out:
 407	kfree(slot);
 408	return ret;
 409}
 410
 411int wl1251_acx_group_address_tbl(struct wl1251 *wl)
 412{
 413	struct acx_dot11_grp_addr_tbl *acx;
 414	int ret;
 415
 416	wl1251_debug(DEBUG_ACX, "acx group address tbl");
 417
 418	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 419	if (!acx) {
 420		ret = -ENOMEM;
 421		goto out;
 422	}
 423
 424	/* MAC filtering */
 425	acx->enabled = 0;
 426	acx->num_groups = 0;
 427	memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
 428
 429	ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
 430				   acx, sizeof(*acx));
 431	if (ret < 0) {
 432		wl1251_warning("failed to set group addr table: %d", ret);
 433		goto out;
 434	}
 435
 436out:
 437	kfree(acx);
 438	return ret;
 439}
 440
 441int wl1251_acx_service_period_timeout(struct wl1251 *wl)
 442{
 443	struct acx_rx_timeout *rx_timeout;
 444	int ret;
 445
 446	rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
 447	if (!rx_timeout) {
 448		ret = -ENOMEM;
 449		goto out;
 450	}
 451
 452	wl1251_debug(DEBUG_ACX, "acx service period timeout");
 453
 454	rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
 455	rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
 456
 457	ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
 458				   rx_timeout, sizeof(*rx_timeout));
 459	if (ret < 0) {
 460		wl1251_warning("failed to set service period timeout: %d",
 461			       ret);
 462		goto out;
 463	}
 464
 465out:
 466	kfree(rx_timeout);
 467	return ret;
 468}
 469
 470int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
 471{
 472	struct acx_rts_threshold *rts;
 473	int ret;
 474
 475	wl1251_debug(DEBUG_ACX, "acx rts threshold");
 476
 477	rts = kzalloc(sizeof(*rts), GFP_KERNEL);
 478	if (!rts) {
 479		ret = -ENOMEM;
 480		goto out;
 481	}
 482
 483	rts->threshold = rts_threshold;
 484
 485	ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
 486	if (ret < 0) {
 487		wl1251_warning("failed to set rts threshold: %d", ret);
 488		goto out;
 489	}
 490
 491out:
 492	kfree(rts);
 493	return ret;
 494}
 495
 496int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
 497{
 498	struct acx_beacon_filter_option *beacon_filter;
 499	int ret;
 500
 501	wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
 502
 503	beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
 504	if (!beacon_filter) {
 505		ret = -ENOMEM;
 506		goto out;
 507	}
 508
 509	beacon_filter->enable = enable_filter;
 510	beacon_filter->max_num_beacons = 0;
 511
 512	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
 513				   beacon_filter, sizeof(*beacon_filter));
 514	if (ret < 0) {
 515		wl1251_warning("failed to set beacon filter opt: %d", ret);
 516		goto out;
 517	}
 518
 519out:
 520	kfree(beacon_filter);
 521	return ret;
 522}
 523
 524int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
 525{
 526	struct acx_beacon_filter_ie_table *ie_table;
 527	int idx = 0;
 528	int ret;
 529
 530	wl1251_debug(DEBUG_ACX, "acx beacon filter table");
 531
 532	ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
 533	if (!ie_table) {
 534		ret = -ENOMEM;
 535		goto out;
 536	}
 537
 538	/* configure default beacon pass-through rules */
 539	ie_table->num_ie = 1;
 540	ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
 541	ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
 542
 543	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
 544				   ie_table, sizeof(*ie_table));
 545	if (ret < 0) {
 546		wl1251_warning("failed to set beacon filter table: %d", ret);
 547		goto out;
 548	}
 549
 550out:
 551	kfree(ie_table);
 552	return ret;
 553}
 554
 555int wl1251_acx_conn_monit_params(struct wl1251 *wl)
 556{
 557	struct acx_conn_monit_params *acx;
 558	int ret;
 559
 560	wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
 561
 562	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 563	if (!acx) {
 564		ret = -ENOMEM;
 565		goto out;
 566	}
 567
 568	acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
 569	acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
 570
 571	ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
 572				   acx, sizeof(*acx));
 573	if (ret < 0) {
 574		wl1251_warning("failed to set connection monitor "
 575			       "parameters: %d", ret);
 576		goto out;
 577	}
 578
 579out:
 580	kfree(acx);
 581	return ret;
 582}
 583
 584int wl1251_acx_sg_enable(struct wl1251 *wl)
 585{
 586	struct acx_bt_wlan_coex *pta;
 587	int ret;
 588
 589	wl1251_debug(DEBUG_ACX, "acx sg enable");
 590
 591	pta = kzalloc(sizeof(*pta), GFP_KERNEL);
 592	if (!pta) {
 593		ret = -ENOMEM;
 594		goto out;
 595	}
 596
 597	pta->enable = SG_ENABLE;
 598
 599	ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
 600	if (ret < 0) {
 601		wl1251_warning("failed to set softgemini enable: %d", ret);
 602		goto out;
 603	}
 604
 605out:
 606	kfree(pta);
 607	return ret;
 608}
 609
 610int wl1251_acx_sg_cfg(struct wl1251 *wl)
 611{
 612	struct acx_bt_wlan_coex_param *param;
 613	int ret;
 614
 615	wl1251_debug(DEBUG_ACX, "acx sg cfg");
 616
 617	param = kzalloc(sizeof(*param), GFP_KERNEL);
 618	if (!param) {
 619		ret = -ENOMEM;
 620		goto out;
 621	}
 622
 623	/* BT-WLAN coext parameters */
 624	param->min_rate = RATE_INDEX_24MBPS;
 625	param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
 626	param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
 627	param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
 628	param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
 629	param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
 630	param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
 631	param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
 632	param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
 633	param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
 634	param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
 635	param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
 636	param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
 637	param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
 638	param->antenna_type = PTA_ANTENNA_TYPE_DEF;
 639	param->signal_type = PTA_SIGNALING_TYPE_DEF;
 640	param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
 641	param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
 642	param->max_cts = PTA_MAX_NUM_CTS_DEF;
 643	param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
 644	param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
 645	param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
 646	param->wlan_elp_hp = PTA_ELP_HP_DEF;
 647	param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
 648	param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
 649	param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
 650	param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
 651	param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
 652
 653	ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
 654	if (ret < 0) {
 655		wl1251_warning("failed to set sg config: %d", ret);
 656		goto out;
 657	}
 658
 659out:
 660	kfree(param);
 661	return ret;
 662}
 663
 664int wl1251_acx_cca_threshold(struct wl1251 *wl)
 665{
 666	struct acx_energy_detection *detection;
 667	int ret;
 668
 669	wl1251_debug(DEBUG_ACX, "acx cca threshold");
 670
 671	detection = kzalloc(sizeof(*detection), GFP_KERNEL);
 672	if (!detection) {
 673		ret = -ENOMEM;
 674		goto out;
 675	}
 676
 677	detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
 678	detection->tx_energy_detection = 0;
 679
 680	ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
 681				   detection, sizeof(*detection));
 682	if (ret < 0)
 683		wl1251_warning("failed to set cca threshold: %d", ret);
 684
 685out:
 686	kfree(detection);
 687	return ret;
 688}
 689
 690int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
 691{
 692	struct acx_beacon_broadcast *bb;
 693	int ret;
 694
 695	wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
 696
 697	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
 698	if (!bb) {
 699		ret = -ENOMEM;
 700		goto out;
 701	}
 702
 703	bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
 704	bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
 705	bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
 706	bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
 707
 708	ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
 709	if (ret < 0) {
 710		wl1251_warning("failed to set rx config: %d", ret);
 711		goto out;
 712	}
 713
 714out:
 715	kfree(bb);
 716	return ret;
 717}
 718
 719int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
 720{
 721	struct acx_aid *acx_aid;
 722	int ret;
 723
 724	wl1251_debug(DEBUG_ACX, "acx aid");
 725
 726	acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
 727	if (!acx_aid) {
 728		ret = -ENOMEM;
 729		goto out;
 730	}
 731
 732	acx_aid->aid = aid;
 733
 734	ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
 735	if (ret < 0) {
 736		wl1251_warning("failed to set aid: %d", ret);
 737		goto out;
 738	}
 739
 740out:
 741	kfree(acx_aid);
 742	return ret;
 743}
 744
 745int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
 746{
 747	struct acx_event_mask *mask;
 748	int ret;
 749
 750	wl1251_debug(DEBUG_ACX, "acx event mbox mask");
 751
 752	mask = kzalloc(sizeof(*mask), GFP_KERNEL);
 753	if (!mask) {
 754		ret = -ENOMEM;
 755		goto out;
 756	}
 757
 758	/* high event mask is unused */
 759	mask->high_event_mask = 0xffffffff;
 760
 761	mask->event_mask = event_mask;
 762
 763	ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
 764				   mask, sizeof(*mask));
 765	if (ret < 0) {
 766		wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
 767		goto out;
 768	}
 769
 770out:
 771	kfree(mask);
 772	return ret;
 773}
 774
 775int wl1251_acx_low_rssi(struct wl1251 *wl, s8 threshold, u8 weight,
 776			u8 depth, enum wl1251_acx_low_rssi_type type)
 777{
 778	struct acx_low_rssi *rssi;
 779	int ret;
 780
 781	wl1251_debug(DEBUG_ACX, "acx low rssi");
 782
 783	rssi = kzalloc(sizeof(*rssi), GFP_KERNEL);
 784	if (!rssi)
 785		return -ENOMEM;
 786
 787	rssi->threshold = threshold;
 788	rssi->weight = weight;
 789	rssi->depth = depth;
 790	rssi->type = type;
 791
 792	ret = wl1251_cmd_configure(wl, ACX_LOW_RSSI, rssi, sizeof(*rssi));
 793	if (ret < 0)
 794		wl1251_warning("failed to set low rssi threshold: %d", ret);
 795
 796	kfree(rssi);
 797	return ret;
 798}
 799
 800int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
 801{
 802	struct acx_preamble *acx;
 803	int ret;
 804
 805	wl1251_debug(DEBUG_ACX, "acx_set_preamble");
 806
 807	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 808	if (!acx) {
 809		ret = -ENOMEM;
 810		goto out;
 811	}
 812
 813	acx->preamble = preamble;
 814
 815	ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
 816	if (ret < 0) {
 817		wl1251_warning("Setting of preamble failed: %d", ret);
 818		goto out;
 819	}
 820
 821out:
 822	kfree(acx);
 823	return ret;
 824}
 825
 826int wl1251_acx_cts_protect(struct wl1251 *wl,
 827			   enum acx_ctsprotect_type ctsprotect)
 828{
 829	struct acx_ctsprotect *acx;
 830	int ret;
 831
 832	wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
 833
 834	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 835	if (!acx) {
 836		ret = -ENOMEM;
 837		goto out;
 838	}
 839
 840	acx->ctsprotect = ctsprotect;
 841
 842	ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
 843	if (ret < 0) {
 844		wl1251_warning("Setting of ctsprotect failed: %d", ret);
 845		goto out;
 846	}
 847
 848out:
 849	kfree(acx);
 850	return ret;
 851}
 852
 853int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
 854{
 855	struct acx_tsf_info *tsf_info;
 856	int ret;
 857
 858	tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
 859	if (!tsf_info) {
 860		ret = -ENOMEM;
 861		goto out;
 862	}
 863
 864	ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
 865				     tsf_info, sizeof(*tsf_info));
 866	if (ret < 0) {
 867		wl1251_warning("ACX_FW_REV interrogate failed");
 868		goto out;
 869	}
 870
 871	*mactime = tsf_info->current_tsf_lsb |
 872		(tsf_info->current_tsf_msb << 31);
 873
 874out:
 875	kfree(tsf_info);
 876	return ret;
 877}
 878
 879int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
 880{
 881	int ret;
 882
 883	wl1251_debug(DEBUG_ACX, "acx statistics");
 884
 885	ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
 886				     sizeof(*stats));
 887	if (ret < 0) {
 888		wl1251_warning("acx statistics failed: %d", ret);
 889		return -ENOMEM;
 890	}
 891
 892	return 0;
 893}
 894
 895int wl1251_acx_rate_policies(struct wl1251 *wl)
 896{
 897	struct acx_rate_policy *acx;
 898	int ret = 0;
 899
 900	wl1251_debug(DEBUG_ACX, "acx rate policies");
 901
 902	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 903
 904	if (!acx) {
 905		ret = -ENOMEM;
 906		goto out;
 907	}
 908
 909	/* configure one default (one-size-fits-all) rate class */
 910	acx->rate_class_cnt = 1;
 911	acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
 912	acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
 913	acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
 914	acx->rate_class[0].aflags = 0;
 915
 916	ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 917	if (ret < 0) {
 918		wl1251_warning("Setting of rate policies failed: %d", ret);
 919		goto out;
 920	}
 921
 922out:
 923	kfree(acx);
 924	return ret;
 925}
 926
 927int wl1251_acx_mem_cfg(struct wl1251 *wl)
 928{
 929	struct wl1251_acx_config_memory *mem_conf;
 930	int ret, i;
 931
 932	wl1251_debug(DEBUG_ACX, "acx mem cfg");
 933
 934	mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
 935	if (!mem_conf) {
 936		ret = -ENOMEM;
 937		goto out;
 938	}
 939
 940	/* memory config */
 941	mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
 942	mem_conf->mem_config.rx_mem_block_num = 35;
 943	mem_conf->mem_config.tx_min_mem_block_num = 64;
 944	mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
 945	mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
 946	mem_conf->mem_config.num_ssid_profiles = 1;
 947	mem_conf->mem_config.debug_buffer_size =
 948		cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
 949
 950	/* RX queue config */
 951	mem_conf->rx_queue_config.dma_address = 0;
 952	mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
 953	mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
 954	mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
 955
 956	/* TX queue config */
 957	for (i = 0; i < MAX_TX_QUEUES; i++) {
 958		mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
 959		mem_conf->tx_queue_config[i].attributes = i;
 960	}
 961
 962	ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
 963				   sizeof(*mem_conf));
 964	if (ret < 0) {
 965		wl1251_warning("wl1251 mem config failed: %d", ret);
 966		goto out;
 967	}
 968
 969out:
 970	kfree(mem_conf);
 971	return ret;
 972}
 973
 974int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
 975{
 976	struct wl1251_acx_wr_tbtt_and_dtim *acx;
 977	int ret;
 978
 979	wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
 980
 981	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 982	if (!acx) {
 983		ret = -ENOMEM;
 984		goto out;
 985	}
 986
 987	acx->tbtt = tbtt;
 988	acx->dtim = dtim;
 989
 990	ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
 991				   acx, sizeof(*acx));
 992	if (ret < 0) {
 993		wl1251_warning("failed to set tbtt and dtim: %d", ret);
 994		goto out;
 995	}
 996
 997out:
 998	kfree(acx);
 999	return ret;
1000}
1001
1002int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
1003			  u8 max_consecutive)
1004{
1005	struct wl1251_acx_bet_enable *acx;
1006	int ret;
1007
1008	wl1251_debug(DEBUG_ACX, "acx bet enable");
1009
1010	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1011	if (!acx) {
1012		ret = -ENOMEM;
1013		goto out;
1014	}
1015
1016	acx->enable = mode;
1017	acx->max_consecutive = max_consecutive;
1018
1019	ret = wl1251_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
1020	if (ret < 0) {
1021		wl1251_warning("wl1251 acx bet enable failed: %d", ret);
1022		goto out;
1023	}
1024
1025out:
1026	kfree(acx);
1027	return ret;
1028}
1029
1030int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1031		      u8 aifs, u16 txop)
1032{
1033	struct wl1251_acx_ac_cfg *acx;
1034	int ret = 0;
1035
1036	wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
1037		     "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
1038
1039	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1040
1041	if (!acx) {
1042		ret = -ENOMEM;
1043		goto out;
1044	}
1045
1046	acx->ac = ac;
1047	acx->cw_min = cw_min;
1048	acx->cw_max = cw_max;
1049	acx->aifsn = aifs;
1050	acx->txop_limit = txop;
1051
1052	ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
1053	if (ret < 0) {
1054		wl1251_warning("acx ac cfg failed: %d", ret);
1055		goto out;
1056	}
1057
1058out:
1059	kfree(acx);
1060	return ret;
1061}
1062
1063int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1064		       enum wl1251_acx_channel_type type,
1065		       u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
1066		       enum wl1251_acx_ack_policy ack_policy)
1067{
1068	struct wl1251_acx_tid_cfg *acx;
1069	int ret = 0;
1070
1071	wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
1072		     "ps_scheme %d ack_policy %d", queue, type, tsid,
1073		     ps_scheme, ack_policy);
1074
1075	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1076
1077	if (!acx) {
1078		ret = -ENOMEM;
1079		goto out;
1080	}
1081
1082	acx->queue = queue;
1083	acx->type = type;
1084	acx->tsid = tsid;
1085	acx->ps_scheme = ps_scheme;
1086	acx->ack_policy = ack_policy;
1087
1088	ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
1089	if (ret < 0) {
1090		wl1251_warning("acx tid cfg failed: %d", ret);
1091		goto out;
1092	}
1093
1094out:
1095	kfree(acx);
1096	return ret;
1097}