wl1251_acx.c 19.0 KB
Newer Older
1
#include "wl1251_acx.h"
K
Kalle Valo 已提交
2 3 4 5

#include <linux/module.h>
#include <linux/crc7.h>

K
Kalle Valo 已提交
6
#include "wl1251.h"
K
Kalle Valo 已提交
7
#include "reg.h"
8
#include "wl1251_cmd.h"
9
#include "wl1251_ps.h"
K
Kalle Valo 已提交
10

11
int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
K
Kalle Valo 已提交
12 13
			   u8 mgt_rate, u8 mgt_mod)
{
14
	struct acx_fw_gen_frame_rates *rates;
K
Kalle Valo 已提交
15 16
	int ret;

17
	wl1251_debug(DEBUG_ACX, "acx frame rates");
K
Kalle Valo 已提交
18

19 20 21 22 23
	rates = kzalloc(sizeof(*rates), GFP_KERNEL);
	if (!rates) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
24

25 26 27 28
	rates->tx_ctrl_frame_rate = ctrl_rate;
	rates->tx_ctrl_frame_mod = ctrl_mod;
	rates->tx_mgt_frame_rate = mgt_rate;
	rates->tx_mgt_frame_mod = mgt_mod;
K
Kalle Valo 已提交
29

30
	ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
31
				   rates, sizeof(*rates));
K
Kalle Valo 已提交
32
	if (ret < 0) {
33
		wl1251_error("Failed to set FW rates and modulation");
34
		goto out;
K
Kalle Valo 已提交
35 36
	}

37 38 39
out:
	kfree(rates);
	return ret;
K
Kalle Valo 已提交
40 41 42
}


43
int wl1251_acx_station_id(struct wl1251 *wl)
K
Kalle Valo 已提交
44
{
45
	struct acx_dot11_station_id *mac;
K
Kalle Valo 已提交
46 47
	int ret, i;

48
	wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
K
Kalle Valo 已提交
49

50 51 52 53 54
	mac = kzalloc(sizeof(*mac), GFP_KERNEL);
	if (!mac) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
55 56

	for (i = 0; i < ETH_ALEN; i++)
57
		mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
K
Kalle Valo 已提交
58

59
	ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
K
Kalle Valo 已提交
60
	if (ret < 0)
61
		goto out;
K
Kalle Valo 已提交
62

63 64 65
out:
	kfree(mac);
	return ret;
K
Kalle Valo 已提交
66 67
}

68
int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
K
Kalle Valo 已提交
69
{
70
	struct acx_dot11_default_key *default_key;
K
Kalle Valo 已提交
71 72
	int ret;

73
	wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
K
Kalle Valo 已提交
74

75 76 77 78 79
	default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
	if (!default_key) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
80

81
	default_key->id = key_id;
K
Kalle Valo 已提交
82

83
	ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
84
				   default_key, sizeof(*default_key));
K
Kalle Valo 已提交
85
	if (ret < 0) {
S
Stefan Weil 已提交
86
		wl1251_error("Couldn't set default key");
87
		goto out;
K
Kalle Valo 已提交
88 89 90 91
	}

	wl->default_key = key_id;

92 93 94
out:
	kfree(default_key);
	return ret;
K
Kalle Valo 已提交
95 96
}

97
int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
98
				  u8 listen_interval)
K
Kalle Valo 已提交
99
{
100 101
	struct acx_wake_up_condition *wake_up;
	int ret;
K
Kalle Valo 已提交
102

103
	wl1251_debug(DEBUG_ACX, "acx wake up conditions");
K
Kalle Valo 已提交
104

105 106 107 108 109
	wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
	if (!wake_up) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
110

111
	wake_up->wake_up_event = wake_up_event;
112
	wake_up->listen_interval = listen_interval;
K
Kalle Valo 已提交
113

114
	ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
115 116
				   wake_up, sizeof(*wake_up));
	if (ret < 0) {
117
		wl1251_warning("could not set wake up conditions: %d", ret);
118 119 120 121 122 123
		goto out;
	}

