host_interface.c 127 KB
Newer Older
1
2
3
4
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/kthread.h>
#include <linux/delay.h>
5
6
#include "host_interface.h"
#include "coreconfigurator.h"
7
#include "wilc_wlan.h"
8
#include "wilc_wlan_if.h"
9
#include "wilc_msgqueue.h"
10
#include <linux/etherdevice.h>
11
#include "wilc_wfi_netdevice.h"
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#define HOST_IF_MSG_SCAN                        0
#define HOST_IF_MSG_CONNECT                     1
#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO        2
#define HOST_IF_MSG_KEY                         3
#define HOST_IF_MSG_RCVD_NTWRK_INFO             4
#define HOST_IF_MSG_RCVD_SCAN_COMPLETE          5
#define HOST_IF_MSG_CFG_PARAMS                  6
#define HOST_IF_MSG_SET_CHANNEL                 7
#define HOST_IF_MSG_DISCONNECT                  8
#define HOST_IF_MSG_GET_RSSI                    9
#define HOST_IF_MSG_GET_CHNL                    10
#define HOST_IF_MSG_ADD_BEACON                  11
#define HOST_IF_MSG_DEL_BEACON                  12
#define HOST_IF_MSG_ADD_STATION                 13
#define HOST_IF_MSG_DEL_STATION                 14
#define HOST_IF_MSG_EDIT_STATION                15
#define HOST_IF_MSG_SCAN_TIMER_FIRED            16
#define HOST_IF_MSG_CONNECT_TIMER_FIRED         17
#define HOST_IF_MSG_POWER_MGMT                  18
#define HOST_IF_MSG_GET_INACTIVETIME            19
#define HOST_IF_MSG_REMAIN_ON_CHAN              20
#define HOST_IF_MSG_REGISTER_FRAME              21
#define HOST_IF_MSG_LISTEN_TIMER_FIRED          22
#define HOST_IF_MSG_GET_LINKSPEED               23
#define HOST_IF_MSG_SET_WFIDRV_HANDLER          24
#define HOST_IF_MSG_SET_MAC_ADDRESS             25
#define HOST_IF_MSG_GET_MAC_ADDRESS             26
#define HOST_IF_MSG_SET_OPERATION_MODE          27
#define HOST_IF_MSG_SET_IPADDRESS               28
#define HOST_IF_MSG_GET_IPADDRESS               29
#define HOST_IF_MSG_FLUSH_CONNECT               30
#define HOST_IF_MSG_GET_STATISTICS              31
#define HOST_IF_MSG_SET_MULTICAST_FILTER        32
#define HOST_IF_MSG_DEL_BA_SESSION              34
#define HOST_IF_MSG_Q_IDLE                      35
#define HOST_IF_MSG_DEL_ALL_STA                 36
#define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS      34
#define HOST_IF_MSG_EXIT                        100
51

52
53
#define HOST_IF_SCAN_TIMEOUT                    4000
#define HOST_IF_CONNECT_TIMEOUT                 9500
54

55
56
57
#define BA_SESSION_DEFAULT_BUFFER_SIZE          16
#define BA_SESSION_DEFAULT_TIMEOUT              1000
#define BLOCK_ACK_REQ_SIZE                      0x14
58
#define FALSE_FRMWR_CHANNEL			100
59

60
struct cfg_param_attr {
61
	struct cfg_param_val cfg_attr_info;
62
};
63

64
struct host_if_wpa_attr {
65
	u8 *key;
66
	const u8 *mac_addr;
67
	u8 *seq;
68
	u8 seq_len;
69
	u8 index;
70
	u8 key_len;
71
	u8 mode;
72
};
73

74
struct host_if_wep_attr {
75
	u8 *key;
76
	u8 key_len;
77
	u8 index;
78
	u8 mode;
79
	enum AUTHTYPE auth_type;
80
};
81

82
union host_if_key_attr {
83
	struct host_if_wep_attr wep;
84
	struct host_if_wpa_attr wpa;
85
	struct host_if_pmkid_attr pmkid;
86
};
87

88
struct key_attr {
89
	enum KEY_TYPE type;
90
	u8 action;
91
	union host_if_key_attr attr;
92
};
93

94
struct scan_attr {
95
	u8 src;
96
	u8 type;
97
	u8 *ch_freq_list;
98
	u8 ch_list_len;
99
	u8 *ies;
100
	size_t ies_len;
101
	wilc_scan_result result;
102
	void *arg;
103
	struct hidden_network hidden_network;
104
};
105

