wl1251_acx.c 21.6 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"
7
#include "wl1251_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, bool enable_filter)
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
	beacon_filter->enable = enable_filter;
511
	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;
528
	int idx = 0;
K
Kalle Valo 已提交
529 530
	int ret;

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

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

539 540 541 542
	/* configure default beacon pass-through rules */
	ie_table->num_ie = 1;
	ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
	ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
K
Kalle Valo 已提交
543

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

551 552 553
out:
	kfree(ie_table);
	return ret;
K
Kalle Valo 已提交
554 555
}

556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
int wl1251_acx_conn_monit_params(struct wl1251 *wl)
{
	struct acx_conn_monit_params *acx;
	int ret;

	wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");

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

	acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
	acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;

	ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
				   acx, sizeof(*acx));
	if (ret < 0) {
		wl1251_warning("failed to set connection monitor "
			       "parameters: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}

585
int wl1251_acx_sg_enable(struct wl1251 *wl)
K
Kalle Valo 已提交
586
{
587
	struct acx_bt_wlan_coex *pta;
K
Kalle Valo 已提交
588 589
	int ret;

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

592 593 594 595 596
	pta = kzalloc(sizeof(*pta), GFP_KERNEL);
	if (!pta) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
597

598
	pta->enable = SG_ENABLE;
K
Kalle Valo 已提交
599

600
	ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
K
Kalle Valo 已提交
601
	if (ret < 0) {
602
		wl1251_warning("failed to set softgemini enable: %d", ret);
603
		goto out;
K
Kalle Valo 已提交
604 605
	}

606 607 608
out:
	kfree(pta);
	return ret;
K
Kalle Valo 已提交
609 610
}

611
int wl1251_acx_sg_cfg(struct wl1251 *wl)
K
Kalle Valo 已提交
612
{
613
	struct acx_bt_wlan_coex_param *param;
K
Kalle Valo 已提交
614 615
	int ret;

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

618 619 620 621 622 623
	param = kzalloc(sizeof(*param), GFP_KERNEL);
	if (!param) {
		ret = -ENOMEM;
		goto out;
	}

K
Kalle Valo 已提交
624
	/* BT-WLAN coext parameters */
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
	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;

654
	ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
K
Kalle Valo 已提交
655
	if (ret < 0) {
656
		wl1251_warning("failed to set sg config: %d", ret);
657
		goto out;
K
Kalle Valo 已提交
658 659
	}

660 661 662
out:
	kfree(param);
	return ret;
K
Kalle Valo 已提交
663 664
}

665
int wl1251_acx_cca_threshold(struct wl1251 *wl)
K
Kalle Valo 已提交
666
{
667
	struct acx_energy_detection *detection;
K
Kalle Valo 已提交
668 669
	int ret;

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

672 673 674 675 676
	detection = kzalloc(sizeof(*detection), GFP_KERNEL);
	if (!detection) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
677

678 679
	detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
	detection->tx_energy_detection = 0;
K
Kalle Valo 已提交
680

681
	ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
682
				   detection, sizeof(*detection));
K
Kalle Valo 已提交
683
	if (ret < 0) {
684
		wl1251_warning("failed to set cca threshold: %d", ret);
K
Kalle Valo 已提交
685 686 687
		return ret;
	}

688 689 690
out:
	kfree(detection);
	return ret;
K
Kalle Valo 已提交
691 692
}

693
int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
K
Kalle Valo 已提交
694
{
695
	struct acx_beacon_broadcast *bb;
K
Kalle Valo 已提交
696 697
	int ret;

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

700 701 702 703 704
	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
	if (!bb) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
705

706 707 708 709
	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 已提交
710

711
	ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
K
Kalle Valo 已提交
712
	if (ret < 0) {
713
		wl1251_warning("failed to set rx config: %d", ret);
714
		goto out;
K
Kalle Valo 已提交
715 716
	}

717 718 719
out:
	kfree(bb);
	return ret;
K
Kalle Valo 已提交
720 721
}

722
int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
K
Kalle Valo 已提交
723
{
724
	struct acx_aid *acx_aid;
K
Kalle Valo 已提交
725 726
	int ret;

727
	wl1251_debug(DEBUG_ACX, "acx aid");
K
Kalle Valo 已提交
728

729 730 731 732 733
	acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
	if (!acx_aid) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
734

735
	acx_aid->aid = aid;
K
Kalle Valo 已提交
736

737
	ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
K
Kalle Valo 已提交
738
	if (ret < 0) {
739
		wl1251_warning("failed to set aid: %d", ret);
740
		goto out;
K
Kalle Valo 已提交
741 742
	}

743 744 745
out:
	kfree(acx_aid);
	return ret;
K
Kalle Valo 已提交
746 747
}

748
int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
K
Kalle Valo 已提交
749
{
750
	struct acx_event_mask *mask;
K
Kalle Valo 已提交
751 752
	int ret;

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

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

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

764
	mask->event_mask = event_mask;
K
Kalle Valo 已提交
765

766
	ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
767
				   mask, sizeof(*mask));
K
Kalle Valo 已提交
768
	if (ret < 0) {
769
		wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
770
		goto out;
K
Kalle Valo 已提交
771 772
	}

773 774 775
out:
	kfree(mask);
	return ret;
K
Kalle Valo 已提交
776 777
}