out:
	kfree(wake_up);
	return ret;
K
Kalle Valo 已提交
124 125
}

126
int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
K
Kalle Valo 已提交
127
{
128
	struct acx_sleep_auth *auth;
K
Kalle Valo 已提交
129 130
	int ret;

131
	wl1251_debug(DEBUG_ACX, "acx sleep auth");
K
Kalle Valo 已提交
132

133 134 135 136 137
	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
	if (!auth) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
138

139
	auth->sleep_auth = sleep_auth;
K
Kalle Valo 已提交
140

141
	ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
K
Kalle Valo 已提交
142 143 144
	if (ret < 0)
		return ret;

145 146 147
out:
	kfree(auth);
	return ret;
K
Kalle Valo 已提交
148 149
}

150
int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
K
Kalle Valo 已提交
151 152 153 154
{
	struct acx_revision *rev;
	int ret;

155
	wl1251_debug(DEBUG_ACX, "acx fw rev");
K
Kalle Valo 已提交
156

157 158 159 160 161
	rev = kzalloc(sizeof(*rev), GFP_KERNEL);
	if (!rev) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
162

163
	ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
K
Kalle Valo 已提交
164
	if (ret < 0) {
165
		wl1251_warning("ACX_FW_REV interrogate failed");
166
		goto out;
K
Kalle Valo 已提交
167 168 169 170 171 172 173 174 175 176 177 178
	}

	/* be careful with the buffer sizes */
	strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));

	/*
	 * if the firmware version string is exactly
	 * sizeof(rev->fw_version) long or fw_len is less than
	 * sizeof(rev->fw_version) it won't be null terminated
	 */
	buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';

179 180 181
out:
	kfree(rev);
	return ret;
K
Kalle Valo 已提交
182 183
}

184
int wl1251_acx_tx_power(struct wl1251 *wl, int power)
K
Kalle Valo 已提交
185
{
186
	struct acx_current_tx_power *acx;
K
Kalle Valo 已提交
187 188
	int ret;

189
	wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
K
Kalle Valo 已提交
190 191 192 193

	if (power < 0 || power > 25)
		return -EINVAL;

194 195 196 197 198
	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
199

200
	acx->current_tx_power = power * 10;
K
Kalle Valo 已提交
201

202
	ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
K
Kalle Valo 已提交
203
	if (ret < 0) {
204
		wl1251_warning("configure of tx power failed: %d", ret);
205
		goto out;
K
Kalle Valo 已提交
206 207
	}

208 209 210
out:
	kfree(acx);
	return ret;
K
Kalle Valo 已提交
211 212
}

213
int wl1251_acx_feature_cfg(struct wl1251 *wl)
K
Kalle Valo 已提交
214
{
215
	struct acx_feature_config *feature;
K
Kalle Valo 已提交
216 217
	int ret;

218
	wl1251_debug(DEBUG_ACX, "acx feature cfg");
K
Kalle Valo 已提交
219

220 221 222 223 224
	feature = kzalloc(sizeof(*feature), GFP_KERNEL);
	if (!feature) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
225 226

	/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
227 228
	feature->data_flow_options = 0;
	feature->options = 0;
K
Kalle Valo 已提交
229

230
	ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
231 232
				   feature, sizeof(*feature));
	if (ret < 0) {
S
Stefan Weil 已提交
233
		wl1251_error("Couldn't set HW encryption");
234 235
		goto out;
	}
K
Kalle Valo 已提交
236

237 238
out:
	kfree(feature);
K
Kalle Valo 已提交
239 240 241
	return ret;
}

242
int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
243
		       size_t len)
K
Kalle Valo 已提交
244 245 246
{
	int ret;

247
	wl1251_debug(DEBUG_ACX, "acx mem map");
K
Kalle Valo 已提交
248

249
	ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
K
Kalle Valo 已提交
250 251 252 253 254 255
	if (ret < 0)
		return ret;

	return 0;
}