106
struct connect_attr {
107
	u8 *bssid;
108
	u8 *ssid;
109
	size_t ssid_len;
110
	u8 *ies;
111
	size_t ies_len;
112
	u8 security;
113
	wilc_connect_result result;
114
	void *arg;
115
	enum AUTHTYPE auth_type;
116
	u8 ch;
117
	void *params;
118
};
119

120
struct rcvd_async_info {
121
	u8 *buffer;
122
	u32 len;
123
};
124

125
struct channel_attr {
126
	u8 set_ch;
127
};
128

129
struct beacon_attr {
130
	u32 interval;
131
	u32 dtim_period;
132
	u32 head_len;
133
	u8 *head;
134
	u32 tail_len;
135
	u8 *tail;
136
};
137

138
struct set_multicast {
139
	bool enabled;
140
	u32 cnt;
141
};
142

143
struct del_all_sta {
144
	u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
145
	u8 assoc_sta;
146
};
147

148
struct del_sta {
149
	u8 mac_addr[ETH_ALEN];
150
};
151

152
struct power_mgmt_param {
153
	bool enabled;
154
	u32 timeout;
155
};
156

157
struct set_ip_addr {
158
	u8 *ip_addr;
159
	u8 idx;
160
};
161

162
struct sta_inactive_t {
163
	u8 mac[6];
164
};
165

166
union message_body {
167
	struct scan_attr scan_info;
168
	struct connect_attr con_info;
169
	struct rcvd_net_info net_info;
170
	struct rcvd_async_info async_info;
171
	struct key_attr key_info;
172
	struct cfg_param_attr cfg_info;
173
	struct channel_attr channel_info;
174
	struct beacon_attr beacon_info;
175
	struct add_sta_param add_sta_info;
176
	struct del_sta del_sta_info;
177
	struct add_sta_param edit_sta_info;
178
	struct power_mgmt_param pwr_mgmt_info;
179
	struct sta_inactive_t mac_info;
180
	struct set_ip_addr ip_info;
181
	struct drv_handler drv;
182
	struct set_multicast multicast_info;
183
	struct op_mode mode;
184
	struct set_mac_addr set_mac_info;
185
	struct get_mac_addr get_mac_info;
186
	struct ba_session_info session_info;
187
	struct remain_ch remain_on_ch;
188
	struct reg_frame reg_frame;
Tony Cho's avatar
Tony Cho committed
189
	char *data;
190
	struct del_all_sta del_all_sta_info;
191
};
192

193
struct host_if_msg {
194
195
	u16 id;
	union message_body body;
196
	struct host_if_drv *drv;
197
};
198

199
struct join_bss_param {
200
	BSSTYPE_T bss_type;
201
	u8 dtim_period;
202
203
	u16 beacon_period;
	u16 cap_info;
204
	u8 au8bssid[6];
205
	char ssid[MAX_SSID_LEN];
206
	u8 ssid_len;
207
208
209
210
	u8 supp_rates[MAX_RATES_SUPPORTED + 1];
	u8 ht_capable;
	u8 wmm_cap;
	u8 uapsd_cap;
211
	bool rsn_found;
212
213
214
215
216
	u8 rsn_grp_policy;
	u8 mode_802_11i;
	u8 rsn_pcip_policy[3];
	u8 rsn_auth_policy[3];
	u8 rsn_cap[2];
217
	u32 tsf;
218
	u8 noa_enabled;
219
	u8 opp_enabled;
220
	u8 ct_window;
221
	u8 cnt;
222
	u8 idx;
223
	u8 duration[4];
224
	u8 interval[4];
225
	u8 start_time[4];
226
};
227

228
229
static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1];
struct host_if_drv *terminated_handle;
230
bool wilc_optaining_ip;
231
static u8 P2P_LISTEN_STATE;
232
static struct task_struct *hif_thread_handler;
233
static WILC_MsgQueueHandle hif_msg_q;
234
static struct semaphore hif_sema_thread;
235
static struct semaphore hif_sema_driver;
236
static struct semaphore hif_sema_wait_response;
237
static struct semaphore hif_sema_deinit;
238
static struct timer_list periodic_rssi;
239

240
u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
241

242
static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
243

244
static bool scan_while_connected;
245

246
static s8 rssi;
247
static s8 link_speed;
248
static u8 ch_no;
249
static u8 set_ip[2][4];
250
static u8 get_ip[2][4];
251
static u32 inactive_time;
252
static u8 del_beacon;
253
static u32 clients_count;
254

