Linux Audio

Check our new training course

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