256
int wl1251_acx_data_path_params(struct wl1251 *wl,
257
				struct acx_data_path_params_resp *resp)
K
Kalle Valo 已提交
258
{
259
	struct acx_data_path_params *params;
K
Kalle Valo 已提交
260 261
	int ret;

262
	wl1251_debug(DEBUG_ACX, "acx data path params");
K
Kalle Valo 已提交
263

264 265 266 267 268
	params = kzalloc(sizeof(*params), GFP_KERNEL);
	if (!params) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
269

270 271
	params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
	params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
K
Kalle Valo 已提交
272

273 274
	params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
	params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
K
Kalle Valo 已提交
275

276
	params->tx_complete_threshold = 1;
K
Kalle Valo 已提交
277

278
	params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
K
Kalle Valo 已提交
279

280
	params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
K
Kalle Valo 已提交
281

282
	ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
283
				   params, sizeof(*params));
K
Kalle Valo 已提交
284
	if (ret < 0)
285
		goto out;
K
Kalle Valo 已提交
286

287
	/* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
288
	ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
289
				     resp, sizeof(*resp));
K
Kalle Valo 已提交
290 291

	if (ret < 0) {
292
		wl1251_warning("failed to read data path parameters: %d", ret);
293 294
		goto out;
	} else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
295
		wl1251_warning("data path parameter acx status failed");
296 297
		ret = -EIO;
		goto out;
K
Kalle Valo 已提交
298 299
	}

300 301 302
out:
	kfree(params);
	return ret;
K
Kalle Valo 已提交
303 304
}

305
int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
K
Kalle Valo 已提交
306
{
307
	struct acx_rx_msdu_lifetime *acx;
K
Kalle Valo 已提交
308 309
	int ret;

310
	wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
K
Kalle Valo 已提交
311

312 313 314 315 316
	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
317

318
	acx->lifetime = life_time;
319
	ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
320
				   acx, sizeof(*acx));
K
Kalle Valo 已提交
321
	if (ret < 0) {
322
		wl1251_warning("failed to set rx msdu life time: %d", ret);
323
		goto out;
K
Kalle Valo 已提交
324 325
	}

326 327 328
out:
	kfree(acx);
	return ret;
K
Kalle Valo 已提交
329 330
}

331
int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
K
Kalle Valo 已提交
332
{
333
	struct acx_rx_config *rx_config;
K
Kalle Valo 已提交
334 335
	int ret;

336
	wl1251_debug(DEBUG_ACX, "acx rx config");
K
Kalle Valo 已提交
337

338 339 340 341 342 343 344 345
	rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
	if (!rx_config) {
		ret = -ENOMEM;
		goto out;
	}

	rx_config->config_options = config;
	rx_config->filter_options = filter;
K
Kalle Valo 已提交
346

347
	ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
348
				   rx_config, sizeof(*rx_config));
K
Kalle Valo 已提交
349
	if (ret < 0) {
350
		wl1251_warning("failed to set rx config: %d", ret);
351
		goto out;
K
Kalle Valo 已提交
352 353
	}

354 355 356
out:
	kfree(rx_config);
	return ret;
K
Kalle Valo 已提交
357 358
}

359
int wl1251_acx_pd_threshold(struct wl1251 *wl)
K
Kalle Valo 已提交
360
{
361
	struct acx_packet_detection *pd;
K
Kalle Valo 已提交
362 363
	int ret;

364
	wl1251_debug(DEBUG_ACX, "acx data pd threshold");
K
Kalle Valo 已提交
365

366 367 368 369 370 371
	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
	if (!pd) {
		ret = -ENOMEM;
		goto out;
	}

K
Kalle Valo 已提交
372 373
	/* FIXME: threshold value not set */

374
	ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
K
Kalle Valo 已提交
375
	if (ret < 0) {
376
		wl1251_warning("failed to set pd threshold: %d", ret);
377
		goto out;
K
Kalle Valo 已提交
378 379
	}

380 381
out:
	kfree(pd);