255
static u8 *join_req;
256
static u8 *info_element;
257
static u8 mode_11i;
258
259
static u8 auth_type;
static u32 join_req_size;
260
static u32 info_element_size;
261
static struct host_if_drv *join_req_drv;
262
263
#define REAL_JOIN_REQ 0
#define FLUSHED_JOIN_REQ 1
264
#define FLUSHED_BYTE_POS 79
265
266
267

static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo);

268
static int add_handler_in_list(struct host_if_drv *handler)
269
270
271
272
273
274
275
276
277
278
279
280
281
{
	int i;

	for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
		if (!wfidrv_list[i]) {
			wfidrv_list[i] = handler;
			return 0;
		}
	}

	return -ENOBUFS;
}

282
static int remove_handler_in_list(struct host_if_drv *handler)
283
284
285
286
287
288
289
290
291
292
293
294
295
{
	int i;

	for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
		if (wfidrv_list[i] == handler) {
			wfidrv_list[i] = NULL;
			return 0;
		}
	}

	return -EINVAL;
}

296
static int get_id_from_handler(struct host_if_drv *handler)
297
298
299
300
301
302
303
304
305
306
307
308
309
310
{
	int i;

	if (!handler)
		return 0;

	for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
		if (wfidrv_list[i] == handler)
			return i;
	}

	return 0;
}

311
static struct host_if_drv *get_handler_from_id(int id)
312
{
313
	if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list))
314
315
316
317
		return NULL;
	return wfidrv_list[id];
}

318
static s32 handle_set_channel(struct host_if_drv *hif_drv,
319
			      struct channel_attr *hif_set_ch)
320
{
321
	s32 result = 0;
322
	struct wid wid;
323

324
325
	wid.id = (u16)WID_CURRENT_CHANNEL;
	wid.type = WID_CHAR;
326
	wid.val = (char *)&hif_set_ch->set_ch;
327
	wid.size = sizeof(char);
328
329

	PRINT_D(HOSTINF_DBG, "Setting channel\n");
330

331
	result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1,
332
				 get_id_from_handler(hif_drv));
333
334

	if (result) {
335
		PRINT_ER("Failed to set channel\n");
336
		return -EINVAL;
337
338
	}

339
	return result;
340
}
341

342
343
static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv,
				      struct drv_handler *hif_drv_handler)
344
{
345
	s32 result = 0;
346
	struct wid wid;
347

348
349
	wid.id = (u16)WID_SET_DRV_HANDLER;
	wid.type = WID_INT;
350
	wid.val = (s8 *)&hif_drv_handler->handler;
351
	wid.size = sizeof(u32);
352

353
354
	result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1,
				      hif_drv_handler->handler);
355

356
	if (!hif_drv)
357
		up(&hif_sema_driver);
358

359
	if (result) {
360
		PRINT_ER("Failed to set driver handler\n");
361
		return -EINVAL;
362
363
	}

364
	return result;
365
366
}

367
368
static s32 handle_set_operation_mode(struct host_if_drv *hif_drv,
				     struct op_mode *hif_op_mode)
369
{
370
	s32 result = 0;
371
	struct wid wid;
372

373
374
	wid.id = (u16)WID_SET_OPERATION_MODE;
	wid.type = WID_INT;
375
	wid.val = (s8 *)&hif_op_mode->mode;
376
	wid.size = sizeof(u32);
377

378
	result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1,
379
				 get_id_from_handler(hif_drv));
380

381
	if ((hif_op_mode->mode) == IDLE_MODE)
382
		up(&hif_sema_driver);
383

384
	if (result) {
385
		PRINT_ER("Failed to set driver handler\n");
386
		return -EINVAL;
387
388
	}

389
	return result;
390
391
}

392
393
394
static s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx);

static s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx)
395
{
396
	s32 result = 0;
397
	struct wid wid;
398
	char firmware_ip_addr[4] = {0};
399

400
401
	if (ip_addr[0] < 192)
		ip_addr[0] = 0;
402

403
404
	PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set  IP = %pI4\n",
		   idx, ip_addr);
405

406
	memcpy(set_ip[idx], ip_addr, IP_ALEN);
407

408
409
	wid.id = (u16)WID_IP_ADDRESS;
	wid.type = WID_STR;
410
	wid.val = (u8 *)ip_addr;
411
	wid.size = IP_ALEN;
412

413
	result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1,
414
				 get_id_from_handler(hif_drv));
415

416
	host_int_get_ipaddress(hif_drv, firmware_ip_addr, idx);