778
int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
K
Kalle Valo 已提交
779
{
780
	struct acx_preamble *acx;
K
Kalle Valo 已提交
781 782
	int ret;

783
	wl1251_debug(DEBUG_ACX, "acx_set_preamble");
K
Kalle Valo 已提交
784

785 786 787 788 789
	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
790

791 792
	acx->preamble = preamble;

793
	ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
K
Kalle Valo 已提交
794
	if (ret < 0) {
795
		wl1251_warning("Setting of preamble failed: %d", ret);
796
		goto out;
K
Kalle Valo 已提交
797
	}
798 799 800 801

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

804
int wl1251_acx_cts_protect(struct wl1251 *wl,
K
Kalle Valo 已提交
805 806
			   enum acx_ctsprotect_type ctsprotect)
{
807
	struct acx_ctsprotect *acx;
K
Kalle Valo 已提交
808 809
	int ret;

810
	wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
K
Kalle Valo 已提交
811

812 813 814 815 816 817 818
	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}

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

820
	ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
K
Kalle Valo 已提交
821
	if (ret < 0) {
822
		wl1251_warning("Setting of ctsprotect failed: %d", ret);
823
		goto out;
K
Kalle Valo 已提交
824
	}
825 826 827 828

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

831
int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
K
Kalle Valo 已提交
832
{
833
	struct acx_tsf_info *tsf_info;
K
Kalle Valo 已提交
834 835
	int ret;

836 837
	tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
	if (!tsf_info) {
K
Kalle Valo 已提交
838 839 840 841
		ret = -ENOMEM;
		goto out;
	}

842
	ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
843
				     tsf_info, sizeof(*tsf_info));
K
Kalle Valo 已提交
844
	if (ret < 0) {
845
		wl1251_warning("ACX_FW_REV interrogate failed");
K
Kalle Valo 已提交
846 847 848
		goto out;
	}

849 850
	*mactime = tsf_info->current_tsf_lsb |
		(tsf_info->current_tsf_msb << 31);
K
Kalle Valo 已提交
851 852

out:
853
	kfree(tsf_info);
K
Kalle Valo 已提交
854 855
	return ret;
}
856

857
int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
858 859 860
{
	int ret;

861
	wl1251_debug(DEBUG_ACX, "acx statistics");
862

863
	ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
864 865
				     sizeof(*stats));
	if (ret < 0) {
866
		wl1251_warning("acx statistics failed: %d", ret);
867 868 869 870 871
		return -ENOMEM;
	}

	return 0;
}
K
Kalle Valo 已提交
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 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950

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;
}
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978

int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
{
	struct wl1251_acx_wr_tbtt_and_dtim *acx;
	int ret;

	wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");

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

	acx->tbtt = tbtt;
	acx->dtim = dtim;

	ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
				   acx, sizeof(*acx));
	if (ret < 0) {
		wl1251_warning("failed to set tbtt and dtim: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}
979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011

int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
		      u8 aifs, u16 txop)
{
	struct wl1251_acx_ac_cfg *acx;
	int ret = 0;

	wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
		     "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);

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

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

	acx->ac = ac;
	acx->cw_min = cw_min;
	acx->cw_max = cw_max;
	acx->aifsn = aifs;
	acx->txop_limit = txop;

	ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
	if (ret < 0) {
		wl1251_warning("acx ac cfg failed: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047

int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
		       enum wl1251_acx_channel_type type,
		       u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
		       enum wl1251_acx_ack_policy ack_policy)
{
	struct wl1251_acx_tid_cfg *acx;
	int ret = 0;

	wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
		     "ps_scheme %d ack_policy %d", queue, type, tsid,
		     ps_scheme, ack_policy);

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

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

	acx->queue = queue;
	acx->type = type;
	acx->tsid = tsid;
	acx->ps_scheme = ps_scheme;
	acx->ack_policy = ack_policy;

	ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
	if (ret < 0) {
		wl1251_warning("acx tid cfg failed: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}