K
Kalle Valo 已提交
382 383 384
	return 0;
}

385
int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
K
Kalle Valo 已提交
386
{
387
	struct acx_slot *slot;
K
Kalle Valo 已提交
388 389
	int ret;

390
	wl1251_debug(DEBUG_ACX, "acx slot");
K
Kalle Valo 已提交
391

392 393 394 395 396
	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
	if (!slot) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
397

398 399
	slot->wone_index = STATION_WONE_INDEX;
	slot->slot_time = slot_time;
K
Kalle Valo 已提交
400

401
	ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
K
Kalle Valo 已提交
402
	if (ret < 0) {
403
		wl1251_warning("failed to set slot time: %d", ret);
404
		goto out;
K
Kalle Valo 已提交
405 406
	}

407 408 409
out:
	kfree(slot);
	return ret;
K
Kalle Valo 已提交
410 411
}

412
int wl1251_acx_group_address_tbl(struct wl1251 *wl)
K
Kalle Valo 已提交
413
{
414
	struct acx_dot11_grp_addr_tbl *acx;
K
Kalle Valo 已提交
415 416
	int ret;

417
	wl1251_debug(DEBUG_ACX, "acx group address tbl");
K
Kalle Valo 已提交
418

419 420 421 422 423
	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
424

425 426 427 428
	/* MAC filtering */
	acx->enabled = 0;
	acx->num_groups = 0;
	memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
K
Kalle Valo 已提交
429

430
	ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
431
				   acx, sizeof(*acx));
K
Kalle Valo 已提交
432
	if (ret < 0) {
433
		wl1251_warning("failed to set group addr table: %d", ret);
434
		goto out;
K
Kalle Valo 已提交
435 436
	}

437 438 439
out:
	kfree(acx);
	return ret;
K
Kalle Valo 已提交
440 441
}

442
int wl1251_acx_service_period_timeout(struct wl1251 *wl)
K
Kalle Valo 已提交
443
{
444
	struct acx_rx_timeout *rx_timeout;
K
Kalle Valo 已提交
445 446
	int ret;

447 448 449 450 451
	rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
	if (!rx_timeout) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
452

453
	wl1251_debug(DEBUG_ACX, "acx service period timeout");
K
Kalle Valo 已提交
454

455 456
	rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
	rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
K
Kalle Valo 已提交
457

458
	ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
459
				   rx_timeout, sizeof(*rx_timeout));
K
Kalle Valo 已提交
460
	if (ret < 0) {
461
		wl1251_warning("failed to set service period timeout: %d",
K
Kalle Valo 已提交
462
			       ret);
463
		goto out;
K
Kalle Valo 已提交
464 465
	}

466 467 468
out:
	kfree(rx_timeout);
	return ret;
K
Kalle Valo 已提交
469 470
}

471
int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
K
Kalle Valo 已提交
472
{
473
	struct acx_rts_threshold *rts;
K
Kalle Valo 已提交
474 475
	int ret;

476
	wl1251_debug(DEBUG_ACX, "acx rts threshold");
K
Kalle Valo 已提交
477

478 479 480 481 482
	rts = kzalloc(sizeof(*rts), GFP_KERNEL);
	if (!rts) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
483

484
	rts->threshold = rts_threshold;
K
Kalle Valo 已提交
485

486
	ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
K
Kalle Valo 已提交
487
	if (ret < 0) {
488
		wl1251_warning("failed to set rts threshold: %d", ret);
489
		goto out;
K
Kalle Valo 已提交
490 491
	}

492 493 494
out:
	kfree(rts);
	return ret;
K
Kalle Valo 已提交
495 496
}

497
int wl1251_acx_beacon_filter_opt(struct wl1251 *wl)
K
Kalle Valo 已提交
498
{
499
	struct acx_beacon_filter_option *beacon_filter;
K
Kalle Valo 已提交
500 501
	int ret;

502
	wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
K
Kalle Valo 已提交
503

504 505 506 507 508
	beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
	if (!beacon_filter) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
509

510 511
	beacon_filter->enable = 0;
	beacon_filter->max_num_beacons = 0;
K
Kalle Valo 已提交
512

513
	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
514
				   beacon_filter, sizeof(*beacon_filter));