417

418
	if (result) {
419
420
		PRINT_ER("Failed to set IP address\n");
		return -EINVAL;
421
422
	}

423
	PRINT_INFO(HOSTINF_DBG, "IP address set\n");
424

425
	return result;
426
427
}

428
static s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx)
429
{
430
	s32 result = 0;
431
	struct wid wid;
432

433
434
435
436
	wid.id = (u16)WID_IP_ADDRESS;
	wid.type = WID_STR;
	wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
	wid.size = IP_ALEN;
437

438
	result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1,
439
				 get_id_from_handler(hif_drv));
440

441
	PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val);
442

443
	memcpy(get_ip[idx], wid.val, IP_ALEN);
444

445
	kfree(wid.val);
446

447
	if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
448
		wilc_setup_ipaddress(hif_drv, set_ip[idx], idx);
449

450
	if (result != 0) {
451
		PRINT_ER("Failed to get IP address\n");
452
		return -EINVAL;
453
454
	}

455
	PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d\n", idx);
456
	PRINT_INFO(HOSTINF_DBG, "%pI4\n", get_ip[idx]);
457
	PRINT_INFO(HOSTINF_DBG, "\n");
458

459
	return result;
460
461
}

462
463
static s32 handle_set_mac_address(struct host_if_drv *hif_drv,
				  struct set_mac_addr *set_mac_addr)
464
{
465
	s32 result = 0;
466
	struct wid wid;
467
	u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL);
468

469
	if (!mac_buf) {
470
		PRINT_ER("No buffer to send mac address\n");
471
		return -EFAULT;
472
	}
473
	memcpy(mac_buf, set_mac_addr->mac_addr, ETH_ALEN);
474

475
476
477
478
479
	wid.id = (u16)WID_MAC_ADDR;
	wid.type = WID_STR;
	wid.val = mac_buf;
	wid.size = ETH_ALEN;
	PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val);
480

481
	result = wilc_send_config_pkt(hif_drv->wilc, SET_CFG, &wid, 1,
482
				 get_id_from_handler(hif_drv));
483
	if (result) {
484
		PRINT_ER("Failed to set mac address\n");
485
		result = -EFAULT;
486
487
	}

488
	kfree(mac_buf);
489
	return result;
490
491
}

492
493
static s32 handle_get_mac_address(struct host_if_drv *hif_drv,
				  struct get_mac_addr *get_mac_addr)
494
{
495
	s32 result = 0;
496
	struct wid wid;
497

498
499
	wid.id = (u16)WID_MAC_ADDR;
	wid.type = WID_STR;
500
	wid.val = get_mac_addr->mac_addr;
501
	wid.size = ETH_ALEN;
502

503
	result = wilc_send_config_pkt(hif_drv->wilc, GET_CFG, &wid, 1,
504
				 get_id_from_handler(hif_drv));
505
506

	if (result) {
507
		PRINT_ER("Failed to get mac address\n");
508
		result = -EFAULT;
509
	}
510
	up(&hif_sema_wait_response);
511

512
	return result;
513
514
}

515
516
static s32 handle_cfg_param(struct host_if_drv *hif_drv,
			    struct cfg_param_attr *cfg_param_attr)