K
Kalle Valo 已提交
515
	if (ret < 0) {
516
		wl1251_warning("failed to set beacon filter opt: %d", ret);
517
		goto out;
K
Kalle Valo 已提交
518 519
	}

520 521 522
out:
	kfree(beacon_filter);
	return ret;
K
Kalle Valo 已提交
523 524
}

525
int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
K
Kalle Valo 已提交
526
{
527
	struct acx_beacon_filter_ie_table *ie_table;
K
Kalle Valo 已提交
528 529
	int ret;

530
	wl1251_debug(DEBUG_ACX, "acx beacon filter table");
K
Kalle Valo 已提交
531

532 533 534 535 536
	ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
	if (!ie_table) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
537

538 539
	ie_table->num_ie = 0;
	memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
K
Kalle Valo 已提交
540

541
	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
542
				   ie_table, sizeof(*ie_table));
K
Kalle Valo 已提交
543
	if (ret < 0) {
544
		wl1251_warning("failed to set beacon filter table: %d", ret);
545
		goto out;
K
Kalle Valo 已提交
546 547
	}

548 549 550
out:
	kfree(ie_table);
	return ret;
K
Kalle Valo 已提交
551 552
}

553
int wl1251_acx_sg_enable(struct wl1251 *wl)
K
Kalle Valo 已提交
554
{
555
	struct acx_bt_wlan_coex *pta;
K
Kalle Valo 已提交
556 557
	int ret;

558
	wl1251_debug(DEBUG_ACX, "acx sg enable");
K
Kalle Valo 已提交
559

560 561 562 563 564
	pta = kzalloc(sizeof(*pta), GFP_KERNEL);
	if (!pta) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
565

566
	pta->enable = SG_ENABLE;
K
Kalle Valo 已提交
567

568
	ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
K
Kalle Valo 已提交
569
	if (ret < 0) {
570
		wl1251_warning("failed to set softgemini enable: %d", ret);
571
		goto out;
K
Kalle Valo 已提交
572 573
	}

574 575 576
out:
	kfree(pta);
	return ret;
K
Kalle Valo 已提交
577 578
}

579
int wl1251_acx_sg_cfg(struct wl1251 *wl)
K
Kalle Valo 已提交
580
{
581
	struct acx_bt_wlan_coex_param *param;
K
Kalle Valo 已提交
582 583
	int ret;

584
	wl1251_debug(DEBUG_ACX, "acx sg cfg");
K
Kalle Valo 已提交
585

586 587 588 589 590 591
	param = kzalloc(sizeof(*param), GFP_KERNEL);
	if (!param) {
		ret = -ENOMEM;
		goto out;
	}

K
Kalle Valo 已提交
592
	/* BT-WLAN coext parameters */
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
	param->min_rate = RATE_INDEX_24MBPS;
	param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
	param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
	param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
	param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
	param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
	param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
	param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
	param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
	param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
	param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
	param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
	param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
	param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
	param->antenna_type = PTA_ANTENNA_TYPE_DEF;
	param->signal_type = PTA_SIGNALING_TYPE_DEF;
	param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
	param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
	param->max_cts = PTA_MAX_NUM_CTS_DEF;
	param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
	param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
	param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
	param->wlan_elp_hp = PTA_ELP_HP_DEF;
	param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
	param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
	param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
	param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
	param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;

622
	ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
K
Kalle Valo 已提交
623
	if (ret < 0) {
624
		wl1251_warning("failed to set sg config: %d", ret);
625
		goto out;
K
Kalle Valo 已提交
626 627
	}

628 629 630
out:
	kfree(param);
	return ret;
K
Kalle Valo 已提交
631 632
}