517
{
518
	s32 result = 0;
519
	struct wid wid_list[32];
520
	u8 wid_cnt = 0;
521

522
	down(&hif_drv->sem_cfg_values);
523
524
525

	PRINT_D(HOSTINF_DBG, "Setting CFG params\n");

526
527
	if (cfg_param_attr->cfg_attr_info.flag & BSS_TYPE) {
		if (cfg_param_attr->cfg_attr_info.bss_type < 6) {
528
529
530
531
			wid_list[wid_cnt].id = WID_BSS_TYPE;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type;
			wid_list[wid_cnt].type = WID_CHAR;
			wid_list[wid_cnt].size = sizeof(char);
532
			hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->cfg_attr_info.bss_type;
533
		} else {
534
			PRINT_ER("check value 6 over\n");
535
			result = -EINVAL;
536
			goto ERRORHANDLER;
537
		}
538
		wid_cnt++;
539
	}
540
541
542
543
	if (cfg_param_attr->cfg_attr_info.flag & AUTH_TYPE) {
		if (cfg_param_attr->cfg_attr_info.auth_type == 1 ||
		    cfg_param_attr->cfg_attr_info.auth_type == 2 ||
		    cfg_param_attr->cfg_attr_info.auth_type == 5) {
544
545
546
547
			wid_list[wid_cnt].id = WID_AUTH_TYPE;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type;
			wid_list[wid_cnt].type = WID_CHAR;
			wid_list[wid_cnt].size = sizeof(char);
548
			hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->cfg_attr_info.auth_type;
549
		} else {
550
			PRINT_ER("Impossible value \n");
551
			result = -EINVAL;
552
			goto ERRORHANDLER;
553
		}
554
		wid_cnt++;
555
	}
556
557
558
	if (cfg_param_attr->cfg_attr_info.flag & AUTHEN_TIMEOUT) {
		if (cfg_param_attr->cfg_attr_info.auth_timeout > 0 &&
		    cfg_param_attr->cfg_attr_info.auth_timeout < 65536) {
559
560
561
562
			wid_list[wid_cnt].id = WID_AUTH_TIMEOUT;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout;
			wid_list[wid_cnt].type = WID_SHORT;
			wid_list[wid_cnt].size = sizeof(u16);
563
			hif_drv->cfg_values.auth_timeout = cfg_param_attr->cfg_attr_info.auth_timeout;
564
		} else {
565
			PRINT_ER("Range(1 ~ 65535) over\n");
566
			result = -EINVAL;
567
			goto ERRORHANDLER;
568
		}
569
		wid_cnt++;
570
	}
571
572
	if (cfg_param_attr->cfg_attr_info.flag & POWER_MANAGEMENT) {
		if (cfg_param_attr->cfg_attr_info.power_mgmt_mode < 5) {
573
574
575
576
			wid_list[wid_cnt].id = WID_POWER_MANAGEMENT;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode;
			wid_list[wid_cnt].type = WID_CHAR;
			wid_list[wid_cnt].size = sizeof(char);
577
			hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->cfg_attr_info.power_mgmt_mode;
578
		} else {
579
			PRINT_ER("Invalide power mode\n");
580
			result = -EINVAL;
581
			goto ERRORHANDLER;
582
		}
583
		wid_cnt++;
584
	}
585
586
587
	if (cfg_param_attr->cfg_attr_info.flag & RETRY_SHORT) {
		if (cfg_param_attr->cfg_attr_info.short_retry_limit > 0 &&
		    cfg_param_attr->cfg_attr_info.short_retry_limit < 256) {
588
589
590
591
			wid_list[wid_cnt].id = WID_SHORT_RETRY_LIMIT;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit;
			wid_list[wid_cnt].type = WID_SHORT;
			wid_list[wid_cnt].size = sizeof(u16);
592
			hif_drv->cfg_values.short_retry_limit = cfg_param_attr->cfg_attr_info.short_retry_limit;
593
		} else {
594
			PRINT_ER("Range(1~256) over\n");
595
			result = -EINVAL;
596
			goto ERRORHANDLER;
597
		}
598
		wid_cnt++;
599
	}
600
601
602
	if (cfg_param_attr->cfg_attr_info.flag & RETRY_LONG) {
		if (cfg_param_attr->cfg_attr_info.long_retry_limit > 0 &&
		    cfg_param_attr->cfg_attr_info.long_retry_limit < 256) {
603
604
605
606
			wid_list[wid_cnt].id = WID_LONG_RETRY_LIMIT;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit;
			wid_list[wid_cnt].type = WID_SHORT;
			wid_list[wid_cnt].size = sizeof(u16);
607
			hif_drv->cfg_values.long_retry_limit = cfg_param_attr->cfg_attr_info.long_retry_limit;
608
		} else {
609
			PRINT_ER("Range(1~256) over\n");
610
			result = -EINVAL;
611
			goto ERRORHANDLER;
612
		}
613
		wid_cnt++;
614
	}
615
616
617
	if (cfg_param_attr->cfg_attr_info.flag & FRAG_THRESHOLD) {
		if (cfg_param_attr->cfg_attr_info.frag_threshold > 255 &&
		    cfg_param_attr->cfg_attr_info.frag_threshold < 7937) {
618
619
620
621
			wid_list[wid_cnt].id = WID_FRAG_THRESHOLD;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold;
			wid_list[wid_cnt].type = WID_SHORT;
			wid_list[wid_cnt].size = sizeof(u16);
622
			hif_drv->cfg_values.frag_threshold = cfg_param_attr->cfg_attr_info.frag_threshold;
623
		} else {
624
			PRINT_ER("Threshold Range fail\n");
625
			result = -EINVAL;
626
			goto ERRORHANDLER;
627
		}
628
		wid_cnt++;
629
	}
630
631
632
	if (cfg_param_attr->cfg_attr_info.flag & RTS_THRESHOLD) {
		if (cfg_param_attr->cfg_attr_info.rts_threshold > 255 &&
		    cfg_param_attr->cfg_attr_info.rts_threshold < 65536) {
633
634
635
636
			wid_list[wid_cnt].id = WID_RTS_THRESHOLD;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold;
			wid_list[wid_cnt].type = WID_SHORT;
			wid_list[wid_cnt].size = sizeof(u16);
637
			hif_drv->cfg_values.rts_threshold = cfg_param_attr->cfg_attr_info.rts_threshold;
638
		} else {
639
			PRINT_ER("Threshold Range fail\n");
640
			result = -EINVAL;
641
			goto ERRORHANDLER;
642
		}
643
		wid_cnt++;
644
	}
645
646
	if (cfg_param_attr->cfg_attr_info.flag & PREAMBLE) {
		if (cfg_param_attr->cfg_attr_info.preamble_type < 3) {
647
648
649
650
			wid_list[wid_cnt].id = WID_PREAMBLE;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type;
			wid_list[wid_cnt].type = WID_CHAR;
			wid_list[wid_cnt].size = sizeof(char);
651
			hif_drv->cfg_values.preamble_type = cfg_param_attr->cfg_attr_info.preamble_type;
652
		} else {
653
			PRINT_ER("Preamle Range(0~2) over\n");
654
			result = -EINVAL;
655
			goto ERRORHANDLER;
656
		}
657
		wid_cnt++;
658
	}
659
660
	if (cfg_param_attr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) {
		if (cfg_param_attr->cfg_attr_info.short_slot_allowed < 2) {
661
662
663
664
			wid_list[wid_cnt].id = WID_SHORT_SLOT_ALLOWED;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed;
			wid_list[wid_cnt].type = WID_CHAR;
			wid_list[wid_cnt].size = sizeof(char);
665
			hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->cfg_attr_info.short_slot_allowed;
666
		} else {
667
			PRINT_ER("Short slot(2) over\n");
668
			result = -EINVAL;
669
			goto ERRORHANDLER;
670
		}
671
		wid_cnt++;
672
	}
673
674
	if (cfg_param_attr->cfg_attr_info.flag & TXOP_PROT_DISABLE) {
		if (cfg_param_attr->cfg_attr_info.txop_prot_disabled < 2) {
675
676
677
678
			wid_list[wid_cnt].id = WID_11N_TXOP_PROT_DISABLE;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled;
			wid_list[wid_cnt].type = WID_CHAR;
			wid_list[wid_cnt].size = sizeof(char);
679
			hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->cfg_attr_info.txop_prot_disabled;
680
		} else {
681
			PRINT_ER("TXOP prot disable\n");
682
			result = -EINVAL;
683
			goto ERRORHANDLER;
684
		}
685
		wid_cnt++;
686
	}
687
688
689
	if (cfg_param_attr->cfg_attr_info.flag & BEACON_INTERVAL) {
		if (cfg_param_attr->cfg_attr_info.beacon_interval > 0 &&
		    cfg_param_attr->cfg_attr_info.beacon_interval < 65536) {
690
691
692
693
			wid_list[wid_cnt].id = WID_BEACON_INTERVAL;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval;
			wid_list[wid_cnt].type = WID_SHORT;
			wid_list[wid_cnt].size = sizeof(u16);
694
			hif_drv->cfg_values.beacon_interval = cfg_param_attr->cfg_attr_info.beacon_interval;
695
		} else {
696
			PRINT_ER("Beacon interval(1~65535) fail\n");
697
			result = -EINVAL;
698
			goto ERRORHANDLER;
699
		}
700
		wid_cnt++;
701
	}
702
703
704
	if (cfg_param_attr->cfg_attr_info.flag & DTIM_PERIOD) {
		if (cfg_param_attr->cfg_attr_info.dtim_period > 0 &&
		    cfg_param_attr->cfg_attr_info.dtim_period < 256) {
705
706
707
708
			wid_list[wid_cnt].id = WID_DTIM_PERIOD;
			wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period;
			wid_list[wid_cnt].type = WID_CHAR;
			wid_list[wid_cnt].size = sizeof(char);
709
			hif_drv->cfg_values.dtim_period = cfg_param_attr->cfg_attr_info.dtim_period;
710
		} else {
711
			PRINT_ER("DTIM range(1~255) fail\n");
712
			result = -EINVAL;
713
			goto ERRORHANDLER;
714
		}