633
int wl1251_acx_cca_threshold(struct wl1251 *wl)
K
Kalle Valo 已提交
634
{
635
	struct acx_energy_detection *detection;
K
Kalle Valo 已提交
636 637
	int ret;

638
	wl1251_debug(DEBUG_ACX, "acx cca threshold");
K
Kalle Valo 已提交
639

640 641 642 643 644
	detection = kzalloc(sizeof(*detection), GFP_KERNEL);
	if (!detection) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
645

646 647
	detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
	detection->tx_energy_detection = 0;
K
Kalle Valo 已提交
648

649
	ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
650
				   detection, sizeof(*detection));
K
Kalle Valo 已提交
651
	if (ret < 0) {
652
		wl1251_warning("failed to set cca threshold: %d", ret);
K
Kalle Valo 已提交
653 654 655
		return ret;
	}

656 657 658
out:
	kfree(detection);
	return ret;
K
Kalle Valo 已提交
659 660
}

661
int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
K
Kalle Valo 已提交
662
{
663
	struct acx_beacon_broadcast *bb;
K
Kalle Valo 已提交
664 665
	int ret;

666
	wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
K
Kalle Valo 已提交
667

668 669 670 671 672
	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
	if (!bb) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
673

674 675 676 677
	bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
	bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
	bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
	bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
K
Kalle Valo 已提交
678

679
	ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
K
Kalle Valo 已提交
680
	if (ret < 0) {
681
		wl1251_warning("failed to set rx config: %d", ret);
682
		goto out;
K
Kalle Valo 已提交
683 684
	}

685 686 687
out:
	kfree(bb);
	return ret;
K
Kalle Valo 已提交
688 689
}

690
int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
K
Kalle Valo 已提交
691
{
692
	struct acx_aid *acx_aid;
K
Kalle Valo 已提交
693 694
	int ret;

695
	wl1251_debug(DEBUG_ACX, "acx aid");
K
Kalle Valo 已提交
696

697 698 699 700 701
	acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
	if (!acx_aid) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
702

703
	acx_aid->aid = aid;
K
Kalle Valo 已提交
704

705
	ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
K
Kalle Valo 已提交
706
	if (ret < 0) {
707
		wl1251_warning("failed to set aid: %d", ret);
708
		goto out;
K
Kalle Valo 已提交
709 710
	}

711 712 713
out:
	kfree(acx_aid);
	return ret;
K
Kalle Valo 已提交
714 715
}

716
int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
K
Kalle Valo 已提交
717
{
718
	struct acx_event_mask *mask;
K
Kalle Valo 已提交
719 720
	int ret;

721
	wl1251_debug(DEBUG_ACX, "acx event mbox mask");
K
Kalle Valo 已提交
722

723 724 725 726 727
	mask = kzalloc(sizeof(*mask), GFP_KERNEL);
	if (!mask) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
728 729

	/* high event mask is unused */
730
	mask->high_event_mask = 0xffffffff;
K
Kalle Valo 已提交
731

732
	mask->event_mask = event_mask;
K
Kalle Valo 已提交
733

734
	ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
735
				   mask, sizeof(*mask));
K
Kalle Valo 已提交
736
	if (ret < 0) {
737
		wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
738
		goto out;
K
Kalle Valo 已提交
739 740
	}

741 742 743
out:
	kfree(mask);
	return ret;
K
Kalle Valo 已提交
744 745
}

746
int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
K
Kalle Valo 已提交
747
{
748
	struct acx_preamble *acx;
K
Kalle Valo 已提交
749 750
	int ret;

751
	wl1251_debug(DEBUG_ACX, "acx_set_preamble");
K
Kalle Valo 已提交
752

753 754 755 756 757
	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
758

759 760
	acx->preamble = preamble;

761
	ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
K
Kalle Valo 已提交
762
	if (ret < 0) {
763
		wl1251_warning("Setting of preamble failed: %d", ret);
764
		goto out;
K
Kalle Valo 已提交
765
	}
766 767 768 769

out:
	kfree(acx);
	return ret;
K
Kalle Valo 已提交
770 771
}

772
int wl1251_acx_cts_protect(struct wl1251 *wl,
K
Kalle Valo 已提交
773 774
			   enum acx_ctsprotect_type ctsprotect)
{
775
	struct acx_ctsprotect *acx;
K
Kalle Valo 已提交
776 777
	int ret;

778
	wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
K
Kalle Valo 已提交
779

780 781 782 783 784 785 786
	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}

	acx->ctsprotect = ctsprotect;
K
Kalle Valo 已提交
787

788
	ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
K
Kalle Valo 已提交
789
	if (ret < 0) {
790
		wl1251_warning("Setting of ctsprotect failed: %d", ret);
791
		goto out;
K
Kalle Valo 已提交
792
	}
793 794 795 796

out:
	kfree(acx);
	return ret;
K
Kalle Valo 已提交
797 798
}

799
int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
K
Kalle Valo 已提交
800
{
801
	struct acx_tsf_info *tsf_info;
K
Kalle Valo 已提交
802 803
	int ret;

804 805
	tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
	if (!tsf_info) {
K
Kalle Valo 已提交
806 807 808 809
		ret = -ENOMEM;
		goto out;
	}

810
	ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
811
				     tsf_info, sizeof(*tsf_info));
K
Kalle Valo 已提交
812
	if (ret < 0) {
813
		wl1251_warning("ACX_FW_REV interrogate failed");
K
Kalle Valo 已提交
814 815 816
		goto out;
	}

817 818
	*mactime = tsf_info->current_tsf_lsb |
		(tsf_info->current_tsf_msb << 31);
K
Kalle Valo 已提交
819 820

out:
821
	kfree(tsf_info);
K
Kalle Valo 已提交
822 823
	return ret;
}
824

825
int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
826 827 828
{
	int ret;

829
	wl1251_debug(DEBUG_ACX, "acx statistics");
830

831
	ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
832 833
				     sizeof(*stats));
	if (ret < 0) {
834
		wl1251_warning("acx statistics failed: %d", ret);
835 836 837 838 839
		return -ENOMEM;
	}

	return 0;
}
K
Kalle Valo 已提交
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918

int wl1251_acx_rate_policies(struct wl1251 *wl)
{
	struct acx_rate_policy *acx;
	int ret = 0;

	wl1251_debug(DEBUG_ACX, "acx rate policies");

	acx = kzalloc(sizeof(*acx), GFP_KERNEL);

	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}

	/* configure one default (one-size-fits-all) rate class */
	acx->rate_class_cnt = 1;
	acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
	acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
	acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
	acx->rate_class[0].aflags = 0;

	ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
	if (ret < 0) {
		wl1251_warning("Setting of rate policies failed: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}

int wl1251_acx_mem_cfg(struct wl1251 *wl)
{
	struct wl1251_acx_config_memory *mem_conf;
	int ret, i;

	wl1251_debug(DEBUG_ACX, "acx mem cfg");

	mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
	if (!mem_conf) {
		ret = -ENOMEM;
		goto out;
	}

	/* memory config */
	mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
	mem_conf->mem_config.rx_mem_block_num = 35;
	mem_conf->mem_config.tx_min_mem_block_num = 64;
	mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
	mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
	mem_conf->mem_config.num_ssid_profiles = 1;
	mem_conf->mem_config.debug_buffer_size =
		cpu_to_le16(TRACE_BUFFER_MAX_SIZE);

	/* RX queue config */
	mem_conf->rx_queue_config.dma_address = 0;
	mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
	mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
	mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;

	/* TX queue config */
	for (i = 0; i < MAX_TX_QUEUES; i++) {
		mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
		mem_conf->tx_queue_config[i].attributes = i;
	}

	ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
				   sizeof(*mem_conf));
	if (ret < 0) {
		wl1251_warning("wl1251 mem config failed: %d", ret);
		goto out;
	}

out:
	kfree(mem_conf);
	return ret;
}