]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/staging/wilc1000/host_interface.c
staging: wilc1000: rename u32Address of struct drv_handler
[mirror_ubuntu-hirsute-kernel.git] / drivers / staging / wilc1000 / host_interface.c
CommitLineData
e215a871
CL
1#include <linux/slab.h>
2#include <linux/time.h>
3#include <linux/kthread.h>
4#include <linux/delay.h>
c5c77ba1 5#include "host_interface.h"
c5c77ba1 6#include "coreconfigurator.h"
5366012d 7#include "wilc_wlan_if.h"
f23eb98b 8#include "wilc_msgqueue.h"
281dd5ac 9#include <linux/etherdevice.h>
d5382219 10#include "wilc_wfi_netdevice.h"
c5c77ba1 11
63d03e47 12extern u8 connecting;
c5c77ba1 13
da711eb6 14extern struct timer_list hDuringIpTimer;
c5c77ba1 15
63d03e47 16extern u8 g_wilc_initialized;
c5c77ba1 17
9eac3a15
CL
18#define HOST_IF_MSG_SCAN 0
19#define HOST_IF_MSG_CONNECT 1
20#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
21#define HOST_IF_MSG_KEY 3
22#define HOST_IF_MSG_RCVD_NTWRK_INFO 4
23#define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
24#define HOST_IF_MSG_CFG_PARAMS 6
25#define HOST_IF_MSG_SET_CHANNEL 7
26#define HOST_IF_MSG_DISCONNECT 8
27#define HOST_IF_MSG_GET_RSSI 9
28#define HOST_IF_MSG_GET_CHNL 10
29#define HOST_IF_MSG_ADD_BEACON 11
30#define HOST_IF_MSG_DEL_BEACON 12
31#define HOST_IF_MSG_ADD_STATION 13
32#define HOST_IF_MSG_DEL_STATION 14
33#define HOST_IF_MSG_EDIT_STATION 15
34#define HOST_IF_MSG_SCAN_TIMER_FIRED 16
35#define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
36#define HOST_IF_MSG_POWER_MGMT 18
37#define HOST_IF_MSG_GET_INACTIVETIME 19
38#define HOST_IF_MSG_REMAIN_ON_CHAN 20
39#define HOST_IF_MSG_REGISTER_FRAME 21
40#define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
41#define HOST_IF_MSG_GET_LINKSPEED 23
42#define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
43#define HOST_IF_MSG_SET_MAC_ADDRESS 25
44#define HOST_IF_MSG_GET_MAC_ADDRESS 26
45#define HOST_IF_MSG_SET_OPERATION_MODE 27
46#define HOST_IF_MSG_SET_IPADDRESS 28
47#define HOST_IF_MSG_GET_IPADDRESS 29
48#define HOST_IF_MSG_FLUSH_CONNECT 30
49#define HOST_IF_MSG_GET_STATISTICS 31
50#define HOST_IF_MSG_SET_MULTICAST_FILTER 32
51#define HOST_IF_MSG_ADD_BA_SESSION 33
52#define HOST_IF_MSG_DEL_BA_SESSION 34
53#define HOST_IF_MSG_Q_IDLE 35
54#define HOST_IF_MSG_DEL_ALL_STA 36
55#define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS 34
56#define HOST_IF_MSG_EXIT 100
d85f5326 57
e54d5b75
CL
58#define HOST_IF_SCAN_TIMEOUT 4000
59#define HOST_IF_CONNECT_TIMEOUT 9500
c5c77ba1 60
e54d5b75
CL
61#define BA_SESSION_DEFAULT_BUFFER_SIZE 16
62#define BA_SESSION_DEFAULT_TIMEOUT 1000
63#define BLOCK_ACK_REQ_SIZE 0x14
9f3295a2 64#define FALSE_FRMWR_CHANNEL 100
c5c77ba1 65
361ff841 66struct cfg_param_attr {
221371e5 67 struct cfg_param_val cfg_attr_info;
361ff841 68};
c5c77ba1 69
4372d3d3 70struct host_if_wpa_attr {
124968fc 71 u8 *key;
248080aa 72 const u8 *mac_addr;
0e74c009 73 u8 *seq;
dacc594d 74 u8 seq_len;
e2dfbac5 75 u8 index;
6acf2919 76 u8 key_len;
7b2ebb28 77 u8 mode;
4372d3d3 78};
c5c77ba1 79
c276c44a 80struct host_if_wep_attr {
e5538d34 81 u8 *key;
d520e355 82 u8 key_len;
259b3aa6 83 u8 index;
b5eaff12 84 u8 mode;
7fa252e7 85 enum AUTHTYPE auth_type;
c276c44a 86};
c5c77ba1 87
40cc2c90 88union host_if_key_attr {
2ed7a2fb 89 struct host_if_wep_attr wep;
e3501a4d 90 struct host_if_wpa_attr wpa;
610e3868 91 struct host_if_pmkid_attr pmkid;
40cc2c90 92};
c5c77ba1 93
c98387a5 94struct key_attr {
8e9f427a 95 enum KEY_TYPE type;
0d17e382 96 u8 action;
73b2e381 97 union host_if_key_attr attr;
c98387a5 98};
c5c77ba1 99
c476feb8 100struct scan_attr {
42568898 101 u8 src;
1e276c88 102 u8 type;
82eeb0ad 103 u8 *ch_freq_list;
f97bd9ca 104 u8 ch_list_len;
d6f19aa5 105 u8 *ies;
7b1f76cd 106 size_t ies_len;
c17c6da6 107 wilc_scan_result result;
5f2b50c8 108 void *arg;
629b9ca0 109 struct hidden_network hidden_network;
c476feb8 110};
c5c77ba1 111
120ae593 112struct connect_attr {
9254db07 113 u8 *bssid;
f7bbd9cf 114 u8 *ssid;
8b3c9fa6 115 size_t ssid_len;
2ea158c4 116 u8 *ies;
b59d5c5b 117 size_t ies_len;
a64fd677 118 u8 security;
6abcc11d 119 wilc_connect_result result;
8f38db89 120 void *arg;
61b4fd02 121 enum AUTHTYPE auth_type;
0d1527e6 122 u8 ch;
f2bed2ca 123 void *params;
120ae593 124};
c5c77ba1 125
f23a9eab 126struct rcvd_async_info {
33722ac7 127 u8 *buffer;
f94f4889 128 u32 len;
f23a9eab 129};
c5c77ba1 130
94bdfe42 131struct channel_attr {
730ee059 132 u8 set_ch;
326b323d 133};
c5c77ba1 134
7f33fecd 135struct beacon_attr {
12262dda 136 u32 interval;
e76ab770 137 u32 dtim_period;
51c66185 138 u32 head_len;
8ce528b9 139 u8 *head;
030c57e2 140 u32 tail_len;
7dbcb6d3 141 u8 *tail;
902362b1 142};
c5c77ba1 143
641210ac 144struct set_multicast {
bae636eb 145 bool enabled;
adab2f71 146 u32 cnt;
641210ac 147};
c5c77ba1 148
b4e644e4 149struct del_all_sta {
e51b9216 150 u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
8ba1803f 151 u8 assoc_sta;
b4e644e4 152};
c5c77ba1 153
fb93a1e1 154struct del_sta {
e4839d39 155 u8 mac_addr[ETH_ALEN];
fb93a1e1 156};
c5c77ba1 157
5a008f1c 158struct power_mgmt_param {
33c70c1b 159 bool enabled;
937918ff 160 u32 timeout;
5a008f1c 161};
c5c77ba1 162
15191eaf 163struct set_ip_addr {
78675be5 164 u8 *ip_addr;
63d03e47 165 u8 idx;
15191eaf 166};
c5c77ba1 167
3d1eac04 168struct sta_inactive_t {
63d03e47 169 u8 mac[6];
3d1eac04 170};
ae4dfa57 171
dfc7663b 172union message_body {
4528bdb5 173 struct scan_attr scan_info;
3f501971 174 struct connect_attr con_info;
02d19460 175 struct rcvd_net_info net_info;
66add622 176 struct rcvd_async_info async_info;
18990bfe 177 struct key_attr key_info;
a2340c36 178 struct cfg_param_attr cfg_info;
ffd6dbc8 179 struct channel_attr channel_info;
a98491e5 180 struct beacon_attr beacon_info;
ca8f47f8 181 struct add_sta_param add_sta_info;
889c25be 182 struct del_sta del_sta_info;
4a930962 183 struct add_sta_param edit_sta_info;
49e1f81b 184 struct power_mgmt_param pwr_mgmt_info;
66bac7f2 185 struct sta_inactive_t mac_info;
fb2d65ed 186 struct set_ip_addr ip_info;
5e4377e6 187 struct drv_handler drv;
a079cf4d 188 struct set_multicast multicast_info;
00c4630e 189 struct op_mode mode;
15326e28 190 struct set_mac_addr set_mac_info;
a5848695 191 struct get_mac_addr get_mac_info;
c833b474 192 struct ba_session_info session_info;
070d365c 193 struct remain_ch remain_on_ch;
5c4008db 194 struct reg_frame reg_frame;
e60831e9 195 char *data;
b0c1e80e 196 struct del_all_sta del_all_sta_info;
dfc7663b 197};
c5c77ba1 198
3a8c41b5 199struct host_if_msg {
ae4dfa57
LK
200 u16 id;
201 union message_body body;
2482a79f 202 struct host_if_drv *drv;
3a8c41b5 203};
c5c77ba1 204
e0a12217 205struct join_bss_param {
c5c77ba1 206 BSSTYPE_T bss_type;
63d03e47 207 u8 dtim_period;
d85f5326
CL
208 u16 beacon_period;
209 u16 cap_info;
63d03e47 210 u8 au8bssid[6];
576917ad 211 char ssid[MAX_SSID_LEN];
619d27b8 212 u8 ssid_len;
63d03e47
GKH
213 u8 supp_rates[MAX_RATES_SUPPORTED + 1];
214 u8 ht_capable;
215 u8 wmm_cap;
216 u8 uapsd_cap;
72ed4dc7 217 bool rsn_found;
63d03e47
GKH
218 u8 rsn_grp_policy;
219 u8 mode_802_11i;
220 u8 rsn_pcip_policy[3];
221 u8 rsn_auth_policy[3];
222 u8 rsn_cap[2];
4e4467fd 223 u32 tsf;
7a8d51d7 224 u8 noa_enabled;
d72b33ca 225 u8 opp_enabled;
99b66945 226 u8 ct_window;
c21047ed 227 u8 cnt;
cc179008 228 u8 idx;
109e6cab 229 u8 duration[4];
1d8b76b3 230 u8 interval[4];
4be55e22 231 u8 start_time[4];
e0a12217 232};
c5c77ba1 233
441dc609
LK
234static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1];
235struct host_if_drv *terminated_handle;
f2fc9f6e 236bool g_obtainingIP;
63d03e47 237u8 P2P_LISTEN_STATE;
c2115d8e 238static struct task_struct *hif_thread_handler;
cb067dcf 239static WILC_MsgQueueHandle hif_msg_q;
834e0cb0 240static struct semaphore hif_sema_thread;
413f930e 241static struct semaphore hif_sema_driver;
2d25af87 242static struct semaphore hif_sema_wait_response;
17225002 243static struct semaphore hif_sema_deinit;
24aadb8b 244static struct timer_list periodic_rssi;
c5c77ba1 245
63d03e47 246u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
c5c77ba1 247
a633c0b5 248static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
c5c77ba1 249
f64321c6 250static bool scan_while_connected;
c5c77ba1 251
144b7b23 252static s8 rssi;
75327a02 253static s8 link_speed;
95ebb0ff 254static u8 ch_no;
078b1e98 255static u8 set_ip[2][4];
1e75d01c 256static u8 get_ip[2][4];
ad26906f 257static u32 inactive_time;
a74c7bf8 258static u8 del_beacon;
7178aed8 259static u32 clients_count;
c5c77ba1 260
ef599194 261static u8 *join_req;
48ce2465 262u8 *info_element;
23047d5b 263static u8 mode_11i;
fba4989e 264u8 auth_type;
0626baaa 265u32 join_req_size;
5e0e7c2e 266static u32 info_element_size;
23fba59d 267static struct host_if_drv *join_req_drv;
c5c77ba1
JK
268#define REAL_JOIN_REQ 0
269#define FLUSHED_JOIN_REQ 1
ae4dfa57 270#define FLUSHED_BYTE_POS 79
c5c77ba1 271
c5c77ba1 272static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo);
c5c77ba1 273
4e4467fd 274extern void chip_sleep_manually(u32 u32SleepTime);
c5c77ba1
JK
275extern int linux_wlan_get_num_conn_ifcs(void);
276
441dc609 277static int add_handler_in_list(struct host_if_drv *handler)
d42ab083
JK
278{
279 int i;
280
281 for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
282 if (!wfidrv_list[i]) {
283 wfidrv_list[i] = handler;
284 return 0;
285 }
286 }
287
288 return -ENOBUFS;
289}
290
441dc609 291static int remove_handler_in_list(struct host_if_drv *handler)
d42ab083
JK
292{
293 int i;
294
295 for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
296 if (wfidrv_list[i] == handler) {
297 wfidrv_list[i] = NULL;
298 return 0;
299 }
300 }
301
302 return -EINVAL;
303}
304
441dc609 305static int get_id_from_handler(struct host_if_drv *handler)
d42ab083
JK
306{
307 int i;
308
309 if (!handler)
310 return 0;
311
312 for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
313 if (wfidrv_list[i] == handler)
314 return i;
315 }
316
317 return 0;
318}
319
441dc609 320static struct host_if_drv *get_handler_from_id(int id)
d42ab083 321{
6ae9ac0b 322 if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list))
d42ab083
JK
323 return NULL;
324 return wfidrv_list[id];
325}
326
a4ab1ade 327static s32 Handle_SetChannel(struct host_if_drv *hif_drv,
94bdfe42 328 struct channel_attr *pstrHostIFSetChan)
c5c77ba1 329{
31390eec 330 s32 result = 0;
45102f83 331 struct wid wid;
c5c77ba1 332
45102f83
LK
333 wid.id = (u16)WID_CURRENT_CHANNEL;
334 wid.type = WID_CHAR;
335 wid.val = (char *)&pstrHostIFSetChan->set_ch;
336 wid.size = sizeof(char);
c5c77ba1
JK
337
338 PRINT_D(HOSTINF_DBG, "Setting channel\n");
ae4dfa57 339
45102f83 340 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 341 get_id_from_handler(hif_drv));
31390eec
LK
342
343 if (result) {
c5c77ba1 344 PRINT_ER("Failed to set channel\n");
24db713f 345 return -EINVAL;
c5c77ba1
JK
346 }
347
31390eec 348 return result;
c5c77ba1 349}
ae4dfa57 350
a4ab1ade 351static s32 Handle_SetWfiDrvHandler(struct host_if_drv *hif_drv,
127f9d94 352 struct drv_handler *pstrHostIfSetDrvHandler)
c5c77ba1 353{
31390eec 354 s32 result = 0;
45102f83 355 struct wid wid;
c5c77ba1 356
45102f83
LK
357 wid.id = (u16)WID_SET_DRV_HANDLER;
358 wid.type = WID_INT;
a7f3b12f 359 wid.val = (s8 *)&pstrHostIfSetDrvHandler->handler;
45102f83 360 wid.size = sizeof(u32);
c5c77ba1 361
45102f83 362 result = send_config_pkt(SET_CFG, &wid, 1,
a7f3b12f 363 pstrHostIfSetDrvHandler->handler);
c5c77ba1 364
a4ab1ade 365 if (!hif_drv)
27ff2168 366 up(&hif_sema_driver);
c5c77ba1 367
31390eec 368 if (result) {
c5c77ba1 369 PRINT_ER("Failed to set driver handler\n");
24db713f 370 return -EINVAL;
c5c77ba1
JK
371 }
372
31390eec 373 return result;
c5c77ba1
JK
374}
375
a4ab1ade 376static s32 Handle_SetOperationMode(struct host_if_drv *hif_drv,
801bee52 377 struct op_mode *pstrHostIfSetOperationMode)
c5c77ba1 378{
31390eec 379 s32 result = 0;
45102f83 380 struct wid wid;
c5c77ba1 381
45102f83
LK
382 wid.id = (u16)WID_SET_OPERATION_MODE;
383 wid.type = WID_INT;
384 wid.val = (s8 *)&pstrHostIfSetOperationMode->u32Mode;
385 wid.size = sizeof(u32);
c5c77ba1 386
45102f83 387 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 388 get_id_from_handler(hif_drv));
c5c77ba1 389
c590b9a4 390 if ((pstrHostIfSetOperationMode->u32Mode) == IDLE_MODE)
27ff2168 391 up(&hif_sema_driver);
c5c77ba1 392
31390eec 393 if (result) {
c5c77ba1 394 PRINT_ER("Failed to set driver handler\n");
24db713f 395 return -EINVAL;
c5c77ba1
JK
396 }
397
31390eec 398 return result;
c5c77ba1
JK
399}
400
a4ab1ade 401s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx)
c5c77ba1 402{
31390eec 403 s32 result = 0;
45102f83 404 struct wid wid;
c5c77ba1 405 char firmwareIPAddress[4] = {0};
c5c77ba1
JK
406
407 if (pu8IPAddr[0] < 192)
408 pu8IPAddr[0] = 0;
409
b3a02832 410 PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %pI4\n", idx, pu8IPAddr);
c5c77ba1 411
078b1e98 412 memcpy(set_ip[idx], pu8IPAddr, IP_ALEN);
c5c77ba1 413
45102f83
LK
414 wid.id = (u16)WID_IP_ADDRESS;
415 wid.type = WID_STR;
416 wid.val = (u8 *)pu8IPAddr;
417 wid.size = IP_ALEN;
c5c77ba1 418
45102f83 419 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 420 get_id_from_handler(hif_drv));
c5c77ba1 421
a4ab1ade 422 host_int_get_ipaddress(hif_drv, firmwareIPAddress, idx);
c5c77ba1 423
31390eec 424 if (result) {
24db713f
LK
425 PRINT_ER("Failed to set IP address\n");
426 return -EINVAL;
c5c77ba1
JK
427 }
428
24db713f 429 PRINT_INFO(HOSTINF_DBG, "IP address set\n");
c5c77ba1 430
31390eec 431 return result;
c5c77ba1
JK
432}
433
a4ab1ade 434s32 Handle_get_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx)
c5c77ba1 435{
31390eec 436 s32 result = 0;
45102f83 437 struct wid wid;
c5c77ba1 438
45102f83
LK
439 wid.id = (u16)WID_IP_ADDRESS;
440 wid.type = WID_STR;
441 wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
442 wid.size = IP_ALEN;
c5c77ba1 443
45102f83 444 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 445 get_id_from_handler(hif_drv));
c5c77ba1 446
45102f83 447 PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val);
c5c77ba1 448
45102f83 449 memcpy(get_ip[idx], wid.val, IP_ALEN);
c5c77ba1 450
45102f83 451 kfree(wid.val);
c5c77ba1 452
1e75d01c 453 if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
078b1e98 454 host_int_setup_ipaddress(hif_drv, set_ip[idx], idx);
c5c77ba1 455
31390eec 456 if (result != 0) {
c5c77ba1 457 PRINT_ER("Failed to get IP address\n");
24db713f 458 return -EINVAL;
c5c77ba1
JK
459 }
460
24db713f 461 PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d\n", idx);
1e75d01c 462 PRINT_INFO(HOSTINF_DBG, "%pI4\n", get_ip[idx]);
24db713f 463 PRINT_INFO(HOSTINF_DBG, "\n");
c5c77ba1 464
31390eec 465 return result;
c5c77ba1
JK
466}
467
a4ab1ade 468static s32 Handle_SetMacAddress(struct host_if_drv *hif_drv,
b7611a87 469 struct set_mac_addr *pstrHostIfSetMacAddress)
c5c77ba1 470{
31390eec 471 s32 result = 0;
45102f83 472 struct wid wid;
f3052587 473 u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL);
c09389ac 474
91109e11 475 if (!mac_buf) {
c5c77ba1 476 PRINT_ER("No buffer to send mac address\n");
e6e12661 477 return -EFAULT;
c5c77ba1 478 }
d00d2ba3 479 memcpy(mac_buf, pstrHostIfSetMacAddress->u8MacAddress, ETH_ALEN);
c5c77ba1 480
45102f83
LK
481 wid.id = (u16)WID_MAC_ADDR;
482 wid.type = WID_STR;
483 wid.val = mac_buf;
484 wid.size = ETH_ALEN;
485 PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val);
ae4dfa57 486
45102f83 487 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 488 get_id_from_handler(hif_drv));
31390eec 489 if (result) {
c5c77ba1 490 PRINT_ER("Failed to set mac address\n");
31390eec 491 result = -EFAULT;
c5c77ba1
JK
492 }
493
49188af2 494 kfree(mac_buf);
31390eec 495 return result;
c5c77ba1
JK
496}
497
a4ab1ade 498static s32 Handle_GetMacAddress(struct host_if_drv *hif_drv,
fcd27c5f 499 struct get_mac_addr *pstrHostIfGetMacAddress)
c5c77ba1 500{
31390eec 501 s32 result = 0;
45102f83 502 struct wid wid;
c5c77ba1 503
45102f83
LK
504 wid.id = (u16)WID_MAC_ADDR;
505 wid.type = WID_STR;
506 wid.val = pstrHostIfGetMacAddress->u8MacAddress;
507 wid.size = ETH_ALEN;
c5c77ba1 508
45102f83 509 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 510 get_id_from_handler(hif_drv));
31390eec
LK
511
512 if (result) {
c5c77ba1 513 PRINT_ER("Failed to get mac address\n");
31390eec 514 result = -EFAULT;
c5c77ba1 515 }
2d25af87 516 up(&hif_sema_wait_response);
c5c77ba1 517
31390eec 518 return result;
c5c77ba1
JK
519}
520
a4ab1ade 521static s32 Handle_CfgParam(struct host_if_drv *hif_drv,
361ff841 522 struct cfg_param_attr *strHostIFCfgParamAttr)
c5c77ba1 523{
31390eec 524 s32 result = 0;
e9e0c260 525 struct wid strWIDList[32];
63d03e47 526 u8 u8WidCnt = 0;
c5c77ba1 527
a4ab1ade 528 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 529
c5c77ba1
JK
530 PRINT_D(HOSTINF_DBG, "Setting CFG params\n");
531
87c05b28 532 if (strHostIFCfgParamAttr->cfg_attr_info.flag & BSS_TYPE) {
221371e5 533 if (strHostIFCfgParamAttr->cfg_attr_info.bss_type < 6) {
daaf16ba 534 strWIDList[u8WidCnt].id = WID_BSS_TYPE;
221371e5 535 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.bss_type;
416d8321 536 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 537 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 538 hif_drv->strCfgValues.bss_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.bss_type;
c5c77ba1 539 } else {
24db713f 540 PRINT_ER("check value 6 over\n");
31390eec 541 result = -EINVAL;
24db713f 542 goto ERRORHANDLER;
c5c77ba1
JK
543 }
544 u8WidCnt++;
545 }
87c05b28 546 if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTH_TYPE) {
221371e5 547 if ((strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 1 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 2 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 5) {
daaf16ba 548 strWIDList[u8WidCnt].id = WID_AUTH_TYPE;
221371e5 549 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_type;
416d8321 550 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 551 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 552 hif_drv->strCfgValues.auth_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.auth_type;
c5c77ba1 553 } else {
24db713f 554 PRINT_ER("Impossible value \n");
31390eec 555 result = -EINVAL;
24db713f 556 goto ERRORHANDLER;
c5c77ba1
JK
557 }
558 u8WidCnt++;
559 }
87c05b28 560 if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTHEN_TIMEOUT) {
221371e5 561 if (strHostIFCfgParamAttr->cfg_attr_info.auth_timeout > 0 && strHostIFCfgParamAttr->cfg_attr_info.auth_timeout < 65536) {
daaf16ba 562 strWIDList[u8WidCnt].id = WID_AUTH_TIMEOUT;
221371e5 563 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_timeout;
416d8321 564 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 565 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 566 hif_drv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->cfg_attr_info.auth_timeout;
c5c77ba1 567 } else {
24db713f 568 PRINT_ER("Range(1 ~ 65535) over\n");
31390eec 569 result = -EINVAL;
24db713f 570 goto ERRORHANDLER;
c5c77ba1
JK
571 }
572 u8WidCnt++;
573 }
87c05b28 574 if (strHostIFCfgParamAttr->cfg_attr_info.flag & POWER_MANAGEMENT) {
221371e5 575 if (strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode < 5) {
daaf16ba 576 strWIDList[u8WidCnt].id = WID_POWER_MANAGEMENT;
221371e5 577 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode;
416d8321 578 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 579 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 580 hif_drv->strCfgValues.power_mgmt_mode = (u8)strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode;
c5c77ba1 581 } else {
24db713f 582 PRINT_ER("Invalide power mode\n");
31390eec 583 result = -EINVAL;
24db713f 584 goto ERRORHANDLER;
c5c77ba1
JK
585 }
586 u8WidCnt++;
587 }
87c05b28 588 if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_SHORT) {
221371e5 589 if ((strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit < 256)) {
daaf16ba 590 strWIDList[u8WidCnt].id = WID_SHORT_RETRY_LIMIT;
221371e5 591 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit;
416d8321 592 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 593 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 594 hif_drv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit;
c5c77ba1 595 } else {
24db713f 596 PRINT_ER("Range(1~256) over\n");
31390eec 597 result = -EINVAL;
24db713f 598 goto ERRORHANDLER;
c5c77ba1
JK
599 }
600 u8WidCnt++;
601 }
87c05b28 602 if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_LONG) {
221371e5 603 if ((strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit < 256)) {
daaf16ba 604 strWIDList[u8WidCnt].id = WID_LONG_RETRY_LIMIT;
221371e5 605 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit;
c5c77ba1 606
416d8321 607 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 608 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 609 hif_drv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit;
c5c77ba1 610 } else {
24db713f 611 PRINT_ER("Range(1~256) over\n");
31390eec 612 result = -EINVAL;
24db713f 613 goto ERRORHANDLER;
c5c77ba1
JK
614 }
615 u8WidCnt++;
616 }
87c05b28 617 if (strHostIFCfgParamAttr->cfg_attr_info.flag & FRAG_THRESHOLD) {
221371e5 618 if (strHostIFCfgParamAttr->cfg_attr_info.frag_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.frag_threshold < 7937) {
daaf16ba 619 strWIDList[u8WidCnt].id = WID_FRAG_THRESHOLD;
221371e5 620 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.frag_threshold;
416d8321 621 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 622 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 623 hif_drv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->cfg_attr_info.frag_threshold;
c5c77ba1 624 } else {
24db713f 625 PRINT_ER("Threshold Range fail\n");
31390eec 626 result = -EINVAL;
24db713f 627 goto ERRORHANDLER;
c5c77ba1
JK
628 }
629 u8WidCnt++;
630 }
87c05b28 631 if (strHostIFCfgParamAttr->cfg_attr_info.flag & RTS_THRESHOLD) {
221371e5 632 if (strHostIFCfgParamAttr->cfg_attr_info.rts_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.rts_threshold < 65536) {
daaf16ba 633 strWIDList[u8WidCnt].id = WID_RTS_THRESHOLD;
221371e5 634 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.rts_threshold;
416d8321 635 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 636 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 637 hif_drv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->cfg_attr_info.rts_threshold;
c5c77ba1 638 } else {
24db713f 639 PRINT_ER("Threshold Range fail\n");
31390eec 640 result = -EINVAL;
24db713f 641 goto ERRORHANDLER;
c5c77ba1
JK
642 }
643 u8WidCnt++;
644 }
87c05b28 645 if (strHostIFCfgParamAttr->cfg_attr_info.flag & PREAMBLE) {
221371e5 646 if (strHostIFCfgParamAttr->cfg_attr_info.preamble_type < 3) {
daaf16ba 647 strWIDList[u8WidCnt].id = WID_PREAMBLE;
221371e5 648 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.preamble_type;
416d8321 649 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 650 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 651 hif_drv->strCfgValues.preamble_type = strHostIFCfgParamAttr->cfg_attr_info.preamble_type;
c5c77ba1 652 } else {
24db713f 653 PRINT_ER("Preamle Range(0~2) over\n");
31390eec 654 result = -EINVAL;
24db713f 655 goto ERRORHANDLER;
c5c77ba1
JK
656 }
657 u8WidCnt++;
658 }
87c05b28 659 if (strHostIFCfgParamAttr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) {
221371e5 660 if (strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed < 2) {
daaf16ba 661 strWIDList[u8WidCnt].id = WID_SHORT_SLOT_ALLOWED;
221371e5 662 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed;
416d8321 663 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 664 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 665 hif_drv->strCfgValues.short_slot_allowed = (u8)strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed;
c5c77ba1 666 } else {
24db713f 667 PRINT_ER("Short slot(2) over\n");
31390eec 668 result = -EINVAL;
24db713f 669 goto ERRORHANDLER;
c5c77ba1
JK
670 }
671 u8WidCnt++;
672 }
87c05b28 673 if (strHostIFCfgParamAttr->cfg_attr_info.flag & TXOP_PROT_DISABLE) {
221371e5 674 if (strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled < 2) {
daaf16ba 675 strWIDList[u8WidCnt].id = WID_11N_TXOP_PROT_DISABLE;
221371e5 676 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled;
416d8321 677 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 678 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 679 hif_drv->strCfgValues.txop_prot_disabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled;
c5c77ba1 680 } else {
24db713f 681 PRINT_ER("TXOP prot disable\n");
31390eec 682 result = -EINVAL;
24db713f 683 goto ERRORHANDLER;
c5c77ba1
JK
684 }
685 u8WidCnt++;
686 }
87c05b28 687 if (strHostIFCfgParamAttr->cfg_attr_info.flag & BEACON_INTERVAL) {
221371e5 688 if (strHostIFCfgParamAttr->cfg_attr_info.beacon_interval > 0 && strHostIFCfgParamAttr->cfg_attr_info.beacon_interval < 65536) {
daaf16ba 689 strWIDList[u8WidCnt].id = WID_BEACON_INTERVAL;
221371e5 690 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.beacon_interval;
416d8321 691 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 692 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 693 hif_drv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->cfg_attr_info.beacon_interval;
c5c77ba1 694 } else {
24db713f 695 PRINT_ER("Beacon interval(1~65535) fail\n");
31390eec 696 result = -EINVAL;
24db713f 697 goto ERRORHANDLER;
c5c77ba1
JK
698 }
699 u8WidCnt++;
700 }
87c05b28 701 if (strHostIFCfgParamAttr->cfg_attr_info.flag & DTIM_PERIOD) {
221371e5 702 if (strHostIFCfgParamAttr->cfg_attr_info.dtim_period > 0 && strHostIFCfgParamAttr->cfg_attr_info.dtim_period < 256) {
daaf16ba 703 strWIDList[u8WidCnt].id = WID_DTIM_PERIOD;
221371e5 704 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.dtim_period;
416d8321 705 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 706 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 707 hif_drv->strCfgValues.dtim_period = strHostIFCfgParamAttr->cfg_attr_info.dtim_period;
c5c77ba1 708 } else {
24db713f 709 PRINT_ER("DTIM range(1~255) fail\n");
31390eec 710 result = -EINVAL;
24db713f 711 goto ERRORHANDLER;
c5c77ba1
JK
712 }
713 u8WidCnt++;
714 }
87c05b28 715 if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY) {
221371e5 716 if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled < 3) {
daaf16ba 717 strWIDList[u8WidCnt].id = WID_SITE_SURVEY;
221371e5 718 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled;
416d8321 719 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 720 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 721 hif_drv->strCfgValues.site_survey_enabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled;
c5c77ba1 722 } else {
24db713f 723 PRINT_ER("Site survey disable\n");
31390eec 724 result = -EINVAL;
24db713f 725 goto ERRORHANDLER;
c5c77ba1
JK
726 }
727 u8WidCnt++;
728 }
87c05b28 729 if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) {
221371e5 730 if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time < 65536) {
daaf16ba 731 strWIDList[u8WidCnt].id = WID_SITE_SURVEY_SCAN_TIME;
221371e5 732 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time;
416d8321 733 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 734 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 735 hif_drv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time;
c5c77ba1 736 } else {
24db713f 737 PRINT_ER("Site survey scan time(1~65535) over\n");
31390eec 738 result = -EINVAL;
24db713f 739 goto ERRORHANDLER;
c5c77ba1
JK
740 }
741 u8WidCnt++;
742 }
87c05b28 743 if (strHostIFCfgParamAttr->cfg_attr_info.flag & ACTIVE_SCANTIME) {
221371e5 744 if (strHostIFCfgParamAttr->cfg_attr_info.active_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.active_scan_time < 65536) {
daaf16ba 745 strWIDList[u8WidCnt].id = WID_ACTIVE_SCAN_TIME;
221371e5 746 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.active_scan_time;
416d8321 747 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 748 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 749 hif_drv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->cfg_attr_info.active_scan_time;
c5c77ba1 750 } else {
24db713f 751 PRINT_ER("Active scan time(1~65535) over\n");
31390eec 752 result = -EINVAL;
24db713f 753 goto ERRORHANDLER;
c5c77ba1
JK
754 }
755 u8WidCnt++;
756 }
87c05b28 757 if (strHostIFCfgParamAttr->cfg_attr_info.flag & PASSIVE_SCANTIME) {
221371e5 758 if (strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time < 65536) {
daaf16ba 759 strWIDList[u8WidCnt].id = WID_PASSIVE_SCAN_TIME;
221371e5 760 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time;
416d8321 761 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 762 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 763 hif_drv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time;
c5c77ba1 764 } else {
24db713f 765 PRINT_ER("Passive scan time(1~65535) over\n");
31390eec 766 result = -EINVAL;
24db713f 767 goto ERRORHANDLER;
c5c77ba1
JK
768 }
769 u8WidCnt++;
770 }
87c05b28 771 if (strHostIFCfgParamAttr->cfg_attr_info.flag & CURRENT_TX_RATE) {
221371e5 772 enum CURRENT_TXRATE curr_tx_rate = strHostIFCfgParamAttr->cfg_attr_info.curr_tx_rate;
c09389ac 773
c5c77ba1
JK
774 if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1
775 || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5
776 || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6
777 || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12
778 || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24
779 || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) {
daaf16ba 780 strWIDList[u8WidCnt].id = WID_CURRENT_TX_RATE;
900bb4a6 781 strWIDList[u8WidCnt].val = (s8 *)&curr_tx_rate;
416d8321 782 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 783 strWIDList[u8WidCnt].size = sizeof(u16);
a4ab1ade 784 hif_drv->strCfgValues.curr_tx_rate = (u8)curr_tx_rate;
c5c77ba1 785 } else {
24db713f 786 PRINT_ER("out of TX rate\n");
31390eec 787 result = -EINVAL;
24db713f 788 goto ERRORHANDLER;
c5c77ba1
JK
789 }
790 u8WidCnt++;
791 }
31390eec
LK
792
793 result = send_config_pkt(SET_CFG, strWIDList, u8WidCnt,
8c8360b3 794 get_id_from_handler(hif_drv));
c5c77ba1 795
31390eec 796 if (result)
c5c77ba1
JK
797 PRINT_ER("Error in setting CFG params\n");
798
24db713f 799ERRORHANDLER:
a4ab1ade 800 up(&hif_drv->gtOsCfgValuesSem);
31390eec 801 return result;
c5c77ba1
JK
802}
803
fb4ec9ca 804static s32 Handle_wait_msg_q_empty(void)
c5c77ba1 805{
c5c77ba1 806 g_wilc_initialized = 0;
2d25af87 807 up(&hif_sema_wait_response);
b68d820b 808 return 0;
c5c77ba1
JK
809}
810
a4ab1ade 811static s32 Handle_Scan(struct host_if_drv *hif_drv,
c476feb8 812 struct scan_attr *pstrHostIFscanAttr)
c5c77ba1 813{
31390eec 814 s32 result = 0;
e9e0c260 815 struct wid strWIDList[5];
4e4467fd
CL
816 u32 u32WidsCount = 0;
817 u32 i;
63d03e47
GKH
818 u8 *pu8Buffer;
819 u8 valuesize = 0;
820 u8 *pu8HdnNtwrksWidVal = NULL;
c5c77ba1
JK
821
822 PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
a4ab1ade 823 PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->enuHostIFstate);
c5c77ba1 824
c17c6da6 825 hif_drv->strWILC_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->result;
5f2b50c8 826 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->arg;
c5c77ba1 827
a4ab1ade 828 if ((hif_drv->enuHostIFstate >= HOST_IF_SCANNING) && (hif_drv->enuHostIFstate < HOST_IF_CONNECTED)) {
a4ab1ade 829 PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", hif_drv->enuHostIFstate);
24db713f 830 PRINT_ER("Already scan\n");
31390eec 831 result = -EBUSY;
24db713f 832 goto ERRORHANDLER;
c5c77ba1
JK
833 }
834
c5c77ba1
JK
835 if (g_obtainingIP || connecting) {
836 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
24db713f 837 PRINT_ER("Don't do obss scan\n");
31390eec 838 result = -EBUSY;
24db713f 839 goto ERRORHANDLER;
c5c77ba1 840 }
c5c77ba1
JK
841
842 PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
843
a4ab1ade 844 hif_drv->strWILC_UsrScanReq.u32RcvdChCount = 0;
c5c77ba1 845
daaf16ba 846 strWIDList[u32WidsCount].id = (u16)WID_SSID_PROBE_REQ;
416d8321 847 strWIDList[u32WidsCount].type = WID_STR;
c5c77ba1 848
629b9ca0
LK
849 for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++)
850 valuesize += ((pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen) + 1);
f3052587 851 pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
900bb4a6 852 strWIDList[u32WidsCount].val = pu8HdnNtwrksWidVal;
91109e11 853 if (strWIDList[u32WidsCount].val) {
900bb4a6 854 pu8Buffer = strWIDList[u32WidsCount].val;
c5c77ba1 855
629b9ca0 856 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.u8ssidnum;
c5c77ba1 857
629b9ca0 858 PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->hidden_network.u8ssidnum);
c5c77ba1 859
629b9ca0
LK
860 for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++) {
861 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen;
862 memcpy(pu8Buffer, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen);
863 pu8Buffer += pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen;
c5c77ba1
JK
864 }
865
2fd3e443 866 strWIDList[u32WidsCount].size = (s32)(valuesize + 1);
c5c77ba1
JK
867 u32WidsCount++;
868 }
869
c5c77ba1 870 {
daaf16ba 871 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_PROBE;
416d8321 872 strWIDList[u32WidsCount].type = WID_BIN_DATA;
d6f19aa5 873 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ies;
7b1f76cd 874 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ies_len;
c5c77ba1
JK
875 u32WidsCount++;
876 }
877
daaf16ba 878 strWIDList[u32WidsCount].id = WID_SCAN_TYPE;
416d8321 879 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 880 strWIDList[u32WidsCount].size = sizeof(char);
bafaa696 881 strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->type;
c5c77ba1
JK
882 u32WidsCount++;
883
daaf16ba 884 strWIDList[u32WidsCount].id = WID_SCAN_CHANNEL_LIST;
416d8321 885 strWIDList[u32WidsCount].type = WID_BIN_DATA;
c5c77ba1 886
91109e11
LK
887 if (pstrHostIFscanAttr->ch_freq_list &&
888 pstrHostIFscanAttr->ch_list_len > 0) {
c5c77ba1
JK
889 int i;
890
f97bd9ca 891 for (i = 0; i < pstrHostIFscanAttr->ch_list_len; i++) {
82eeb0ad
LK
892 if (pstrHostIFscanAttr->ch_freq_list[i] > 0)
893 pstrHostIFscanAttr->ch_freq_list[i] = pstrHostIFscanAttr->ch_freq_list[i] - 1;
c5c77ba1
JK
894 }
895 }
896
82eeb0ad 897 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ch_freq_list;
f97bd9ca 898 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ch_list_len;
c5c77ba1
JK
899 u32WidsCount++;
900
daaf16ba 901 strWIDList[u32WidsCount].id = WID_START_SCAN_REQ;
416d8321 902 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 903 strWIDList[u32WidsCount].size = sizeof(char);
bafaa696 904 strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->src;
c5c77ba1
JK
905 u32WidsCount++;
906
a4ab1ade 907 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
ca8540e4 908 scan_while_connected = true;
a4ab1ade 909 else if (hif_drv->enuHostIFstate == HOST_IF_IDLE)
ca8540e4 910 scan_while_connected = false;
c5c77ba1 911
31390eec 912 result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
8c8360b3 913 get_id_from_handler(hif_drv));
c5c77ba1 914
31390eec 915 if (result)
c5c77ba1 916 PRINT_ER("Failed to send scan paramters config packet\n");
24db713f 917 else
c5c77ba1 918 PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n");
c5c77ba1 919
24db713f 920ERRORHANDLER:
31390eec 921 if (result) {
a4ab1ade 922 del_timer(&hif_drv->hScanTimer);
a4ab1ade 923 Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
c5c77ba1
JK
924 }
925
95f840fb
SB
926 kfree(pstrHostIFscanAttr->ch_freq_list);
927 pstrHostIFscanAttr->ch_freq_list = NULL;
c5c77ba1 928
95f840fb
SB
929 kfree(pstrHostIFscanAttr->ies);
930 pstrHostIFscanAttr->ies = NULL;
931 kfree(pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo);
932 pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo = NULL;
c5c77ba1 933
95f840fb 934 kfree(pu8HdnNtwrksWidVal);
c5c77ba1 935
31390eec 936 return result;
c5c77ba1
JK
937}
938
a4ab1ade
TC
939static s32 Handle_ScanDone(struct host_if_drv *hif_drv,
940 enum scan_event enuEvent)
c5c77ba1 941{
31390eec 942 s32 result = 0;
63d03e47 943 u8 u8abort_running_scan;
45102f83 944 struct wid wid;
c5c77ba1 945
c5c77ba1
JK
946 PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n");
947
c5c77ba1
JK
948 if (enuEvent == SCAN_EVENT_ABORTED) {
949 PRINT_D(GENERIC_DBG, "Abort running scan\n");
950 u8abort_running_scan = 1;
45102f83
LK
951 wid.id = (u16)WID_ABORT_RUNNING_SCAN;
952 wid.type = WID_CHAR;
953 wid.val = (s8 *)&u8abort_running_scan;
954 wid.size = sizeof(char);
c5c77ba1 955
45102f83 956 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 957 get_id_from_handler(hif_drv));
31390eec
LK
958
959 if (result) {
c5c77ba1 960 PRINT_ER("Failed to set abort running scan\n");
31390eec 961 result = -EFAULT;
c5c77ba1
JK
962 }
963 }
964
a4ab1ade 965 if (!hif_drv) {
c5c77ba1 966 PRINT_ER("Driver handler is NULL\n");
31390eec 967 return result;
c5c77ba1
JK
968 }
969
a4ab1ade
TC
970 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
971 hif_drv->strWILC_UsrScanReq.pfUserScanResult(enuEvent, NULL,
972 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
a4ab1ade 973 hif_drv->strWILC_UsrScanReq.pfUserScanResult = NULL;
c5c77ba1
JK
974 }
975
31390eec 976 return result;
c5c77ba1
JK
977}
978
63d03e47 979u8 u8ConnectedSSID[6] = {0};
a4ab1ade 980static s32 Handle_Connect(struct host_if_drv *hif_drv,
120ae593 981 struct connect_attr *pstrHostIFconnectAttr)
c5c77ba1 982{
31390eec 983 s32 result = 0;
e9e0c260 984 struct wid strWIDList[8];
4e4467fd 985 u32 u32WidsCount = 0, dummyval = 0;
63d03e47 986 u8 *pu8CurrByte = NULL;
e0a12217 987 struct join_bss_param *ptstrJoinBssParam;
c5c77ba1
JK
988
989 PRINT_D(GENERIC_DBG, "Handling connect request\n");
990
9254db07 991 if (memcmp(pstrHostIFconnectAttr->bssid, u8ConnectedSSID, ETH_ALEN) == 0) {
31390eec 992 result = 0;
c5c77ba1 993 PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n");
31390eec 994 return result;
c5c77ba1
JK
995 }
996
997 PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n");
998
f2bed2ca 999 ptstrJoinBssParam = (struct join_bss_param *)pstrHostIFconnectAttr->params;
91109e11 1000 if (!ptstrJoinBssParam) {
c5c77ba1 1001 PRINT_ER("Required BSSID not found\n");
31390eec 1002 result = -ENOENT;
24db713f 1003 goto ERRORHANDLER;
c5c77ba1 1004 }
c5c77ba1 1005
91109e11 1006 if (pstrHostIFconnectAttr->bssid) {
a4ab1ade 1007 hif_drv->strWILC_UsrConnReq.pu8bssid = kmalloc(6, GFP_KERNEL);
9254db07 1008 memcpy(hif_drv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->bssid, 6);
c5c77ba1
JK
1009 }
1010
8b3c9fa6 1011 hif_drv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssid_len;
91109e11 1012 if (pstrHostIFconnectAttr->ssid) {
8b3c9fa6 1013 hif_drv->strWILC_UsrConnReq.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
8c8360b3
LK
1014 memcpy(hif_drv->strWILC_UsrConnReq.pu8ssid,
1015 pstrHostIFconnectAttr->ssid,
1016 pstrHostIFconnectAttr->ssid_len);
8b3c9fa6 1017 hif_drv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
c5c77ba1
JK
1018 }
1019
b59d5c5b 1020 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->ies_len;
91109e11 1021 if (pstrHostIFconnectAttr->ies) {
b59d5c5b 1022 hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
8c8360b3
LK
1023 memcpy(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
1024 pstrHostIFconnectAttr->ies,
1025 pstrHostIFconnectAttr->ies_len);
c5c77ba1
JK
1026 }
1027
a64fd677 1028 hif_drv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->security;
61b4fd02 1029 hif_drv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->auth_type;
6abcc11d 1030 hif_drv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->result;
8f38db89 1031 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->arg;
c5c77ba1 1032
daaf16ba 1033 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
416d8321 1034 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 1035 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 1036 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
c5c77ba1
JK
1037 u32WidsCount++;
1038
daaf16ba 1039 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
416d8321 1040 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 1041 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 1042 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
c5c77ba1
JK
1043 u32WidsCount++;
1044
daaf16ba 1045 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
416d8321 1046 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 1047 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 1048 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
c5c77ba1
JK
1049 u32WidsCount++;
1050
c5c77ba1 1051 {
daaf16ba 1052 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
416d8321 1053 strWIDList[u32WidsCount].type = WID_BIN_DATA;
a4ab1ade
TC
1054 strWIDList[u32WidsCount].val = hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs;
1055 strWIDList[u32WidsCount].size = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
c5c77ba1
JK
1056 u32WidsCount++;
1057
f7bbd9cf 1058 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
dfef7b84
LK
1059 info_element_size = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
1060 info_element = kmalloc(info_element_size, GFP_KERNEL);
48ce2465 1061 memcpy(info_element, hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
dfef7b84 1062 info_element_size);
c5c77ba1
JK
1063 }
1064 }
daaf16ba 1065 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
416d8321 1066 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1067 strWIDList[u32WidsCount].size = sizeof(char);
bafaa696 1068 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->strWILC_UsrConnReq.u8security;
c5c77ba1
JK
1069 u32WidsCount++;
1070
f7bbd9cf 1071 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1bd9d44c 1072 mode_11i = hif_drv->strWILC_UsrConnReq.u8security;
c5c77ba1 1073
a4ab1ade 1074 PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", hif_drv->strWILC_UsrConnReq.u8security);
c5c77ba1 1075
daaf16ba 1076 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
416d8321 1077 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1078 strWIDList[u32WidsCount].size = sizeof(char);
a4ab1ade 1079 strWIDList[u32WidsCount].val = (s8 *)(&hif_drv->strWILC_UsrConnReq.tenuAuth_type);
c5c77ba1
JK
1080 u32WidsCount++;
1081
f7bbd9cf 1082 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
fba4989e 1083 auth_type = (u8)hif_drv->strWILC_UsrConnReq.tenuAuth_type;
c5c77ba1 1084
a4ab1ade 1085 PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", hif_drv->strWILC_UsrConnReq.tenuAuth_type);
c5c77ba1 1086 PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n",
0d1527e6 1087 hif_drv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->ch);
c5c77ba1 1088
daaf16ba 1089 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
416d8321 1090 strWIDList[u32WidsCount].type = WID_STR;
ae4dfa57 1091 strWIDList[u32WidsCount].size = 112;
900bb4a6 1092 strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
c5c77ba1 1093
f7bbd9cf 1094 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
0626baaa
LK
1095 join_req_size = strWIDList[u32WidsCount].size;
1096 join_req = kmalloc(join_req_size, GFP_KERNEL);
c5c77ba1 1097 }
91109e11 1098 if (!strWIDList[u32WidsCount].val) {
31390eec 1099 result = -EFAULT;
24db713f
LK
1100 goto ERRORHANDLER;
1101 }
c5c77ba1 1102
900bb4a6 1103 pu8CurrByte = strWIDList[u32WidsCount].val;
c5c77ba1 1104
91109e11 1105 if (pstrHostIFconnectAttr->ssid) {
8b3c9fa6
LK
1106 memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
1107 pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
c5c77ba1
JK
1108 }
1109 pu8CurrByte += MAX_SSID_LEN;
c5c77ba1 1110 *(pu8CurrByte++) = INFRASTRUCTURE;
ae4dfa57 1111
0d1527e6
LK
1112 if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1113 *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
c5c77ba1
JK
1114 } else {
1115 PRINT_ER("Channel out of range\n");
1116 *(pu8CurrByte++) = 0xFF;
1117 }
c5c77ba1
JK
1118 *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF;
1119 *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1120 PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
1121
91109e11 1122 if (pstrHostIFconnectAttr->bssid)
9254db07 1123 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
c5c77ba1
JK
1124 pu8CurrByte += 6;
1125
c0f52fba
TC
1126 if (pstrHostIFconnectAttr->bssid)
1127 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1128 pu8CurrByte += 6;
1129
c5c77ba1
JK
1130 *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
1131 *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1132 PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
c5c77ba1
JK
1133 *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
1134 PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1)));
ae4dfa57 1135
d00d2ba3 1136 memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
c5c77ba1
JK
1137 pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1138
c5c77ba1
JK
1139 *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
1140 PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1)));
c5c77ba1
JK
1141 *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
1142
c5c77ba1 1143 *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
a4ab1ade 1144 hif_drv->strWILC_UsrConnReq.IsHTCapable = ptstrJoinBssParam->ht_capable;
c5c77ba1 1145
c5c77ba1
JK
1146 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
1147 PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1));
c5c77ba1
JK
1148 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
1149 PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1)));
c5c77ba1
JK
1150 *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
1151 PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1)));
ae4dfa57 1152
d00d2ba3 1153 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
c5c77ba1
JK
1154 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1155
d00d2ba3 1156 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
c5c77ba1
JK
1157 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1158
d00d2ba3 1159 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
c5c77ba1
JK
1160 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1161
c5c77ba1 1162 *(pu8CurrByte++) = REAL_JOIN_REQ;
7a8d51d7 1163 *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
c5c77ba1 1164
7a8d51d7 1165 if (ptstrJoinBssParam->noa_enabled) {
c5c77ba1
JK
1166 PRINT_D(HOSTINF_DBG, "NOA present\n");
1167
1168 *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1169 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1170 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1171 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1172
d72b33ca 1173 *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
cc179008 1174 *(pu8CurrByte++) = ptstrJoinBssParam->idx;
c5c77ba1 1175
d72b33ca 1176 if (ptstrJoinBssParam->opp_enabled)
99b66945 1177 *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
c5c77ba1 1178
c21047ed 1179 *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
c5c77ba1 1180
109e6cab
LK
1181 memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1182 pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
c5c77ba1 1183
1d8b76b3
LK
1184 memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1185 pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
c5c77ba1 1186
4be55e22
LK
1187 memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
1188 pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
c5c77ba1
JK
1189 } else
1190 PRINT_D(HOSTINF_DBG, "NOA not present\n");
c5c77ba1 1191
900bb4a6 1192 pu8CurrByte = strWIDList[u32WidsCount].val;
c5c77ba1 1193 u32WidsCount++;
c5c77ba1 1194
f7bbd9cf 1195 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
0626baaa 1196 memcpy(join_req, pu8CurrByte, join_req_size);
870515c1 1197 join_req_drv = hif_drv;
c5c77ba1
JK
1198 }
1199
1200 PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n");
1201
91109e11 1202 if (pstrHostIFconnectAttr->bssid) {
9254db07 1203 memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->bssid, ETH_ALEN);
c5c77ba1 1204
9254db07 1205 PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->bssid);
310a28fd 1206 PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID);
c5c77ba1
JK
1207 }
1208
31390eec 1209 result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
8c8360b3 1210 get_id_from_handler(hif_drv));
31390eec 1211 if (result) {
24db713f 1212 PRINT_ER("failed to send config packet\n");
31390eec 1213 result = -EFAULT;
24db713f 1214 goto ERRORHANDLER;
c5c77ba1
JK
1215 } else {
1216 PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n");
a4ab1ade 1217 hif_drv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP;
c5c77ba1 1218 }
c5c77ba1 1219
24db713f 1220ERRORHANDLER:
31390eec 1221 if (result) {
c5c77ba1
JK
1222 tstrConnectInfo strConnectInfo;
1223
a4ab1ade 1224 del_timer(&hif_drv->hConnectTimer);
c5c77ba1
JK
1225
1226 PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n");
1227
2cc46837 1228 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
c5c77ba1 1229
91109e11
LK
1230 if (pstrHostIFconnectAttr->result) {
1231 if (pstrHostIFconnectAttr->bssid)
9254db07 1232 memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->bssid, 6);
c5c77ba1 1233
91109e11 1234 if (pstrHostIFconnectAttr->ies) {
b59d5c5b
LK
1235 strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->ies_len;
1236 strConnectInfo.pu8ReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
d00d2ba3 1237 memcpy(strConnectInfo.pu8ReqIEs,
8c8360b3
LK
1238 pstrHostIFconnectAttr->ies,
1239 pstrHostIFconnectAttr->ies_len);
c5c77ba1
JK
1240 }
1241
6abcc11d 1242 pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
c5c77ba1
JK
1243 &strConnectInfo,
1244 MAC_DISCONNECTED,
1245 NULL,
8f38db89 1246 pstrHostIFconnectAttr->arg);
a4ab1ade 1247 hif_drv->enuHostIFstate = HOST_IF_IDLE;
95f840fb
SB
1248 kfree(strConnectInfo.pu8ReqIEs);
1249 strConnectInfo.pu8ReqIEs = NULL;
c5c77ba1
JK
1250
1251 } else {
03b2d5e7 1252 PRINT_ER("Connect callback function pointer is NULL\n");
c5c77ba1
JK
1253 }
1254 }
1255
1256 PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n");
95f840fb
SB
1257 kfree(pstrHostIFconnectAttr->bssid);
1258 pstrHostIFconnectAttr->bssid = NULL;
c5c77ba1 1259
95f840fb
SB
1260 kfree(pstrHostIFconnectAttr->ssid);
1261 pstrHostIFconnectAttr->ssid = NULL;
c5c77ba1 1262
95f840fb
SB
1263 kfree(pstrHostIFconnectAttr->ies);
1264 pstrHostIFconnectAttr->ies = NULL;
c5c77ba1 1265
95f840fb 1266 kfree(pu8CurrByte);
31390eec 1267 return result;
c5c77ba1
JK
1268}
1269
a4ab1ade 1270static s32 Handle_FlushConnect(struct host_if_drv *hif_drv)
c5c77ba1 1271{
31390eec 1272 s32 result = 0;
e9e0c260 1273 struct wid strWIDList[5];
4e4467fd 1274 u32 u32WidsCount = 0;
63d03e47 1275 u8 *pu8CurrByte = NULL;
c5c77ba1 1276
daaf16ba 1277 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
416d8321 1278 strWIDList[u32WidsCount].type = WID_BIN_DATA;
48ce2465 1279 strWIDList[u32WidsCount].val = info_element;
dfef7b84 1280 strWIDList[u32WidsCount].size = info_element_size;
c5c77ba1
JK
1281 u32WidsCount++;
1282
daaf16ba 1283 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
416d8321 1284 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1285 strWIDList[u32WidsCount].size = sizeof(char);
1bd9d44c 1286 strWIDList[u32WidsCount].val = (s8 *)(&(mode_11i));
c5c77ba1
JK
1287 u32WidsCount++;
1288
daaf16ba 1289 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
416d8321 1290 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1291 strWIDList[u32WidsCount].size = sizeof(char);
fba4989e 1292 strWIDList[u32WidsCount].val = (s8 *)(&auth_type);
c5c77ba1
JK
1293 u32WidsCount++;
1294
daaf16ba 1295 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
416d8321 1296 strWIDList[u32WidsCount].type = WID_STR;
0626baaa 1297 strWIDList[u32WidsCount].size = join_req_size;
044a6410 1298 strWIDList[u32WidsCount].val = (s8 *)join_req;
900bb4a6 1299 pu8CurrByte = strWIDList[u32WidsCount].val;
c5c77ba1
JK
1300
1301 pu8CurrByte += FLUSHED_BYTE_POS;
1302 *(pu8CurrByte) = FLUSHED_JOIN_REQ;
1303
1304 u32WidsCount++;
1305
31390eec 1306 result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
8c8360b3 1307 get_id_from_handler(join_req_drv));
31390eec 1308 if (result) {
24db713f 1309 PRINT_ER("failed to send config packet\n");
31390eec 1310 result = -EINVAL;
c5c77ba1
JK
1311 }
1312
31390eec 1313 return result;
c5c77ba1
JK
1314}
1315
a4ab1ade 1316static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv)
c5c77ba1 1317{
31390eec 1318 s32 result = 0;
c5c77ba1 1319 tstrConnectInfo strConnectInfo;
45102f83 1320 struct wid wid;
d85f5326 1321 u16 u16DummyReasonCode = 0;
c5c77ba1 1322
a4ab1ade 1323 if (!hif_drv) {
c5c77ba1 1324 PRINT_ER("Driver handler is NULL\n");
31390eec 1325 return result;
c5c77ba1
JK
1326 }
1327
a4ab1ade 1328 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 1329
ca8540e4 1330 scan_while_connected = false;
c5c77ba1 1331
2cc46837 1332 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
c5c77ba1 1333
91109e11
LK
1334 if (hif_drv->strWILC_UsrConnReq.pfUserConnectResult) {
1335 if (hif_drv->strWILC_UsrConnReq.pu8bssid) {
d00d2ba3 1336 memcpy(strConnectInfo.au8bssid,
8c8360b3 1337 hif_drv->strWILC_UsrConnReq.pu8bssid, 6);
c5c77ba1
JK
1338 }
1339
91109e11 1340 if (hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs) {
a4ab1ade
TC
1341 strConnectInfo.ReqIEsLen = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
1342 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
d00d2ba3 1343 memcpy(strConnectInfo.pu8ReqIEs,
8c8360b3
LK
1344 hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
1345 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen);
c5c77ba1
JK
1346 }
1347
a4ab1ade 1348 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
c5c77ba1
JK
1349 &strConnectInfo,
1350 MAC_DISCONNECTED,
1351 NULL,
a4ab1ade 1352 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1 1353
95f840fb
SB
1354 kfree(strConnectInfo.pu8ReqIEs);
1355 strConnectInfo.pu8ReqIEs = NULL;
c5c77ba1 1356 } else {
03b2d5e7 1357 PRINT_ER("Connect callback function pointer is NULL\n");
c5c77ba1
JK
1358 }
1359
45102f83
LK
1360 wid.id = (u16)WID_DISCONNECT;
1361 wid.type = WID_CHAR;
1362 wid.val = (s8 *)&u16DummyReasonCode;
1363 wid.size = sizeof(char);
c5c77ba1
JK
1364
1365 PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1366
45102f83 1367 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1368 get_id_from_handler(hif_drv));
31390eec 1369 if (result)
c5c77ba1 1370 PRINT_ER("Failed to send dissconect config packet\n");
c5c77ba1 1371
a4ab1ade
TC
1372 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
1373 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
1374 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
1375 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
1376 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 1377
281dd5ac 1378 eth_zero_addr(u8ConnectedSSID);
ae4dfa57 1379
91109e11 1380 if (join_req && join_req_drv == hif_drv) {
044a6410
LK
1381 kfree(join_req);
1382 join_req = NULL;
c5c77ba1 1383 }
48ce2465 1384
91109e11 1385 if (info_element && join_req_drv == hif_drv) {
48ce2465
LK
1386 kfree(info_element);
1387 info_element = NULL;
c5c77ba1
JK
1388 }
1389
31390eec 1390 return result;
c5c77ba1
JK
1391}
1392
a4ab1ade 1393static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv,
3bbd59f5 1394 struct rcvd_net_info *pstrRcvdNetworkInfo)
c5c77ba1 1395{
4e4467fd 1396 u32 i;
72ed4dc7 1397 bool bNewNtwrkFound;
31390eec 1398 s32 result = 0;
c5c77ba1
JK
1399 tstrNetworkInfo *pstrNetworkInfo = NULL;
1400 void *pJoinParams = NULL;
1401
72ed4dc7 1402 bNewNtwrkFound = true;
c5c77ba1
JK
1403 PRINT_INFO(HOSTINF_DBG, "Handling received network info\n");
1404
a4ab1ade 1405 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
c5c77ba1 1406 PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n");
b021b80b 1407 parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
91109e11
LK
1408 if ((!pstrNetworkInfo) ||
1409 (!hif_drv->strWILC_UsrScanReq.pfUserScanResult)) {
24db713f 1410 PRINT_ER("driver is null\n");
31390eec 1411 result = -EINVAL;
24db713f 1412 goto done;
c5c77ba1
JK
1413 }
1414
a4ab1ade 1415 for (i = 0; i < hif_drv->strWILC_UsrScanReq.u32RcvdChCount; i++) {
91109e11
LK
1416 if ((hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid) &&
1417 (pstrNetworkInfo->au8bssid)) {
a4ab1ade 1418 if (memcmp(hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid,
8c8360b3 1419 pstrNetworkInfo->au8bssid, 6) == 0) {
a4ab1ade 1420 if (pstrNetworkInfo->s8rssi <= hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi) {
c5c77ba1
JK
1421 PRINT_D(HOSTINF_DBG, "Network previously discovered\n");
1422 goto done;
1423 } else {
a4ab1ade 1424 hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi;
72ed4dc7 1425 bNewNtwrkFound = false;
c5c77ba1
JK
1426 break;
1427 }
1428 }
1429 }
1430 }
1431
047e6646 1432 if (bNewNtwrkFound) {
c5c77ba1
JK
1433 PRINT_D(HOSTINF_DBG, "New network found\n");
1434
a4ab1ade
TC
1435 if (hif_drv->strWILC_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
1436 hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[hif_drv->strWILC_UsrScanReq.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi;
c5c77ba1 1437
91109e11
LK
1438 if (hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[hif_drv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid &&
1439 pstrNetworkInfo->au8bssid) {
a4ab1ade 1440 memcpy(hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[hif_drv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid,
8c8360b3 1441 pstrNetworkInfo->au8bssid, 6);
c5c77ba1 1442
a4ab1ade 1443 hif_drv->strWILC_UsrScanReq.u32RcvdChCount++;
c5c77ba1 1444
72ed4dc7 1445 pstrNetworkInfo->bNewNetwork = true;
c5c77ba1 1446 pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
c5c77ba1 1447
a4ab1ade
TC
1448 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1449 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid,
c5c77ba1 1450 pJoinParams);
c5c77ba1
JK
1451 }
1452 } else {
03b2d5e7 1453 PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit\n");
c5c77ba1
JK
1454 }
1455 } else {
72ed4dc7 1456 pstrNetworkInfo->bNewNetwork = false;
a4ab1ade
TC
1457 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1458 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
c5c77ba1
JK
1459 }
1460 }
1461
c5c77ba1 1462done:
95f840fb
SB
1463 kfree(pstrRcvdNetworkInfo->buffer);
1464 pstrRcvdNetworkInfo->buffer = NULL;
c5c77ba1 1465
91109e11 1466 if (pstrNetworkInfo) {
c5c77ba1 1467 DeallocateNetworkInfo(pstrNetworkInfo);
b1413b60 1468 pstrNetworkInfo = NULL;
c5c77ba1
JK
1469 }
1470
31390eec 1471 return result;
c5c77ba1
JK
1472}
1473
a4ab1ade 1474static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
f23a9eab 1475 struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
c5c77ba1 1476{
31390eec 1477 s32 result = 0;
63d03e47
GKH
1478 u8 u8MsgType = 0;
1479 u8 u8MsgID = 0;
d85f5326
CL
1480 u16 u16MsgLen = 0;
1481 u16 u16WidID = (u16)WID_NIL;
63d03e47
GKH
1482 u8 u8WidLen = 0;
1483 u8 u8MacStatus;
1484 u8 u8MacStatusReasonCode;
1485 u8 u8MacStatusAdditionalInfo;
c5c77ba1
JK
1486 tstrConnectInfo strConnectInfo;
1487 tstrDisconnectNotifInfo strDisconnectNotifInfo;
e6e12661 1488 s32 s32Err = 0;
78c87591 1489
a4ab1ade 1490 if (!hif_drv) {
c5c77ba1 1491 PRINT_ER("Driver handler is NULL\n");
234837de
LK
1492 return -ENODEV;
1493 }
a4ab1ade 1494 PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", hif_drv->enuHostIFstate,
33722ac7 1495 pstrRcvdGnrlAsyncInfo->buffer[7]);
c5c77ba1 1496
a4ab1ade
TC
1497 if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) ||
1498 (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) ||
1499 hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
91109e11
LK
1500 if (!pstrRcvdGnrlAsyncInfo->buffer ||
1501 !hif_drv->strWILC_UsrConnReq.pfUserConnectResult) {
24db713f
LK
1502 PRINT_ER("driver is null\n");
1503 return -EINVAL;
c5c77ba1
JK
1504 }
1505
33722ac7 1506 u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
c5c77ba1 1507
c5c77ba1
JK
1508 if ('I' != u8MsgType) {
1509 PRINT_ER("Received Message format incorrect.\n");
24db713f 1510 return -EFAULT;
c5c77ba1
JK
1511 }
1512
33722ac7
LK
1513 u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
1514 u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
1515 u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
1516 u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
1517 u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7];
1518 u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
1519 u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
c5c77ba1 1520 PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
a4ab1ade 1521 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
4e4467fd 1522 u32 u32RcvdAssocRespInfoLen;
c5c77ba1
JK
1523 tstrConnectRespInfo *pstrConnectRespInfo = NULL;
1524
1525 PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
1526
2cc46837 1527 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
c5c77ba1
JK
1528
1529 if (u8MacStatus == MAC_CONNECTED) {
a633c0b5 1530 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
c5c77ba1 1531
a4ab1ade 1532 host_int_get_assoc_res_info(hif_drv,
a633c0b5 1533 rcv_assoc_resp,
c5c77ba1
JK
1534 MAX_ASSOC_RESP_FRAME_SIZE,
1535 &u32RcvdAssocRespInfoLen);
1536
1537 PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen);
1538
1539 if (u32RcvdAssocRespInfoLen != 0) {
c5c77ba1 1540 PRINT_D(HOSTINF_DBG, "Parsing association response\n");
a633c0b5 1541 s32Err = ParseAssocRespInfo(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
c5c77ba1
JK
1542 &pstrConnectRespInfo);
1543 if (s32Err) {
03b2d5e7 1544 PRINT_ER("ParseAssocRespInfo() returned error %d\n", s32Err);
c5c77ba1 1545 } else {
c5c77ba1
JK
1546 strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus;
1547
1548 if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
1549 PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n");
91109e11 1550 if (pstrConnectRespInfo->pu8RespIEs) {
c5c77ba1 1551 strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen;
f3052587 1552 strConnectInfo.pu8RespIEs = kmalloc(pstrConnectRespInfo->u16RespIEsLen, GFP_KERNEL);
d00d2ba3 1553 memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs,
c5c77ba1
JK
1554 pstrConnectRespInfo->u16RespIEsLen);
1555 }
1556 }
1557
91109e11 1558 if (pstrConnectRespInfo) {
c5c77ba1
JK
1559 DeallocateAssocRespInfo(pstrConnectRespInfo);
1560 pstrConnectRespInfo = NULL;
1561 }
1562 }
1563 }
1564 }
1565
c5c77ba1
JK
1566 if ((u8MacStatus == MAC_CONNECTED) &&
1567 (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) {
03b2d5e7 1568 PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
281dd5ac 1569 eth_zero_addr(u8ConnectedSSID);
c5c77ba1
JK
1570
1571 } else if (u8MacStatus == MAC_DISCONNECTED) {
1572 PRINT_ER("Received MAC status is MAC_DISCONNECTED\n");
281dd5ac 1573 eth_zero_addr(u8ConnectedSSID);
c5c77ba1
JK
1574 }
1575
91109e11 1576 if (hif_drv->strWILC_UsrConnReq.pu8bssid) {
c5c77ba1 1577 PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n");
a4ab1ade 1578 memcpy(strConnectInfo.au8bssid, hif_drv->strWILC_UsrConnReq.pu8bssid, 6);
c5c77ba1
JK
1579
1580 if ((u8MacStatus == MAC_CONNECTED) &&
1581 (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
a4ab1ade
TC
1582 memcpy(hif_drv->au8AssociatedBSSID,
1583 hif_drv->strWILC_UsrConnReq.pu8bssid, ETH_ALEN);
c5c77ba1
JK
1584 }
1585 }
1586
91109e11 1587 if (hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs) {
a4ab1ade
TC
1588 strConnectInfo.ReqIEsLen = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
1589 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
d00d2ba3 1590 memcpy(strConnectInfo.pu8ReqIEs,
a4ab1ade
TC
1591 hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
1592 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen);
c5c77ba1
JK
1593 }
1594
a4ab1ade
TC
1595 del_timer(&hif_drv->hConnectTimer);
1596 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
c5c77ba1
JK
1597 &strConnectInfo,
1598 u8MacStatus,
1599 NULL,
a4ab1ade 1600 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1 1601
c5c77ba1
JK
1602 if ((u8MacStatus == MAC_CONNECTED) &&
1603 (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
a4ab1ade 1604 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1
JK
1605
1606 PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n");
a4ab1ade 1607 hif_drv->enuHostIFstate = HOST_IF_CONNECTED;
c5c77ba1 1608
c5c77ba1 1609 PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n");
72ed4dc7 1610 g_obtainingIP = true;
9eb06643
GKH
1611 mod_timer(&hDuringIpTimer,
1612 jiffies + msecs_to_jiffies(10000));
c5c77ba1
JK
1613 } else {
1614 PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus);
a4ab1ade 1615 hif_drv->enuHostIFstate = HOST_IF_IDLE;
ca8540e4 1616 scan_while_connected = false;
c5c77ba1
JK
1617 }
1618
95f840fb
SB
1619 kfree(strConnectInfo.pu8RespIEs);
1620 strConnectInfo.pu8RespIEs = NULL;
c5c77ba1 1621
95f840fb
SB
1622 kfree(strConnectInfo.pu8ReqIEs);
1623 strConnectInfo.pu8ReqIEs = NULL;
a4ab1ade
TC
1624 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
1625 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
1626 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
1627 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
1628 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 1629 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
a4ab1ade 1630 (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)) {
c5c77ba1
JK
1631 PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n");
1632
2cc46837 1633 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
c5c77ba1 1634
a4ab1ade 1635 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
03b2d5e7 1636 PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n");
a4ab1ade
TC
1637 del_timer(&hif_drv->hScanTimer);
1638 Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED);
c5c77ba1
JK
1639 }
1640
1641 strDisconnectNotifInfo.u16reason = 0;
1642 strDisconnectNotifInfo.ie = NULL;
1643 strDisconnectNotifInfo.ie_len = 0;
1644
91109e11 1645 if (hif_drv->strWILC_UsrConnReq.pfUserConnectResult) {
72ed4dc7 1646 g_obtainingIP = false;
a4ab1ade 1647 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1 1648
a4ab1ade 1649 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF,
c5c77ba1
JK
1650 NULL,
1651 0,
1652 &strDisconnectNotifInfo,
a4ab1ade 1653 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1
JK
1654
1655 } else {
03b2d5e7 1656 PRINT_ER("Connect result callback function is NULL\n");
c5c77ba1
JK
1657 }
1658
a4ab1ade 1659 eth_zero_addr(hif_drv->au8AssociatedBSSID);
c5c77ba1 1660
a4ab1ade
TC
1661 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
1662 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
1663 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
1664 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
1665 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 1666
91109e11 1667 if (join_req && join_req_drv == hif_drv) {
044a6410
LK
1668 kfree(join_req);
1669 join_req = NULL;
c5c77ba1 1670 }
48ce2465 1671
91109e11 1672 if (info_element && join_req_drv == hif_drv) {
48ce2465
LK
1673 kfree(info_element);
1674 info_element = NULL;
c5c77ba1
JK
1675 }
1676
a4ab1ade 1677 hif_drv->enuHostIFstate = HOST_IF_IDLE;
ca8540e4 1678 scan_while_connected = false;
c5c77ba1
JK
1679
1680 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
91109e11 1681 (hif_drv->strWILC_UsrScanReq.pfUserScanResult)) {
c5c77ba1 1682 PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n");
03b2d5e7 1683 PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n");
ae4dfa57 1684
a4ab1ade
TC
1685 del_timer(&hif_drv->hScanTimer);
1686 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult)
1687 Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
c5c77ba1 1688 }
c5c77ba1
JK
1689 }
1690
95f840fb
SB
1691 kfree(pstrRcvdGnrlAsyncInfo->buffer);
1692 pstrRcvdGnrlAsyncInfo->buffer = NULL;
c5c77ba1 1693
31390eec 1694 return result;
c5c77ba1
JK
1695}
1696
a4ab1ade 1697static int Handle_Key(struct host_if_drv *hif_drv,
c98387a5 1698 struct key_attr *pstrHostIFkeyAttr)
c5c77ba1 1699{
31390eec 1700 s32 result = 0;
45102f83 1701 struct wid wid;
e9e0c260 1702 struct wid strWIDList[5];
63d03e47
GKH
1703 u8 i;
1704 u8 *pu8keybuf;
ca356ada
CL
1705 s8 s8idxarray[1];
1706 s8 ret = 0;
c5c77ba1 1707
8e9f427a 1708 switch (pstrHostIFkeyAttr->type) {
c5c77ba1
JK
1709 case WEP:
1710
0d17e382 1711 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
c5c77ba1 1712 PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
bafaa696 1713 PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", pstrHostIFkeyAttr->attr.wep.index);
daaf16ba 1714 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1715 strWIDList[0].type = WID_CHAR;
2fd3e443 1716 strWIDList[0].size = sizeof(char);
bafaa696 1717 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
c5c77ba1 1718
daaf16ba 1719 strWIDList[1].id = WID_AUTH_TYPE;
416d8321 1720 strWIDList[1].type = WID_CHAR;
2fd3e443 1721 strWIDList[1].size = sizeof(char);
bafaa696 1722 strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
c5c77ba1 1723
daaf16ba 1724 strWIDList[2].id = (u16)WID_KEY_ID;
416d8321 1725 strWIDList[2].type = WID_CHAR;
c5c77ba1 1726
bafaa696 1727 strWIDList[2].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
2fd3e443 1728 strWIDList[2].size = sizeof(char);
c5c77ba1 1729
543f5b13
SB
1730 pu8keybuf = kmemdup(pstrHostIFkeyAttr->attr.wep.key,
1731 pstrHostIFkeyAttr->attr.wep.key_len,
1732 GFP_KERNEL);
c5c77ba1
JK
1733
1734 if (pu8keybuf == NULL) {
1735 PRINT_ER("No buffer to send Key\n");
9081987d 1736 return -ENOMEM;
c5c77ba1
JK
1737 }
1738
73b2e381 1739 kfree(pstrHostIFkeyAttr->attr.wep.key);
c5c77ba1 1740
daaf16ba 1741 strWIDList[3].id = (u16)WID_WEP_KEY_VALUE;
416d8321 1742 strWIDList[3].type = WID_STR;
73b2e381 1743 strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len;
900bb4a6 1744 strWIDList[3].val = (s8 *)pu8keybuf;
c5c77ba1 1745
31390eec 1746 result = send_config_pkt(SET_CFG, strWIDList, 4,
8c8360b3 1747 get_id_from_handler(hif_drv));
49188af2 1748 kfree(pu8keybuf);
c5c77ba1 1749 }
c5c77ba1 1750
0d17e382 1751 if (pstrHostIFkeyAttr->action & ADDKEY) {
c5c77ba1 1752 PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
73b2e381 1753 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
91109e11 1754 if (!pu8keybuf) {
c5c77ba1 1755 PRINT_ER("No buffer to send Key\n");
9081987d 1756 return -ENOMEM;
c5c77ba1 1757 }
73b2e381
LK
1758 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1759 memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1760 memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
8c8360b3 1761 pstrHostIFkeyAttr->attr.wep.key_len);
73b2e381 1762 kfree(pstrHostIFkeyAttr->attr.wep.key);
c5c77ba1 1763
45102f83
LK
1764 wid.id = (u16)WID_ADD_WEP_KEY;
1765 wid.type = WID_STR;
1766 wid.val = (s8 *)pu8keybuf;
1767 wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
c5c77ba1 1768
45102f83 1769 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1770 get_id_from_handler(hif_drv));
49188af2 1771 kfree(pu8keybuf);
0d17e382 1772 } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
c5c77ba1 1773 PRINT_D(HOSTINF_DBG, "Removing key\n");
45102f83
LK
1774 wid.id = (u16)WID_REMOVE_WEP_KEY;
1775 wid.type = WID_STR;
c5c77ba1 1776
73b2e381 1777 s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
45102f83
LK
1778 wid.val = s8idxarray;
1779 wid.size = 1;
c5c77ba1 1780
45102f83 1781 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1782 get_id_from_handler(hif_drv));
c5c77ba1 1783 } else {
45102f83
LK
1784 wid.id = (u16)WID_KEY_ID;
1785 wid.type = WID_CHAR;
1786 wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1787 wid.size = sizeof(char);
c5c77ba1
JK
1788
1789 PRINT_D(HOSTINF_DBG, "Setting default key index\n");
1790
45102f83 1791 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1792 get_id_from_handler(hif_drv));
c5c77ba1 1793 }
a4ab1ade 1794 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1795 break;
1796
1797 case WPARxGtk:
0d17e382 1798 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
b156f1ed 1799 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
91109e11 1800 if (!pu8keybuf) {
c5c77ba1 1801 PRINT_ER("No buffer to send RxGTK Key\n");
9081987d 1802 ret = -ENOMEM;
c5c77ba1
JK
1803 goto _WPARxGtk_end_case_;
1804 }
1805
91109e11 1806 if (pstrHostIFkeyAttr->attr.wpa.seq)
0e74c009 1807 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
c5c77ba1 1808
e2dfbac5 1809 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1810 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1811 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1812 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1813
daaf16ba 1814 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1815 strWIDList[0].type = WID_CHAR;
2fd3e443 1816 strWIDList[0].size = sizeof(char);
bafaa696 1817 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
c5c77ba1 1818
daaf16ba 1819 strWIDList[1].id = (u16)WID_ADD_RX_GTK;
416d8321 1820 strWIDList[1].type = WID_STR;
900bb4a6 1821 strWIDList[1].val = (s8 *)pu8keybuf;
2fd3e443 1822 strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
c5c77ba1 1823
31390eec 1824 result = send_config_pkt(SET_CFG, strWIDList, 2,
8c8360b3 1825 get_id_from_handler(hif_drv));
c5c77ba1 1826
49188af2 1827 kfree(pu8keybuf);
a4ab1ade 1828 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1829 }
1830
0d17e382 1831 if (pstrHostIFkeyAttr->action & ADDKEY) {
c5c77ba1
JK
1832 PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
1833
b156f1ed 1834 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
c5c77ba1
JK
1835 if (pu8keybuf == NULL) {
1836 PRINT_ER("No buffer to send RxGTK Key\n");
9081987d 1837 ret = -ENOMEM;
c5c77ba1
JK
1838 goto _WPARxGtk_end_case_;
1839 }
1840
a4ab1ade
TC
1841 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
1842 memcpy(pu8keybuf, hif_drv->au8AssociatedBSSID, ETH_ALEN);
78174ada 1843 else
03b2d5e7 1844 PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED\n");
c5c77ba1 1845
0e74c009 1846 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
e2dfbac5 1847 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1848 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1849 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1850 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1851
45102f83
LK
1852 wid.id = (u16)WID_ADD_RX_GTK;
1853 wid.type = WID_STR;
1854 wid.val = (s8 *)pu8keybuf;
1855 wid.size = RX_MIC_KEY_MSG_LEN;
c5c77ba1 1856
45102f83 1857 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1858 get_id_from_handler(hif_drv));
c5c77ba1 1859
49188af2 1860 kfree(pu8keybuf);
a4ab1ade 1861 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1862 }
1863_WPARxGtk_end_case_:
124968fc 1864 kfree(pstrHostIFkeyAttr->attr.wpa.key);
0e74c009 1865 kfree(pstrHostIFkeyAttr->attr.wpa.seq);
9081987d 1866 if (ret)
c5c77ba1
JK
1867 return ret;
1868
1869 break;
1870
1871 case WPAPtk:
0d17e382 1872 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
f3052587 1873 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
91109e11 1874 if (!pu8keybuf) {
c5c77ba1 1875 PRINT_ER("No buffer to send PTK Key\n");
9081987d 1876 ret = -ENOMEM;
c5c77ba1 1877 goto _WPAPtk_end_case_;
c5c77ba1
JK
1878 }
1879
248080aa 1880 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
e2dfbac5 1881 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1882 memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1883 memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1884 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1885
daaf16ba 1886 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1887 strWIDList[0].type = WID_CHAR;
2fd3e443 1888 strWIDList[0].size = sizeof(char);
bafaa696 1889 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
c5c77ba1 1890
daaf16ba 1891 strWIDList[1].id = (u16)WID_ADD_PTK;
416d8321 1892 strWIDList[1].type = WID_STR;
900bb4a6 1893 strWIDList[1].val = (s8 *)pu8keybuf;
2fd3e443 1894 strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
c5c77ba1 1895
31390eec 1896 result = send_config_pkt(SET_CFG, strWIDList, 2,
8c8360b3 1897 get_id_from_handler(hif_drv));
49188af2 1898 kfree(pu8keybuf);
a4ab1ade 1899 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1 1900 }
0d17e382 1901 if (pstrHostIFkeyAttr->action & ADDKEY) {
f3052587 1902 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
91109e11 1903 if (!pu8keybuf) {
c5c77ba1 1904 PRINT_ER("No buffer to send PTK Key\n");
9081987d 1905 ret = -ENOMEM;
c5c77ba1 1906 goto _WPAPtk_end_case_;
c5c77ba1
JK
1907 }
1908
248080aa 1909 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
6acf2919 1910 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1911 memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1912 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1913
45102f83
LK
1914 wid.id = (u16)WID_ADD_PTK;
1915 wid.type = WID_STR;
1916 wid.val = (s8 *)pu8keybuf;
1917 wid.size = PTK_KEY_MSG_LEN;
c5c77ba1 1918
45102f83 1919 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1920 get_id_from_handler(hif_drv));
49188af2 1921 kfree(pu8keybuf);
a4ab1ade 1922 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1923 }
1924
1925_WPAPtk_end_case_:
124968fc 1926 kfree(pstrHostIFkeyAttr->attr.wpa.key);
9081987d 1927 if (ret)
c5c77ba1
JK
1928 return ret;
1929
1930 break;
1931
c5c77ba1
JK
1932 case PMKSA:
1933
1934 PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n");
1935
73b2e381 1936 pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
91109e11 1937 if (!pu8keybuf) {
c5c77ba1 1938 PRINT_ER("No buffer to send PMKSA Key\n");
9081987d 1939 return -ENOMEM;
c5c77ba1
JK
1940 }
1941
73b2e381 1942 pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
c5c77ba1 1943
73b2e381
LK
1944 for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1945 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1946 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
c5c77ba1
JK
1947 }
1948
45102f83
LK
1949 wid.id = (u16)WID_PMKID_INFO;
1950 wid.type = WID_STR;
1951 wid.val = (s8 *)pu8keybuf;
1952 wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
c5c77ba1 1953
45102f83 1954 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1955 get_id_from_handler(hif_drv));
c5c77ba1 1956
49188af2 1957 kfree(pu8keybuf);
c5c77ba1
JK
1958 break;
1959 }
1960
31390eec 1961 if (result)
c5c77ba1
JK
1962 PRINT_ER("Failed to send key config packet\n");
1963
31390eec 1964 return result;
c5c77ba1
JK
1965}
1966
a4ab1ade 1967static void Handle_Disconnect(struct host_if_drv *hif_drv)
c5c77ba1 1968{
45102f83 1969 struct wid wid;
c5c77ba1 1970
31390eec 1971 s32 result = 0;
d85f5326 1972 u16 u16DummyReasonCode = 0;
c5c77ba1 1973
45102f83
LK
1974 wid.id = (u16)WID_DISCONNECT;
1975 wid.type = WID_CHAR;
1976 wid.val = (s8 *)&u16DummyReasonCode;
1977 wid.size = sizeof(char);
c5c77ba1 1978
c5c77ba1
JK
1979 PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1980
72ed4dc7 1981 g_obtainingIP = false;
a4ab1ade 1982 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1 1983
281dd5ac 1984 eth_zero_addr(u8ConnectedSSID);
c5c77ba1 1985
45102f83 1986 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1987 get_id_from_handler(hif_drv));
c5c77ba1 1988
31390eec 1989 if (result) {
c5c77ba1 1990 PRINT_ER("Failed to send dissconect config packet\n");
c5c77ba1
JK
1991 } else {
1992 tstrDisconnectNotifInfo strDisconnectNotifInfo;
1993
2cc46837 1994 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
c5c77ba1
JK
1995
1996 strDisconnectNotifInfo.u16reason = 0;
1997 strDisconnectNotifInfo.ie = NULL;
1998 strDisconnectNotifInfo.ie_len = 0;
1999
a4ab1ade
TC
2000 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
2001 del_timer(&hif_drv->hScanTimer);
2002 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
2003 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
c5c77ba1 2004
a4ab1ade 2005 hif_drv->strWILC_UsrScanReq.pfUserScanResult = NULL;
c5c77ba1
JK
2006 }
2007
91109e11 2008 if (hif_drv->strWILC_UsrConnReq.pfUserConnectResult) {
a4ab1ade 2009 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
c5c77ba1 2010 PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n");
a4ab1ade 2011 del_timer(&hif_drv->hConnectTimer);
c5c77ba1
JK
2012 }
2013
a4ab1ade
TC
2014 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
2015 0, &strDisconnectNotifInfo, hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1 2016 } else {
03b2d5e7 2017 PRINT_ER("strWILC_UsrConnReq.pfUserConnectResult = NULL\n");
c5c77ba1
JK
2018 }
2019
ca8540e4 2020 scan_while_connected = false;
c5c77ba1 2021
a4ab1ade 2022 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 2023
a4ab1ade 2024 eth_zero_addr(hif_drv->au8AssociatedBSSID);
c5c77ba1 2025
a4ab1ade
TC
2026 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
2027 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
2028 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
2029 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
2030 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 2031
91109e11 2032 if (join_req && join_req_drv == hif_drv) {
044a6410
LK
2033 kfree(join_req);
2034 join_req = NULL;
c5c77ba1 2035 }
48ce2465 2036
91109e11 2037 if (info_element && join_req_drv == hif_drv) {
48ce2465
LK
2038 kfree(info_element);
2039 info_element = NULL;
c5c77ba1 2040 }
c5c77ba1
JK
2041 }
2042
a4ab1ade 2043 up(&hif_drv->hSemTestDisconnectBlock);
c5c77ba1
JK
2044}
2045
a4ab1ade 2046void resolve_disconnect_aberration(struct host_if_drv *hif_drv)
c5c77ba1 2047{
a4ab1ade 2048 if (!hif_drv)
c5c77ba1 2049 return;
a4ab1ade 2050 if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (hif_drv->enuHostIFstate == HOST_IF_CONNECTING)) {
c5c77ba1 2051 PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n");
a4ab1ade 2052 host_int_disconnect(hif_drv, 1);
c5c77ba1
JK
2053 }
2054}
c5c77ba1 2055
a4ab1ade 2056static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
c5c77ba1 2057{
31390eec 2058 s32 result = 0;
45102f83 2059 struct wid wid;
78c87591 2060
45102f83
LK
2061 wid.id = (u16)WID_CURRENT_CHANNEL;
2062 wid.type = WID_CHAR;
2063 wid.val = (s8 *)&ch_no;
2064 wid.size = sizeof(char);
c5c77ba1
JK
2065
2066 PRINT_D(HOSTINF_DBG, "Getting channel value\n");
2067
45102f83 2068 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2069 get_id_from_handler(hif_drv));
ae4dfa57 2070
31390eec 2071 if (result) {
c5c77ba1 2072 PRINT_ER("Failed to get channel number\n");
31390eec 2073 result = -EFAULT;
c5c77ba1
JK
2074 }
2075
a4ab1ade 2076 up(&hif_drv->hSemGetCHNL);
c5c77ba1 2077
31390eec 2078 return result;
c5c77ba1
JK
2079}
2080
a4ab1ade 2081static void Handle_GetRssi(struct host_if_drv *hif_drv)
c5c77ba1 2082{
31390eec 2083 s32 result = 0;
45102f83 2084 struct wid wid;
c5c77ba1 2085
45102f83
LK
2086 wid.id = (u16)WID_RSSI;
2087 wid.type = WID_CHAR;
2088 wid.val = &rssi;
2089 wid.size = sizeof(char);
c5c77ba1 2090
c5c77ba1
JK
2091 PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
2092
45102f83 2093 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2094 get_id_from_handler(hif_drv));
31390eec 2095 if (result) {
c5c77ba1 2096 PRINT_ER("Failed to get RSSI value\n");
31390eec 2097 result = -EFAULT;
c5c77ba1
JK
2098 }
2099
a4ab1ade 2100 up(&hif_drv->hSemGetRSSI);
c5c77ba1
JK
2101}
2102
a4ab1ade 2103static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
c5c77ba1 2104{
31390eec 2105 s32 result = 0;
45102f83 2106 struct wid wid;
c5c77ba1 2107
75327a02 2108 link_speed = 0;
c5c77ba1 2109
45102f83
LK
2110 wid.id = (u16)WID_LINKSPEED;
2111 wid.type = WID_CHAR;
2112 wid.val = &link_speed;
2113 wid.size = sizeof(char);
ae4dfa57 2114
c5c77ba1
JK
2115 PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
2116
45102f83 2117 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2118 get_id_from_handler(hif_drv));
31390eec 2119 if (result) {
c5c77ba1 2120 PRINT_ER("Failed to get LINKSPEED value\n");
31390eec 2121 result = -EFAULT;
c5c77ba1
JK
2122 }
2123
bafaa696 2124 up(&hif_drv->hSemGetLINKSPEED);
c5c77ba1
JK
2125}
2126
a4ab1ade 2127s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
c5c77ba1 2128{
e9e0c260 2129 struct wid strWIDList[5];
31390eec 2130 u32 u32WidsCount = 0, result = 0;
c5c77ba1 2131
daaf16ba 2132 strWIDList[u32WidsCount].id = WID_LINKSPEED;
416d8321 2133 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 2134 strWIDList[u32WidsCount].size = sizeof(char);
bafaa696 2135 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u8LinkSpeed;
c5c77ba1
JK
2136 u32WidsCount++;
2137
daaf16ba 2138 strWIDList[u32WidsCount].id = WID_RSSI;
416d8321 2139 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 2140 strWIDList[u32WidsCount].size = sizeof(char);
bafaa696 2141 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->s8RSSI;
c5c77ba1
JK
2142 u32WidsCount++;
2143
daaf16ba 2144 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
416d8321 2145 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2146 strWIDList[u32WidsCount].size = sizeof(u32);
bafaa696 2147 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxCount;
c5c77ba1
JK
2148 u32WidsCount++;
2149
daaf16ba 2150 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
416d8321 2151 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2152 strWIDList[u32WidsCount].size = sizeof(u32);
bafaa696 2153 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32RxCount;
c5c77ba1
JK
2154 u32WidsCount++;
2155
daaf16ba 2156 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
416d8321 2157 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2158 strWIDList[u32WidsCount].size = sizeof(u32);
bafaa696 2159 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxFailureCount;
c5c77ba1
JK
2160 u32WidsCount++;
2161
31390eec 2162 result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount,
8c8360b3 2163 get_id_from_handler(hif_drv));
c5c77ba1 2164
31390eec 2165 if (result)
c5c77ba1 2166 PRINT_ER("Failed to send scan paramters config packet\n");
24db713f 2167
2d25af87 2168 up(&hif_sema_wait_response);
c5c77ba1 2169 return 0;
c5c77ba1
JK
2170}
2171
a4ab1ade 2172static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
3d1eac04 2173 struct sta_inactive_t *strHostIfStaInactiveT)
c5c77ba1 2174{
31390eec 2175 s32 result = 0;
63d03e47 2176 u8 *stamac;
45102f83 2177 struct wid wid;
c5c77ba1 2178
45102f83
LK
2179 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
2180 wid.type = WID_STR;
2181 wid.size = ETH_ALEN;
2182 wid.val = kmalloc(wid.size, GFP_KERNEL);
c5c77ba1 2183
45102f83 2184 stamac = wid.val;
d00d2ba3 2185 memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
c5c77ba1 2186
c5c77ba1
JK
2187 PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
2188
45102f83 2189 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2190 get_id_from_handler(hif_drv));
ae4dfa57 2191
31390eec 2192 if (result) {
c5c77ba1 2193 PRINT_ER("Failed to SET incative time\n");
24db713f 2194 return -EFAULT;
c5c77ba1
JK
2195 }
2196
45102f83
LK
2197 wid.id = (u16)WID_GET_INACTIVE_TIME;
2198 wid.type = WID_INT;
2199 wid.val = (s8 *)&inactive_time;
2200 wid.size = sizeof(u32);
c5c77ba1 2201
45102f83 2202 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2203 get_id_from_handler(hif_drv));
ae4dfa57 2204
31390eec 2205 if (result) {
c5c77ba1 2206 PRINT_ER("Failed to get incative time\n");
24db713f 2207 return -EFAULT;
c5c77ba1
JK
2208 }
2209
ad26906f 2210 PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time);
c5c77ba1 2211
a4ab1ade 2212 up(&hif_drv->hSemInactiveTime);
c5c77ba1 2213
31390eec 2214 return result;
c5c77ba1
JK
2215}
2216
a4ab1ade 2217static void Handle_AddBeacon(struct host_if_drv *hif_drv,
7f33fecd 2218 struct beacon_attr *pstrSetBeaconParam)
c5c77ba1 2219{
31390eec 2220 s32 result = 0;
45102f83 2221 struct wid wid;
63d03e47 2222 u8 *pu8CurrByte;
78c87591 2223
c5c77ba1
JK
2224 PRINT_D(HOSTINF_DBG, "Adding BEACON\n");
2225
45102f83
LK
2226 wid.id = (u16)WID_ADD_BEACON;
2227 wid.type = WID_BIN;
2228 wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
2229 wid.val = kmalloc(wid.size, GFP_KERNEL);
2230 if (!wid.val)
24db713f 2231 goto ERRORHANDLER;
c5c77ba1 2232
45102f83 2233 pu8CurrByte = wid.val;
12262dda
LK
2234 *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2235 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2236 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2237 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
c5c77ba1 2238
e76ab770
LK
2239 *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2240 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2241 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2242 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
c5c77ba1 2243
51c66185
LK
2244 *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2245 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2246 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2247 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
c5c77ba1 2248
8ce528b9 2249 memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
51c66185 2250 pu8CurrByte += pstrSetBeaconParam->head_len;
c5c77ba1 2251
030c57e2
LK
2252 *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2253 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2254 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2255 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
c5c77ba1 2256
7dbcb6d3
LK
2257 if (pstrSetBeaconParam->tail > 0)
2258 memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
030c57e2 2259 pu8CurrByte += pstrSetBeaconParam->tail_len;
c5c77ba1 2260
45102f83 2261 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2262 get_id_from_handler(hif_drv));
31390eec 2263 if (result)
c5c77ba1 2264 PRINT_ER("Failed to send add beacon config packet\n");
c5c77ba1 2265
24db713f 2266ERRORHANDLER:
45102f83 2267 kfree(wid.val);
8ce528b9 2268 kfree(pstrSetBeaconParam->head);
7dbcb6d3 2269 kfree(pstrSetBeaconParam->tail);
c5c77ba1
JK
2270}
2271
a4ab1ade 2272static void Handle_DelBeacon(struct host_if_drv *hif_drv)
c5c77ba1 2273{
31390eec 2274 s32 result = 0;
45102f83 2275 struct wid wid;
63d03e47 2276 u8 *pu8CurrByte;
78c87591 2277
45102f83
LK
2278 wid.id = (u16)WID_DEL_BEACON;
2279 wid.type = WID_CHAR;
2280 wid.size = sizeof(char);
2281 wid.val = &del_beacon;
c5c77ba1 2282
45102f83 2283 if (!wid.val)
24db713f 2284 return;
c5c77ba1 2285
45102f83 2286 pu8CurrByte = wid.val;
c5c77ba1
JK
2287
2288 PRINT_D(HOSTINF_DBG, "Deleting BEACON\n");
c5c77ba1 2289
45102f83 2290 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2291 get_id_from_handler(hif_drv));
31390eec 2292 if (result)
c5c77ba1 2293 PRINT_ER("Failed to send delete beacon config packet\n");
c5c77ba1
JK
2294}
2295
6a89ba9c
TC
2296static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2297 struct add_sta_param *pstrStationParam)
c5c77ba1 2298{
63d03e47 2299 u8 *pu8CurrByte;
c5c77ba1
JK
2300
2301 pu8CurrByte = pu8Buffer;
2302
2303 PRINT_D(HOSTINF_DBG, "Packing STA params\n");
d00d2ba3 2304 memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN);
c5c77ba1
JK
2305 pu8CurrByte += ETH_ALEN;
2306
2307 *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF;
2308 *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF;
2309
2310 *pu8CurrByte++ = pstrStationParam->u8NumRates;
2b9d5b48 2311 if (pstrStationParam->u8NumRates > 0)
d00d2ba3 2312 memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates);
c5c77ba1
JK
2313 pu8CurrByte += pstrStationParam->u8NumRates;
2314
2315 *pu8CurrByte++ = pstrStationParam->bIsHTSupported;
2316 *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF;
2317 *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF;
2318
2319 *pu8CurrByte++ = pstrStationParam->u8AmpduParams;
d00d2ba3 2320 memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE);
c5c77ba1
JK
2321 pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2322
2323 *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF;
2324 *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF;
2325
2326 *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF;
2327 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF;
2328 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF;
2329 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF;
2330
2331 *pu8CurrByte++ = pstrStationParam->u8ASELCap;
2332
2333 *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF;
2334 *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF;
2335
2336 *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF;
2337 *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF;
2338
2339 return pu8CurrByte - pu8Buffer;
2340}
2341
a4ab1ade 2342static void Handle_AddStation(struct host_if_drv *hif_drv,
6a89ba9c 2343 struct add_sta_param *pstrStationParam)
c5c77ba1 2344{
31390eec 2345 s32 result = 0;
45102f83 2346 struct wid wid;
63d03e47 2347 u8 *pu8CurrByte;
78c87591 2348
c5c77ba1 2349 PRINT_D(HOSTINF_DBG, "Handling add station\n");
45102f83
LK
2350 wid.id = (u16)WID_ADD_STA;
2351 wid.type = WID_BIN;
2352 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
c5c77ba1 2353
45102f83
LK
2354 wid.val = kmalloc(wid.size, GFP_KERNEL);
2355 if (!wid.val)
24db713f 2356 goto ERRORHANDLER;
c5c77ba1 2357
45102f83 2358 pu8CurrByte = wid.val;
c5c77ba1
JK
2359 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2360
45102f83 2361 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2362 get_id_from_handler(hif_drv));
31390eec 2363 if (result != 0)
c5c77ba1 2364 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2365
24db713f 2366ERRORHANDLER:
969effe9 2367 kfree(pstrStationParam->pu8Rates);
45102f83 2368 kfree(wid.val);
c5c77ba1
JK
2369}
2370
a4ab1ade 2371static void Handle_DelAllSta(struct host_if_drv *hif_drv,
b4e644e4 2372 struct del_all_sta *pstrDelAllStaParam)
c5c77ba1 2373{
31390eec 2374 s32 result = 0;
45102f83 2375 struct wid wid;
63d03e47 2376 u8 *pu8CurrByte;
63d03e47 2377 u8 i;
3703480b 2378 u8 au8Zero_Buff[6] = {0};
78c87591 2379
45102f83
LK
2380 wid.id = (u16)WID_DEL_ALL_STA;
2381 wid.type = WID_STR;
2382 wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
c5c77ba1 2383
03b2d5e7 2384 PRINT_D(HOSTINF_DBG, "Handling delete station\n");
c5c77ba1 2385
45102f83
LK
2386 wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2387 if (!wid.val)
24db713f 2388 goto ERRORHANDLER;
c5c77ba1 2389
45102f83 2390 pu8CurrByte = wid.val;
c5c77ba1 2391
8ba1803f 2392 *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
c5c77ba1
JK
2393
2394 for (i = 0; i < MAX_NUM_STA; i++) {
e51b9216
LK
2395 if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2396 memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
c5c77ba1
JK
2397 else
2398 continue;
2399
2400 pu8CurrByte += ETH_ALEN;
2401 }
2402
45102f83 2403 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2404 get_id_from_handler(hif_drv));
31390eec 2405 if (result)
83cc9be5 2406 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2407
24db713f 2408ERRORHANDLER:
45102f83 2409 kfree(wid.val);
c5c77ba1 2410
2d25af87 2411 up(&hif_sema_wait_response);
c5c77ba1
JK
2412}
2413
a4ab1ade 2414static void Handle_DelStation(struct host_if_drv *hif_drv,
fb93a1e1 2415 struct del_sta *pstrDelStaParam)
c5c77ba1 2416{
31390eec 2417 s32 result = 0;
45102f83 2418 struct wid wid;
63d03e47 2419 u8 *pu8CurrByte;
c5c77ba1 2420
45102f83
LK
2421 wid.id = (u16)WID_REMOVE_STA;
2422 wid.type = WID_BIN;
2423 wid.size = ETH_ALEN;
c5c77ba1 2424
03b2d5e7 2425 PRINT_D(HOSTINF_DBG, "Handling delete station\n");
c5c77ba1 2426
45102f83
LK
2427 wid.val = kmalloc(wid.size, GFP_KERNEL);
2428 if (!wid.val)
24db713f 2429 goto ERRORHANDLER;
c5c77ba1 2430
45102f83 2431 pu8CurrByte = wid.val;
c5c77ba1 2432
e4839d39 2433 memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
c5c77ba1 2434
45102f83 2435 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2436 get_id_from_handler(hif_drv));
31390eec 2437 if (result)
83cc9be5 2438 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2439
24db713f 2440ERRORHANDLER:
45102f83 2441 kfree(wid.val);
c5c77ba1
JK
2442}
2443
a4ab1ade 2444static void Handle_EditStation(struct host_if_drv *hif_drv,
6a89ba9c 2445 struct add_sta_param *pstrStationParam)
c5c77ba1 2446{
31390eec 2447 s32 result = 0;
45102f83 2448 struct wid wid;
63d03e47 2449 u8 *pu8CurrByte;
c5c77ba1 2450
45102f83
LK
2451 wid.id = (u16)WID_EDIT_STA;
2452 wid.type = WID_BIN;
2453 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
c5c77ba1
JK
2454
2455 PRINT_D(HOSTINF_DBG, "Handling edit station\n");
45102f83
LK
2456 wid.val = kmalloc(wid.size, GFP_KERNEL);
2457 if (!wid.val)
24db713f 2458 goto ERRORHANDLER;
c5c77ba1 2459
45102f83 2460 pu8CurrByte = wid.val;
c5c77ba1
JK
2461 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2462
45102f83 2463 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2464 get_id_from_handler(hif_drv));
31390eec 2465 if (result)
c5c77ba1 2466 PRINT_ER("Failed to send edit station config packet\n");
c5c77ba1 2467
24db713f 2468ERRORHANDLER:
969effe9 2469 kfree(pstrStationParam->pu8Rates);
45102f83 2470 kfree(wid.val);
c5c77ba1 2471}
c5c77ba1 2472
a4ab1ade 2473static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
2f9c03f5 2474 struct remain_ch *pstrHostIfRemainOnChan)
c5c77ba1 2475{
31390eec 2476 s32 result = 0;
63d03e47 2477 u8 u8remain_on_chan_flag;
45102f83 2478 struct wid wid;
c5c77ba1 2479
a4ab1ade
TC
2480 if (!hif_drv->u8RemainOnChan_pendingreq) {
2481 hif_drv->strHostIfRemainOnChan.pVoid = pstrHostIfRemainOnChan->pVoid;
2482 hif_drv->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired;
2483 hif_drv->strHostIfRemainOnChan.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady;
2484 hif_drv->strHostIfRemainOnChan.u16Channel = pstrHostIfRemainOnChan->u16Channel;
2485 hif_drv->strHostIfRemainOnChan.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID;
c5c77ba1 2486 } else {
a4ab1ade 2487 pstrHostIfRemainOnChan->u16Channel = hif_drv->strHostIfRemainOnChan.u16Channel;
c5c77ba1
JK
2488 }
2489
91109e11 2490 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
c5c77ba1 2491 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n");
a4ab1ade 2492 hif_drv->u8RemainOnChan_pendingreq = 1;
31390eec 2493 result = -EBUSY;
24db713f 2494 goto ERRORHANDLER;
c5c77ba1 2495 }
a4ab1ade 2496 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
c5c77ba1 2497 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n");
31390eec 2498 result = -EBUSY;
24db713f 2499 goto ERRORHANDLER;
c5c77ba1
JK
2500 }
2501
c5c77ba1
JK
2502 if (g_obtainingIP || connecting) {
2503 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
31390eec 2504 result = -EBUSY;
24db713f 2505 goto ERRORHANDLER;
c5c77ba1 2506 }
c5c77ba1
JK
2507
2508 PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel);
2509
72ed4dc7 2510 u8remain_on_chan_flag = true;
45102f83
LK
2511 wid.id = (u16)WID_REMAIN_ON_CHAN;
2512 wid.type = WID_STR;
2513 wid.size = 2;
2514 wid.val = kmalloc(wid.size, GFP_KERNEL);
2515 if (!wid.val) {
31390eec 2516 result = -ENOMEM;
24db713f
LK
2517 goto ERRORHANDLER;
2518 }
c5c77ba1 2519
45102f83
LK
2520 wid.val[0] = u8remain_on_chan_flag;
2521 wid.val[1] = (s8)pstrHostIfRemainOnChan->u16Channel;
c5c77ba1 2522
45102f83 2523 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2524 get_id_from_handler(hif_drv));
31390eec 2525 if (result != 0)
c5c77ba1 2526 PRINT_ER("Failed to set remain on channel\n");
c5c77ba1 2527
24db713f 2528ERRORHANDLER:
c5c77ba1
JK
2529 {
2530 P2P_LISTEN_STATE = 1;
a4ab1ade
TC
2531 hif_drv->hRemainOnChannel.data = (unsigned long)hif_drv;
2532 mod_timer(&hif_drv->hRemainOnChannel,
9eb06643
GKH
2533 jiffies +
2534 msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration));
c5c77ba1 2535
a4ab1ade
TC
2536 if (hif_drv->strHostIfRemainOnChan.pRemainOnChanReady)
2537 hif_drv->strHostIfRemainOnChan.pRemainOnChanReady(hif_drv->strHostIfRemainOnChan.pVoid);
c5c77ba1 2538
a4ab1ade
TC
2539 if (hif_drv->u8RemainOnChan_pendingreq)
2540 hif_drv->u8RemainOnChan_pendingreq = 0;
c5c77ba1 2541 }
31390eec
LK
2542
2543 return result;
c5c77ba1
JK
2544}
2545
a4ab1ade 2546static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
bc37c5df 2547 struct reg_frame *pstrHostIfRegisterFrame)
c5c77ba1 2548{
31390eec 2549 s32 result = 0;
45102f83 2550 struct wid wid;
63d03e47 2551 u8 *pu8CurrByte;
c5c77ba1
JK
2552
2553 PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType);
2554
45102f83
LK
2555 wid.id = (u16)WID_REGISTER_FRAME;
2556 wid.type = WID_STR;
2557 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2558 if (!wid.val)
24db713f 2559 return -ENOMEM;
c5c77ba1 2560
45102f83 2561 pu8CurrByte = wid.val;
c5c77ba1
JK
2562
2563 *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg;
2564 *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid;
bafaa696
LK
2565 memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->u16FrameType,
2566 sizeof(u16));
c5c77ba1 2567
45102f83 2568 wid.size = sizeof(u16) + 2;
c5c77ba1 2569
45102f83 2570 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2571 get_id_from_handler(hif_drv));
31390eec 2572 if (result) {
c5c77ba1 2573 PRINT_ER("Failed to frame register config packet\n");
31390eec 2574 result = -EINVAL;
c5c77ba1
JK
2575 }
2576
31390eec 2577 return result;
c5c77ba1
JK
2578}
2579
a4ab1ade 2580static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv,
2f9c03f5 2581 struct remain_ch *pstrHostIfRemainOnChan)
c5c77ba1 2582{
63d03e47 2583 u8 u8remain_on_chan_flag;
45102f83 2584 struct wid wid;
31390eec 2585 s32 result = 0;
c5c77ba1
JK
2586
2587 PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n");
2588
c5c77ba1 2589 if (P2P_LISTEN_STATE) {
72ed4dc7 2590 u8remain_on_chan_flag = false;
45102f83
LK
2591 wid.id = (u16)WID_REMAIN_ON_CHAN;
2592 wid.type = WID_STR;
2593 wid.size = 2;
2594 wid.val = kmalloc(wid.size, GFP_KERNEL);
c5c77ba1 2595
45102f83 2596 if (!wid.val)
c5c77ba1 2597 PRINT_ER("Failed to allocate memory\n");
c5c77ba1 2598
45102f83
LK
2599 wid.val[0] = u8remain_on_chan_flag;
2600 wid.val[1] = FALSE_FRMWR_CHANNEL;
c5c77ba1 2601
45102f83 2602 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2603 get_id_from_handler(hif_drv));
31390eec 2604 if (result != 0) {
c5c77ba1
JK
2605 PRINT_ER("Failed to set remain on channel\n");
2606 goto _done_;
2607 }
2608
a4ab1ade
TC
2609 if (hif_drv->strHostIfRemainOnChan.pRemainOnChanExpired) {
2610 hif_drv->strHostIfRemainOnChan.pRemainOnChanExpired(hif_drv->strHostIfRemainOnChan.pVoid
c5c77ba1
JK
2611 , pstrHostIfRemainOnChan->u32ListenSessionID);
2612 }
2613 P2P_LISTEN_STATE = 0;
2614 } else {
2615 PRINT_D(GENERIC_DBG, "Not in listen state\n");
31390eec 2616 result = -EFAULT;
c5c77ba1
JK
2617 }
2618
2619_done_:
31390eec 2620 return result;
c5c77ba1
JK
2621}
2622
93dee8ee 2623static void ListenTimerCB(unsigned long arg)
c5c77ba1 2624{
31390eec 2625 s32 result = 0;
143eb95a 2626 struct host_if_msg msg;
a4ab1ade 2627 struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
ae4dfa57 2628
a4ab1ade 2629 del_timer(&hif_drv->hRemainOnChannel);
c5c77ba1 2630
143eb95a 2631 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 2632 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
a4ab1ade
TC
2633 msg.drv = hif_drv;
2634 msg.body.remain_on_ch.u32ListenSessionID = hif_drv->strHostIfRemainOnChan.u32ListenSessionID;
c5c77ba1 2635
31390eec
LK
2636 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2637 if (result)
24db713f 2638 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 2639}
c5c77ba1 2640
a4ab1ade 2641static void Handle_PowerManagement(struct host_if_drv *hif_drv,
5a008f1c 2642 struct power_mgmt_param *strPowerMgmtParam)
c5c77ba1 2643{
31390eec 2644 s32 result = 0;
45102f83 2645 struct wid wid;
ca356ada 2646 s8 s8PowerMode;
78c87591 2647
45102f83 2648 wid.id = (u16)WID_POWER_MANAGEMENT;
c5c77ba1 2649
047e6646 2650 if (strPowerMgmtParam->enabled)
c5c77ba1 2651 s8PowerMode = MIN_FAST_PS;
78174ada 2652 else
c5c77ba1 2653 s8PowerMode = NO_POWERSAVE;
c5c77ba1 2654 PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode);
45102f83
LK
2655 wid.val = &s8PowerMode;
2656 wid.size = sizeof(char);
c5c77ba1
JK
2657
2658 PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
2659
45102f83 2660 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2661 get_id_from_handler(hif_drv));
31390eec 2662 if (result)
c5c77ba1 2663 PRINT_ER("Failed to send power management config packet\n");
c5c77ba1
JK
2664}
2665
a4ab1ade 2666static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
641210ac 2667 struct set_multicast *strHostIfSetMulti)
c5c77ba1 2668{
31390eec 2669 s32 result = 0;
45102f83 2670 struct wid wid;
63d03e47 2671 u8 *pu8CurrByte;
c5c77ba1
JK
2672
2673 PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n");
2674
45102f83
LK
2675 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2676 wid.type = WID_BIN;
2677 wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2678 wid.val = kmalloc(wid.size, GFP_KERNEL);
2679 if (!wid.val)
24db713f 2680 goto ERRORHANDLER;
c5c77ba1 2681
45102f83 2682 pu8CurrByte = wid.val;
bae636eb
LK
2683 *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2684 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
2685 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
2686 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
c5c77ba1 2687
adab2f71
LK
2688 *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2689 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2690 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2691 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
c5c77ba1 2692
adab2f71
LK
2693 if ((strHostIfSetMulti->cnt) > 0)
2694 memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->cnt) * ETH_ALEN));
c5c77ba1 2695
45102f83 2696 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2697 get_id_from_handler(hif_drv));
31390eec 2698 if (result)
c5c77ba1 2699 PRINT_ER("Failed to send setup multicast config packet\n");
c5c77ba1 2700
24db713f 2701ERRORHANDLER:
45102f83 2702 kfree(wid.val);
c5c77ba1
JK
2703}
2704
a4ab1ade 2705static s32 Handle_AddBASession(struct host_if_drv *hif_drv,
54265472 2706 struct ba_session_info *strHostIfBASessionInfo)
c5c77ba1 2707{
31390eec 2708 s32 result = 0;
45102f83 2709 struct wid wid;
c5c77ba1
JK
2710 int AddbaTimeout = 100;
2711 char *ptr = NULL;
c5c77ba1 2712
03b2d5e7 2713 PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n",
c5c77ba1
JK
2714 strHostIfBASessionInfo->au8Bssid[0],
2715 strHostIfBASessionInfo->au8Bssid[1],
2716 strHostIfBASessionInfo->au8Bssid[2],
2717 strHostIfBASessionInfo->u16BufferSize,
2718 strHostIfBASessionInfo->u16SessionTimeout,
2719 strHostIfBASessionInfo->u8Ted);
2720
45102f83
LK
2721 wid.id = (u16)WID_11E_P_ACTION_REQ;
2722 wid.type = WID_STR;
2723 wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2724 wid.size = BLOCK_ACK_REQ_SIZE;
2725 ptr = wid.val;
c5c77ba1
JK
2726 *ptr++ = 0x14;
2727 *ptr++ = 0x3;
2728 *ptr++ = 0x0;
d00d2ba3 2729 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1
JK
2730 ptr += ETH_ALEN;
2731 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2732 *ptr++ = 1;
c5c77ba1
JK
2733 *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2734 *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF);
c5c77ba1
JK
2735 *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF);
2736 *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
c5c77ba1
JK
2737 *ptr++ = (AddbaTimeout & 0xFF);
2738 *ptr++ = ((AddbaTimeout >> 16) & 0xFF);
c5c77ba1 2739 *ptr++ = 8;
c5c77ba1
JK
2740 *ptr++ = 0;
2741
45102f83 2742 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2743 get_id_from_handler(hif_drv));
31390eec 2744 if (result)
c5c77ba1
JK
2745 PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
2746
45102f83
LK
2747 wid.id = (u16)WID_11E_P_ACTION_REQ;
2748 wid.type = WID_STR;
2749 wid.size = 15;
2750 ptr = wid.val;
c5c77ba1
JK
2751 *ptr++ = 15;
2752 *ptr++ = 7;
2753 *ptr++ = 0x2;
d00d2ba3 2754 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1 2755 ptr += ETH_ALEN;
c5c77ba1 2756 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2757 *ptr++ = 8;
c5c77ba1
JK
2758 *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2759 *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
c5c77ba1 2760 *ptr++ = 3;
45102f83 2761 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2762 get_id_from_handler(hif_drv));
c5c77ba1 2763
45102f83 2764 kfree(wid.val);
c5c77ba1 2765
31390eec 2766 return result;
c5c77ba1
JK
2767}
2768
a4ab1ade 2769static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv,
54265472 2770 struct ba_session_info *strHostIfBASessionInfo)
c5c77ba1 2771{
31390eec 2772 s32 result = 0;
45102f83 2773 struct wid wid;
c5c77ba1 2774 char *ptr = NULL;
c5c77ba1 2775
03b2d5e7 2776 PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n",
c5c77ba1
JK
2777 strHostIfBASessionInfo->au8Bssid[0],
2778 strHostIfBASessionInfo->au8Bssid[1],
2779 strHostIfBASessionInfo->au8Bssid[2],
2780 strHostIfBASessionInfo->u8Ted);
2781
45102f83
LK
2782 wid.id = (u16)WID_DEL_ALL_RX_BA;
2783 wid.type = WID_STR;
2784 wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2785 wid.size = BLOCK_ACK_REQ_SIZE;
2786 ptr = wid.val;
c5c77ba1
JK
2787 *ptr++ = 0x14;
2788 *ptr++ = 0x3;
2789 *ptr++ = 0x2;
d00d2ba3 2790 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1
JK
2791 ptr += ETH_ALEN;
2792 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2793 *ptr++ = 0;
ae4dfa57 2794 *ptr++ = 32;
c5c77ba1 2795
45102f83 2796 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2797 get_id_from_handler(hif_drv));
31390eec 2798 if (result)
c5c77ba1
JK
2799 PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
2800
45102f83 2801 kfree(wid.val);
c5c77ba1 2802
2d25af87 2803 up(&hif_sema_wait_response);
c5c77ba1 2804
31390eec 2805 return result;
c5c77ba1
JK
2806}
2807
1999bd52 2808static int hostIFthread(void *pvArg)
c5c77ba1 2809{
4e4467fd 2810 u32 u32Ret;
143eb95a 2811 struct host_if_msg msg;
a4ab1ade 2812 struct host_if_drv *hif_drv;
c5c77ba1 2813
143eb95a 2814 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
2815
2816 while (1) {
cb067dcf 2817 wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
a4ab1ade 2818 hif_drv = (struct host_if_drv *)msg.drv;
a9f812a6 2819 if (msg.id == HOST_IF_MSG_EXIT) {
c5c77ba1
JK
2820 PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
2821 break;
2822 }
2823
c5c77ba1
JK
2824 if ((!g_wilc_initialized)) {
2825 PRINT_D(GENERIC_DBG, "--WAIT--");
80e29c7a 2826 usleep_range(200 * 1000, 200 * 1000);
cb067dcf 2827 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
2828 continue;
2829 }
2830
91109e11
LK
2831 if (msg.id == HOST_IF_MSG_CONNECT &&
2832 hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
c5c77ba1 2833 PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
cb067dcf 2834 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
80e29c7a 2835 usleep_range(2 * 1000, 2 * 1000);
c5c77ba1
JK
2836 continue;
2837 }
2838
a9f812a6 2839 switch (msg.id) {
c5c77ba1
JK
2840 case HOST_IF_MSG_Q_IDLE:
2841 Handle_wait_msg_q_empty();
2842 break;
2843
2844 case HOST_IF_MSG_SCAN:
2482a79f 2845 Handle_Scan(msg.drv, &msg.body.scan_info);
c5c77ba1
JK
2846 break;
2847
2848 case HOST_IF_MSG_CONNECT:
2482a79f 2849 Handle_Connect(msg.drv, &msg.body.con_info);
c5c77ba1
JK
2850 break;
2851
c5c77ba1 2852 case HOST_IF_MSG_FLUSH_CONNECT:
2482a79f 2853 Handle_FlushConnect(msg.drv);
c5c77ba1
JK
2854 break;
2855
2856 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2482a79f 2857 Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info);
c5c77ba1
JK
2858 break;
2859
2860 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2482a79f 2861 Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info);
c5c77ba1
JK
2862 break;
2863
2864 case HOST_IF_MSG_KEY:
2482a79f 2865 Handle_Key(msg.drv, &msg.body.key_info);
c5c77ba1
JK
2866 break;
2867
2868 case HOST_IF_MSG_CFG_PARAMS:
2869
2482a79f 2870 Handle_CfgParam(msg.drv, &msg.body.cfg_info);
c5c77ba1
JK
2871 break;
2872
2873 case HOST_IF_MSG_SET_CHANNEL:
2482a79f 2874 Handle_SetChannel(msg.drv, &msg.body.channel_info);
c5c77ba1
JK
2875 break;
2876
2877 case HOST_IF_MSG_DISCONNECT:
2482a79f 2878 Handle_Disconnect(msg.drv);
c5c77ba1
JK
2879 break;
2880
2881 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
a4ab1ade 2882 del_timer(&hif_drv->hScanTimer);
c5c77ba1
JK
2883 PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
2884
2b9d5b48 2885 if (!linux_wlan_get_num_conn_ifcs())
c5c77ba1 2886 chip_sleep_manually(INFINITE_SLEEP_TIME);
c5c77ba1 2887
2482a79f 2888 Handle_ScanDone(msg.drv, SCAN_EVENT_DONE);
c5c77ba1 2889
a4ab1ade 2890 if (hif_drv->u8RemainOnChan_pendingreq)
2482a79f 2891 Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
2892
2893 break;
2894
2895 case HOST_IF_MSG_GET_RSSI:
2482a79f 2896 Handle_GetRssi(msg.drv);
c5c77ba1
JK
2897 break;
2898
2899 case HOST_IF_MSG_GET_LINKSPEED:
2482a79f 2900 Handle_GetLinkspeed(msg.drv);
c5c77ba1
JK
2901 break;
2902
2903 case HOST_IF_MSG_GET_STATISTICS:
03e7b9c4 2904 Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data);
c5c77ba1
JK
2905 break;
2906
2907 case HOST_IF_MSG_GET_CHNL:
2482a79f 2908 Handle_GetChnl(msg.drv);
c5c77ba1
JK
2909 break;
2910
c5c77ba1 2911 case HOST_IF_MSG_ADD_BEACON:
2482a79f 2912 Handle_AddBeacon(msg.drv, &msg.body.beacon_info);
c5c77ba1
JK
2913 break;
2914
2915 case HOST_IF_MSG_DEL_BEACON:
2482a79f 2916 Handle_DelBeacon(msg.drv);
c5c77ba1
JK
2917 break;
2918
2919 case HOST_IF_MSG_ADD_STATION:
2482a79f 2920 Handle_AddStation(msg.drv, &msg.body.add_sta_info);
c5c77ba1
JK
2921 break;
2922
2923 case HOST_IF_MSG_DEL_STATION:
2482a79f 2924 Handle_DelStation(msg.drv, &msg.body.del_sta_info);
c5c77ba1
JK
2925 break;
2926
2927 case HOST_IF_MSG_EDIT_STATION:
2482a79f 2928 Handle_EditStation(msg.drv, &msg.body.edit_sta_info);
c5c77ba1
JK
2929 break;
2930
2931 case HOST_IF_MSG_GET_INACTIVETIME:
2482a79f 2932 Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info);
c5c77ba1
JK
2933 break;
2934
c5c77ba1
JK
2935 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2936 PRINT_D(HOSTINF_DBG, "Scan Timeout\n");
2937
2482a79f 2938 Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED);
c5c77ba1
JK
2939 break;
2940
2941 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
03b2d5e7 2942 PRINT_D(HOSTINF_DBG, "Connect Timeout\n");
2482a79f 2943 Handle_ConnectTimeout(msg.drv);
c5c77ba1
JK
2944 break;
2945
2946 case HOST_IF_MSG_POWER_MGMT:
2482a79f 2947 Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info);
c5c77ba1
JK
2948 break;
2949
2950 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2482a79f 2951 Handle_SetWfiDrvHandler(msg.drv,
5e4377e6 2952 &msg.body.drv);
c5c77ba1
JK
2953 break;
2954
2955 case HOST_IF_MSG_SET_OPERATION_MODE:
2482a79f 2956 Handle_SetOperationMode(msg.drv, &msg.body.mode);
c5c77ba1
JK
2957 break;
2958
2959 case HOST_IF_MSG_SET_IPADDRESS:
2960 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
78675be5 2961 Handle_set_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
c5c77ba1
JK
2962 break;
2963
2964 case HOST_IF_MSG_GET_IPADDRESS:
2965 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
78675be5 2966 Handle_get_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
c5c77ba1
JK
2967 break;
2968
c5c77ba1 2969 case HOST_IF_MSG_SET_MAC_ADDRESS:
2482a79f 2970 Handle_SetMacAddress(msg.drv, &msg.body.set_mac_info);
c5c77ba1
JK
2971 break;
2972
c5c77ba1 2973 case HOST_IF_MSG_GET_MAC_ADDRESS:
2482a79f 2974 Handle_GetMacAddress(msg.drv, &msg.body.get_mac_info);
c5c77ba1
JK
2975 break;
2976
c5c77ba1
JK
2977 case HOST_IF_MSG_REMAIN_ON_CHAN:
2978 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n");
2482a79f 2979 Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
2980 break;
2981
2982 case HOST_IF_MSG_REGISTER_FRAME:
2983 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n");
2482a79f 2984 Handle_RegisterFrame(msg.drv, &msg.body.reg_frame);
c5c77ba1
JK
2985 break;
2986
2987 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2482a79f 2988 Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
2989 break;
2990
c5c77ba1
JK
2991 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2992 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n");
2482a79f 2993 Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info);
c5c77ba1
JK
2994 break;
2995
c5c77ba1 2996 case HOST_IF_MSG_ADD_BA_SESSION:
2482a79f 2997 Handle_AddBASession(msg.drv, &msg.body.session_info);
c5c77ba1
JK
2998 break;
2999
3000 case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
2482a79f 3001 Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info);
c5c77ba1
JK
3002 break;
3003
3004 case HOST_IF_MSG_DEL_ALL_STA:
2482a79f 3005 Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info);
c5c77ba1
JK
3006 break;
3007
3008 default:
03b2d5e7 3009 PRINT_ER("[Host Interface] undefined Received Msg ID\n");
c5c77ba1
JK
3010 break;
3011 }
3012 }
3013
3014 PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n");
834e0cb0 3015 up(&hif_sema_thread);
1999bd52 3016 return 0;
c5c77ba1
JK
3017}
3018
93dee8ee 3019static void TimerCB_Scan(unsigned long arg)
c5c77ba1 3020{
93dee8ee 3021 void *pvArg = (void *)arg;
143eb95a 3022 struct host_if_msg msg;
c5c77ba1 3023
143eb95a 3024 memset(&msg, 0, sizeof(struct host_if_msg));
2482a79f 3025 msg.drv = pvArg;
a9f812a6 3026 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
c5c77ba1 3027
cb067dcf 3028 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
3029}
3030
93dee8ee 3031static void TimerCB_Connect(unsigned long arg)
c5c77ba1 3032{
93dee8ee 3033 void *pvArg = (void *)arg;
143eb95a 3034 struct host_if_msg msg;
c5c77ba1 3035
143eb95a 3036 memset(&msg, 0, sizeof(struct host_if_msg));
2482a79f 3037 msg.drv = pvArg;
a9f812a6 3038 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
c5c77ba1 3039
cb067dcf 3040 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
3041}
3042
a4ab1ade 3043s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
c5c77ba1 3044{
45102f83 3045 struct wid wid;
c5c77ba1 3046
45102f83
LK
3047 wid.id = (u16)WID_REMOVE_KEY;
3048 wid.type = WID_STR;
3049 wid.val = (s8 *)pu8StaAddress;
3050 wid.size = 6;
c5c77ba1 3051
b68d820b 3052 return 0;
c5c77ba1
JK
3053}
3054
a4ab1ade 3055int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
c5c77ba1 3056{
9e5e8b44 3057 int result = 0;
143eb95a 3058 struct host_if_msg msg;
c5c77ba1 3059
a4ab1ade 3060 if (!hif_drv) {
9e5e8b44 3061 result = -EFAULT;
24db713f 3062 PRINT_ER("Failed to send setup multicast config packet\n");
9e5e8b44 3063 return result;
24db713f 3064 }
c5c77ba1 3065
143eb95a 3066 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3067
a9f812a6 3068 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3069 msg.body.key_info.type = WEP;
0d17e382 3070 msg.body.key_info.action = REMOVEKEY;
a4ab1ade 3071 msg.drv = hif_drv;
73b2e381 3072 msg.body.key_info.attr.wep.index = index;
c5c77ba1 3073
cb067dcf 3074 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
9e5e8b44 3075 if (result)
03b2d5e7 3076 PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
a4ab1ade 3077 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3078
9e5e8b44 3079 return result;
c5c77ba1
JK
3080}
3081
df8b4830 3082int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index)
c5c77ba1 3083{
5b41c7c9 3084 int result = 0;
143eb95a 3085 struct host_if_msg msg;
c5c77ba1 3086
a4ab1ade 3087 if (!hif_drv) {
31390eec 3088 result = -EFAULT;
24db713f 3089 PRINT_ER("driver is null\n");
31390eec 3090 return result;
24db713f 3091 }
c5c77ba1 3092
143eb95a 3093 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3094
a9f812a6 3095 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3096 msg.body.key_info.type = WEP;
0d17e382 3097 msg.body.key_info.action = DEFAULTKEY;
a4ab1ade 3098 msg.drv = hif_drv;
e91d0349 3099 msg.body.key_info.attr.wep.index = index;
c5c77ba1 3100
31390eec
LK
3101 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3102 if (result)
c5c77ba1 3103 PRINT_ER("Error in sending message queue : Default key index\n");
a4ab1ade 3104 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3105
31390eec 3106 return result;
c5c77ba1
JK
3107}
3108
a4ab1ade
TC
3109s32 host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
3110 const u8 *pu8WepKey,
3111 u8 u8WepKeylen,
3112 u8 u8Keyidx)
c5c77ba1 3113{
31390eec 3114 s32 result = 0;
143eb95a 3115 struct host_if_msg msg;
c5c77ba1 3116
a4ab1ade 3117 if (!hif_drv) {
24db713f 3118 PRINT_ER("driver is null\n");
77178807 3119 return -EFAULT;
24db713f 3120 }
c5c77ba1 3121
143eb95a 3122 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3123
a9f812a6 3124 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3125 msg.body.key_info.type = WEP;
0d17e382 3126 msg.body.key_info.action = ADDKEY;
a4ab1ade 3127 msg.drv = hif_drv;
73b2e381
LK
3128 msg.body.key_info.attr.wep.key = kmalloc(u8WepKeylen, GFP_KERNEL);
3129 memcpy(msg.body.key_info.attr.wep.key, pu8WepKey, u8WepKeylen);
3130 msg.body.key_info.attr.wep.key_len = (u8WepKeylen);
3131 msg.body.key_info.attr.wep.index = u8Keyidx;
c5c77ba1 3132
31390eec
LK
3133 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3134 if (result)
c5c77ba1 3135 PRINT_ER("Error in sending message queue :WEP Key\n");
a4ab1ade 3136 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3137
31390eec 3138 return result;
c5c77ba1
JK
3139}
3140
a4ab1ade
TC
3141s32 host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
3142 const u8 *pu8WepKey,
3143 u8 u8WepKeylen,
3144 u8 u8Keyidx,
3145 u8 u8mode,
3146 enum AUTHTYPE tenuAuth_type)
c5c77ba1 3147{
31390eec 3148 s32 result = 0;
143eb95a 3149 struct host_if_msg msg;
63d03e47 3150 u8 i;
c5c77ba1 3151
a4ab1ade 3152 if (!hif_drv) {
24db713f 3153 PRINT_ER("driver is null\n");
77178807 3154 return -EFAULT;
24db713f 3155 }
c5c77ba1 3156
143eb95a 3157 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
3158
3159 if (INFO) {
3160 for (i = 0; i < u8WepKeylen; i++)
3161 PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", pu8WepKey[i]);
3162 }
a9f812a6 3163 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3164 msg.body.key_info.type = WEP;
0d17e382 3165 msg.body.key_info.action = ADDKEY_AP;
a4ab1ade 3166 msg.drv = hif_drv;
73b2e381
LK
3167 msg.body.key_info.attr.wep.key = kmalloc(u8WepKeylen, GFP_KERNEL);
3168 memcpy(msg.body.key_info.attr.wep.key, pu8WepKey, (u8WepKeylen));
3169 msg.body.key_info.attr.wep.key_len = (u8WepKeylen);
3170 msg.body.key_info.attr.wep.index = u8Keyidx;
3171 msg.body.key_info.attr.wep.mode = u8mode;
3172 msg.body.key_info.attr.wep.auth_type = tenuAuth_type;
ae4dfa57 3173
31390eec 3174 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3175
31390eec 3176 if (result)
c5c77ba1 3177 PRINT_ER("Error in sending message queue :WEP Key\n");
a4ab1ade 3178 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3179
31390eec 3180 return result;
c5c77ba1 3181}
108b3439 3182
a4ab1ade
TC
3183s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
3184 u8 u8PtkKeylen, const u8 *mac_addr,
3185 const u8 *pu8RxMic, const u8 *pu8TxMic,
3186 u8 mode, u8 u8Ciphermode, u8 u8Idx)
c5c77ba1 3187{
31390eec 3188 s32 result = 0;
143eb95a 3189 struct host_if_msg msg;
63d03e47 3190 u8 u8KeyLen = u8PtkKeylen;
4e4467fd 3191 u32 i;
78c87591 3192
a4ab1ade 3193 if (!hif_drv) {
24db713f 3194 PRINT_ER("driver is null\n");
77178807 3195 return -EFAULT;
24db713f 3196 }
91109e11
LK
3197
3198 if (pu8RxMic)
c5c77ba1 3199 u8KeyLen += RX_MIC_KEY_LEN;
91109e11
LK
3200
3201 if (pu8TxMic)
c5c77ba1 3202 u8KeyLen += TX_MIC_KEY_LEN;
c5c77ba1 3203
143eb95a 3204 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3205
a9f812a6 3206 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3207 msg.body.key_info.type = WPAPtk;
c5c77ba1 3208 if (mode == AP_MODE) {
0d17e382 3209 msg.body.key_info.action = ADDKEY_AP;
e2dfbac5 3210 msg.body.key_info.attr.wpa.index = u8Idx;
c5c77ba1 3211 }
c5c77ba1 3212 if (mode == STATION_MODE)
0d17e382 3213 msg.body.key_info.action = ADDKEY;
c5c77ba1 3214
124968fc
LK
3215 msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
3216 memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
c5c77ba1 3217
91109e11 3218 if (pu8RxMic) {
124968fc 3219 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
c5c77ba1
JK
3220 if (INFO) {
3221 for (i = 0; i < RX_MIC_KEY_LEN; i++)
3222 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
3223 }
3224 }
91109e11 3225 if (pu8TxMic) {
124968fc 3226 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
c5c77ba1
JK
3227 if (INFO) {
3228 for (i = 0; i < TX_MIC_KEY_LEN; i++)
3229 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
3230 }
3231 }
3232
6acf2919 3233 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
248080aa 3234 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
7b2ebb28 3235 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
a4ab1ade 3236 msg.drv = hif_drv;
c5c77ba1 3237
31390eec 3238 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3239
31390eec 3240 if (result)
c5c77ba1
JK
3241 PRINT_ER("Error in sending message queue: PTK Key\n");
3242
a4ab1ade 3243 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3244
31390eec 3245 return result;
c5c77ba1
JK
3246}
3247
a4ab1ade
TC
3248s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
3249 u8 u8GtkKeylen, u8 u8KeyIdx,
3250 u32 u32KeyRSClen, const u8 *KeyRSC,
3251 const u8 *pu8RxMic, const u8 *pu8TxMic,
3252 u8 mode, u8 u8Ciphermode)
c5c77ba1 3253{
31390eec 3254 s32 result = 0;
143eb95a 3255 struct host_if_msg msg;
63d03e47 3256 u8 u8KeyLen = u8GtkKeylen;
c5c77ba1 3257
a4ab1ade 3258 if (!hif_drv) {
24db713f 3259 PRINT_ER("driver is null\n");
77178807 3260 return -EFAULT;
24db713f 3261 }
143eb95a 3262 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3263
91109e11 3264 if (pu8RxMic)
c5c77ba1 3265 u8KeyLen += RX_MIC_KEY_LEN;
91109e11
LK
3266
3267 if (pu8TxMic)
c5c77ba1 3268 u8KeyLen += TX_MIC_KEY_LEN;
91109e11
LK
3269
3270 if (KeyRSC) {
0e74c009
LK
3271 msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
3272 memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
c5c77ba1
JK
3273 }
3274
a9f812a6 3275 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3276 msg.body.key_info.type = WPARxGtk;
a4ab1ade 3277 msg.drv = hif_drv;
c5c77ba1 3278
c5c77ba1 3279 if (mode == AP_MODE) {
0d17e382 3280 msg.body.key_info.action = ADDKEY_AP;
7b2ebb28 3281 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
c5c77ba1 3282 }
c5c77ba1 3283 if (mode == STATION_MODE)
0d17e382 3284 msg.body.key_info.action = ADDKEY;
c5c77ba1 3285
124968fc
LK
3286 msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
3287 memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
c5c77ba1 3288
d1666e2a
LK
3289 if (pu8RxMic)
3290 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic,
3291 RX_MIC_KEY_LEN);
91109e11 3292
d1666e2a
LK
3293 if (pu8TxMic)
3294 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic,
3295 TX_MIC_KEY_LEN);
c5c77ba1 3296
e2dfbac5 3297 msg.body.key_info.attr.wpa.index = u8KeyIdx;
6acf2919 3298 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
dacc594d 3299 msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
c5c77ba1 3300
31390eec
LK
3301 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3302 if (result)
c5c77ba1 3303 PRINT_ER("Error in sending message queue: RX GTK\n");
ae4dfa57 3304
a4ab1ade 3305 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3306
31390eec 3307 return result;
c5c77ba1 3308}
c5c77ba1 3309
a4ab1ade 3310s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
c5c77ba1 3311{
31390eec 3312 s32 result = 0;
143eb95a 3313 struct host_if_msg msg;
4e4467fd 3314 u32 i;
c5c77ba1 3315
a4ab1ade 3316 if (!hif_drv) {
24db713f 3317 PRINT_ER("driver is null\n");
77178807 3318 return -EFAULT;
24db713f 3319 }
c5c77ba1 3320
143eb95a 3321 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3322
a9f812a6 3323 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3324 msg.body.key_info.type = PMKSA;
0d17e382 3325 msg.body.key_info.action = ADDKEY;
a4ab1ade 3326 msg.drv = hif_drv;
c5c77ba1
JK
3327
3328 for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
8c8360b3
LK
3329 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3330 &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN);
3331 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3332 &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN);
c5c77ba1
JK
3333 }
3334
31390eec
LK
3335 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3336 if (result)
c5c77ba1
JK
3337 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3338
31390eec 3339 return result;
c5c77ba1
JK
3340}
3341
a4ab1ade
TC
3342s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
3343 u8 *pu8PmkidInfoArray,
3344 u32 u32PmkidInfoLen)
c5c77ba1 3345{
45102f83 3346 struct wid wid;
c5c77ba1 3347
45102f83
LK
3348 wid.id = (u16)WID_PMKID_INFO;
3349 wid.type = WID_STR;
3350 wid.size = u32PmkidInfoLen;
3351 wid.val = pu8PmkidInfoArray;
c5c77ba1 3352
b68d820b 3353 return 0;
c5c77ba1
JK
3354}
3355
a4ab1ade
TC
3356s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3357 u8 *pu8PassPhrase,
3358 u8 u8Psklength)
c5c77ba1 3359{
45102f83 3360 struct wid wid;
c5c77ba1 3361
c5c77ba1 3362 if ((u8Psklength > 7) && (u8Psklength < 65)) {
45102f83
LK
3363 wid.id = (u16)WID_11I_PSK;
3364 wid.type = WID_STR;
3365 wid.val = pu8PassPhrase;
3366 wid.size = u8Psklength;
c5c77ba1
JK
3367 }
3368
b68d820b 3369 return 0;
c5c77ba1 3370}
ae4dfa57 3371
a4ab1ade 3372s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3373{
31390eec 3374 s32 result = 0;
143eb95a 3375 struct host_if_msg msg;
c5c77ba1 3376
143eb95a 3377 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3378
a9f812a6 3379 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
a5848695 3380 msg.body.get_mac_info.u8MacAddress = pu8MacAddress;
a4ab1ade 3381 msg.drv = hif_drv;
ae4dfa57 3382
31390eec
LK
3383 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3384 if (result) {
c5c77ba1 3385 PRINT_ER("Failed to send get mac address\n");
e6e12661 3386 return -EFAULT;
c5c77ba1
JK
3387 }
3388
2d25af87 3389 down(&hif_sema_wait_response);
31390eec 3390 return result;
c5c77ba1
JK
3391}
3392
a4ab1ade 3393s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3394{
31390eec 3395 s32 result = 0;
143eb95a 3396 struct host_if_msg msg;
c5c77ba1
JK
3397
3398 PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
3399
143eb95a 3400 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3401 msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
15326e28 3402 memcpy(msg.body.set_mac_info.u8MacAddress, pu8MacAddress, ETH_ALEN);
a4ab1ade 3403 msg.drv = hif_drv;
c5c77ba1 3404
31390eec
LK
3405 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3406 if (result)
c5c77ba1 3407 PRINT_ER("Failed to send message queue: Set mac address\n");
c5c77ba1 3408
31390eec 3409 return result;
c5c77ba1
JK
3410}
3411
a4ab1ade
TC
3412s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3413 u8 *pu8PassPhrase, u8 u8Psklength)
c5c77ba1 3414{
45102f83 3415 struct wid wid;
c5c77ba1 3416
45102f83
LK
3417 wid.id = (u16)WID_11I_PSK;
3418 wid.type = WID_STR;
3419 wid.size = u8Psklength;
3420 wid.val = pu8PassPhrase;
c5c77ba1 3421
b68d820b 3422 return 0;
c5c77ba1
JK
3423}
3424
a4ab1ade 3425s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
c5c77ba1 3426{
45102f83 3427 struct wid wid;
c5c77ba1 3428
45102f83
LK
3429 wid.id = (u16)WID_START_SCAN_REQ;
3430 wid.type = WID_CHAR;
3431 wid.val = (s8 *)&scanSource;
3432 wid.size = sizeof(char);
c5c77ba1 3433
b68d820b 3434 return 0;
c5c77ba1
JK
3435}
3436
a4ab1ade 3437s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
c5c77ba1 3438{
45102f83 3439 struct wid wid;
c5c77ba1 3440
45102f83
LK
3441 wid.id = (u16)WID_START_SCAN_REQ;
3442 wid.type = WID_CHAR;
3443 wid.val = (s8 *)pu8ScanSource;
3444 wid.size = sizeof(char);
c5c77ba1 3445
b68d820b 3446 return 0;
c5c77ba1
JK
3447}
3448
a4ab1ade
TC
3449s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
3450 const u8 *pu8ssid, size_t ssidLen,
3451 const u8 *pu8IEs, size_t IEsLen,
3452 wilc_connect_result pfConnectResult, void *pvUserArg,
3453 u8 u8security, enum AUTHTYPE tenuAuth_type,
3454 u8 u8channel, void *pJoinParams)
c5c77ba1 3455{
31390eec 3456 s32 result = 0;
143eb95a 3457 struct host_if_msg msg;
c5c77ba1 3458
91109e11 3459 if (!hif_drv || !pfConnectResult) {
24db713f 3460 PRINT_ER("Driver is null\n");
77178807 3461 return -EFAULT;
24db713f 3462 }
c5c77ba1 3463
91109e11 3464 if (!pJoinParams) {
c5c77ba1 3465 PRINT_ER("Unable to Join - JoinParams is NULL\n");
24db713f 3466 return -EFAULT;
c5c77ba1 3467 }
24db713f 3468
143eb95a 3469 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3470
a9f812a6 3471 msg.id = HOST_IF_MSG_CONNECT;
c5c77ba1 3472
a64fd677 3473 msg.body.con_info.security = u8security;
61b4fd02 3474 msg.body.con_info.auth_type = tenuAuth_type;
0d1527e6 3475 msg.body.con_info.ch = u8channel;
6abcc11d 3476 msg.body.con_info.result = pfConnectResult;
8f38db89 3477 msg.body.con_info.arg = pvUserArg;
f2bed2ca 3478 msg.body.con_info.params = pJoinParams;
a4ab1ade 3479 msg.drv = hif_drv ;
c5c77ba1 3480
91109e11 3481 if (pu8bssid) {
9254db07
LK
3482 msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
3483 memcpy(msg.body.con_info.bssid, pu8bssid, 6);
c5c77ba1
JK
3484 }
3485
91109e11 3486 if (pu8ssid) {
8b3c9fa6 3487 msg.body.con_info.ssid_len = ssidLen;
f7bbd9cf
LK
3488 msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL);
3489 memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen);
c5c77ba1
JK
3490 }
3491
91109e11 3492 if (pu8IEs) {
b59d5c5b 3493 msg.body.con_info.ies_len = IEsLen;
2ea158c4
LK
3494 msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3495 memcpy(msg.body.con_info.ies, pu8IEs, IEsLen);
c5c77ba1 3496 }
a4ab1ade
TC
3497 if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING)
3498 hif_drv->enuHostIFstate = HOST_IF_CONNECTING;
78174ada 3499 else
a4ab1ade 3500 PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate);
c5c77ba1 3501
31390eec
LK
3502 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3503 if (result) {
c5c77ba1 3504 PRINT_ER("Failed to send message queue: Set join request\n");
24db713f 3505 return -EFAULT;
c5c77ba1
JK
3506 }
3507
a4ab1ade
TC
3508 hif_drv->hConnectTimer.data = (unsigned long)hif_drv;
3509 mod_timer(&hif_drv->hConnectTimer,
9eb06643 3510 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
c5c77ba1 3511
31390eec 3512 return result;
c5c77ba1
JK
3513}
3514
a4ab1ade 3515s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
c5c77ba1 3516{
31390eec 3517 s32 result = 0;
143eb95a 3518 struct host_if_msg msg;
c5c77ba1 3519
77178807
LK
3520 if (!join_req)
3521 return -EFAULT;
c5c77ba1 3522
a4ab1ade 3523 if (!hif_drv) {
24db713f 3524 PRINT_ER("Driver is null\n");
77178807 3525 return -EFAULT;
24db713f 3526 }
c5c77ba1 3527
a9f812a6 3528 msg.id = HOST_IF_MSG_FLUSH_CONNECT;
a4ab1ade 3529 msg.drv = hif_drv;
c5c77ba1 3530
31390eec
LK
3531 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3532 if (result) {
c5c77ba1 3533 PRINT_ER("Failed to send message queue: Flush join request\n");
24db713f 3534 return -EFAULT;
c5c77ba1
JK
3535 }
3536
31390eec 3537 return result;
c5c77ba1
JK
3538}
3539
a4ab1ade 3540s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
c5c77ba1 3541{
31390eec 3542 s32 result = 0;
143eb95a 3543 struct host_if_msg msg;
c5c77ba1 3544
a4ab1ade 3545 if (!hif_drv) {
24db713f
LK
3546 PRINT_ER("Driver is null\n");
3547 return -EFAULT;
c5c77ba1
JK
3548 }
3549
143eb95a 3550 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3551
a9f812a6 3552 msg.id = HOST_IF_MSG_DISCONNECT;
a4ab1ade 3553 msg.drv = hif_drv;
c5c77ba1 3554
31390eec
LK
3555 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3556 if (result)
c5c77ba1 3557 PRINT_ER("Failed to send message queue: disconnect\n");
ae4dfa57 3558
a4ab1ade 3559 down(&hif_drv->hSemTestDisconnectBlock);
c5c77ba1 3560
31390eec 3561 return result;
c5c77ba1
JK
3562}
3563
a4ab1ade 3564s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
c5c77ba1 3565{
45102f83 3566 struct wid wid;
c5c77ba1 3567
45102f83
LK
3568 wid.id = (u16)WID_DISCONNECT;
3569 wid.type = WID_CHAR;
3570 wid.val = (s8 *)&assoc_id;
3571 wid.size = sizeof(char);
c5c77ba1 3572
b68d820b 3573 return 0;
c5c77ba1
JK
3574}
3575
8c8360b3
LK
3576s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
3577 u8 *pu8AssocReqInfo,
3578 u32 u32AssocReqInfoLen)
c5c77ba1 3579{
45102f83 3580 struct wid wid;
c5c77ba1 3581
45102f83
LK
3582 wid.id = (u16)WID_ASSOC_REQ_INFO;
3583 wid.type = WID_STR;
3584 wid.val = pu8AssocReqInfo;
3585 wid.size = u32AssocReqInfoLen;
c5c77ba1 3586
b68d820b 3587 return 0;
c5c77ba1
JK
3588}
3589
8c8360b3
LK
3590s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
3591 u8 *pu8AssocRespInfo,
3592 u32 u32MaxAssocRespInfoLen,
3593 u32 *pu32RcvdAssocRespInfoLen)
c5c77ba1 3594{
31390eec 3595 s32 result = 0;
45102f83 3596 struct wid wid;
c5c77ba1 3597
a4ab1ade 3598 if (!hif_drv) {
24db713f
LK
3599 PRINT_ER("Driver is null\n");
3600 return -EFAULT;
c5c77ba1
JK
3601 }
3602
45102f83
LK
3603 wid.id = (u16)WID_ASSOC_RES_INFO;
3604 wid.type = WID_STR;
3605 wid.val = pu8AssocRespInfo;
3606 wid.size = u32MaxAssocRespInfoLen;
c5c77ba1 3607
45102f83 3608 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 3609 get_id_from_handler(hif_drv));
31390eec 3610 if (result) {
c5c77ba1 3611 *pu32RcvdAssocRespInfoLen = 0;
24db713f
LK
3612 PRINT_ER("Failed to send association response config packet\n");
3613 return -EINVAL;
c5c77ba1 3614 } else {
45102f83 3615 *pu32RcvdAssocRespInfoLen = wid.size;
c5c77ba1
JK
3616 }
3617
31390eec 3618 return result;
c5c77ba1
JK
3619}
3620
8c8360b3
LK
3621s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
3622 u8 *pu8RxPowerLevel,
3623 u32 u32RxPowerLevelLen)
c5c77ba1 3624{
45102f83 3625 struct wid wid;
c5c77ba1 3626
45102f83
LK
3627 wid.id = (u16)WID_RX_POWER_LEVEL;
3628 wid.type = WID_STR;
3629 wid.val = pu8RxPowerLevel;
3630 wid.size = u32RxPowerLevelLen;
c5c77ba1 3631
b68d820b 3632 return 0;
c5c77ba1
JK
3633}
3634
a4ab1ade 3635int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
c5c77ba1 3636{
792fb25b 3637 int result;
143eb95a 3638 struct host_if_msg msg;
c5c77ba1 3639
a4ab1ade 3640 if (!hif_drv) {
24db713f
LK
3641 PRINT_ER("driver is null\n");
3642 return -EFAULT;
3643 }
c5c77ba1 3644
143eb95a 3645 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3646 msg.id = HOST_IF_MSG_SET_CHANNEL;
730ee059 3647 msg.body.channel_info.set_ch = channel;
a4ab1ade 3648 msg.drv = hif_drv;
c5c77ba1 3649
cb067dcf 3650 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
1ef58e42 3651 if (result) {
24db713f 3652 PRINT_ER("wilc mq send fail\n");
792fb25b 3653 return -EINVAL;
c5c77ba1
JK
3654 }
3655
792fb25b 3656 return 0;
c5c77ba1
JK
3657}
3658
244efb1f 3659int host_int_wait_msg_queue_idle(void)
c5c77ba1 3660{
6d6c9bbb 3661 int result = 0;
143eb95a 3662 struct host_if_msg msg;
c09389ac 3663
143eb95a 3664 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3665 msg.id = HOST_IF_MSG_Q_IDLE;
cb067dcf 3666 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
6d6c9bbb 3667 if (result) {
24db713f 3668 PRINT_ER("wilc mq send fail\n");
6d6c9bbb 3669 result = -EINVAL;
c5c77ba1
JK
3670 }
3671
2d25af87 3672 down(&hif_sema_wait_response);
c5c77ba1 3673
6d6c9bbb 3674 return result;
c5c77ba1
JK
3675}
3676
a4ab1ade 3677int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
c5c77ba1 3678{
a094101c 3679 int result = 0;
143eb95a 3680 struct host_if_msg msg;
c09389ac 3681
143eb95a 3682 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3683 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
a7f3b12f 3684 msg.body.drv.handler = get_id_from_handler(hif_drv);
a4ab1ade 3685 msg.drv = hif_drv;
c5c77ba1 3686
cb067dcf 3687 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a094101c 3688 if (result) {
24db713f 3689 PRINT_ER("wilc mq send fail\n");
a094101c 3690 result = -EINVAL;
c5c77ba1
JK
3691 }
3692
a094101c 3693 return result;
c5c77ba1
JK
3694}
3695
a4ab1ade 3696int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
c5c77ba1 3697{
a0c1ee0c 3698 int result = 0;
143eb95a 3699 struct host_if_msg msg;
c09389ac 3700
143eb95a 3701 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3702 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
49fb6f71 3703 msg.body.mode.u32Mode = mode;
a4ab1ade 3704 msg.drv = hif_drv;
c5c77ba1 3705
cb067dcf 3706 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a0c1ee0c 3707 if (result) {
24db713f 3708 PRINT_ER("wilc mq send fail\n");
a0c1ee0c 3709 result = -EINVAL;
c5c77ba1
JK
3710 }
3711
a0c1ee0c 3712 return result;
c5c77ba1
JK
3713}
3714
a4ab1ade 3715s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
c5c77ba1 3716{
31390eec 3717 s32 result = 0;
143eb95a 3718 struct host_if_msg msg;
c5c77ba1 3719
a4ab1ade 3720 if (!hif_drv) {
24db713f
LK
3721 PRINT_ER("driver is null\n");
3722 return -EFAULT;
c5c77ba1
JK
3723 }
3724
143eb95a 3725 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3726
a9f812a6 3727 msg.id = HOST_IF_MSG_GET_CHNL;
a4ab1ade 3728 msg.drv = hif_drv;
c5c77ba1 3729
31390eec
LK
3730 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3731 if (result)
24db713f 3732 PRINT_ER("wilc mq send fail\n");
a4ab1ade 3733 down(&hif_drv->hSemGetCHNL);
c5c77ba1 3734
95ebb0ff 3735 *pu8ChNo = ch_no;
c5c77ba1 3736
31390eec 3737 return result;
c5c77ba1
JK
3738}
3739
a4ab1ade
TC
3740s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
3741 const u8 *mac, u32 *pu32InactiveTime)
c5c77ba1 3742{
31390eec 3743 s32 result = 0;
143eb95a 3744 struct host_if_msg msg;
c5c77ba1 3745
a4ab1ade 3746 if (!hif_drv) {
24db713f
LK
3747 PRINT_ER("driver is null\n");
3748 return -EFAULT;
c5c77ba1
JK
3749 }
3750
143eb95a 3751 memset(&msg, 0, sizeof(struct host_if_msg));
8c8360b3 3752 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
c5c77ba1 3753
a9f812a6 3754 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
a4ab1ade 3755 msg.drv = hif_drv;
c5c77ba1 3756
31390eec
LK
3757 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3758 if (result)
c5c77ba1
JK
3759 PRINT_ER("Failed to send get host channel param's message queue ");
3760
a4ab1ade 3761 down(&hif_drv->hSemInactiveTime);
c5c77ba1 3762
ad26906f 3763 *pu32InactiveTime = inactive_time;
c5c77ba1 3764
31390eec 3765 return result;
c5c77ba1 3766}
108b3439 3767
a4ab1ade 3768s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
c5c77ba1 3769{
31390eec 3770 s32 result = 0;
45102f83 3771 struct wid wid;
c5c77ba1 3772
a4ab1ade 3773 if (!hif_drv) {
24db713f
LK
3774 PRINT_ER("driver is null\n");
3775 return -EFAULT;
c5c77ba1
JK
3776 }
3777
45102f83
LK
3778 wid.id = (u16)WID_MEMORY_ADDRESS;
3779 wid.type = WID_INT;
3780 wid.val = (s8 *)pu32TestMemAddr;
3781 wid.size = sizeof(u32);
c5c77ba1 3782
45102f83 3783 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 3784 get_id_from_handler(hif_drv));
ae4dfa57 3785
31390eec 3786 if (result) {
24db713f
LK
3787 PRINT_ER("Failed to get wid value\n");
3788 return -EINVAL;
c5c77ba1
JK
3789 } else {
3790 PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
c5c77ba1
JK
3791 }
3792
31390eec 3793 return result;
c5c77ba1
JK
3794}
3795
a4ab1ade 3796s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
c5c77ba1 3797{
31390eec 3798 s32 result = 0;
143eb95a 3799 struct host_if_msg msg;
c5c77ba1 3800
c09389ac 3801 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3802 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 3803 msg.drv = hif_drv;
c5c77ba1 3804
31390eec
LK
3805 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3806 if (result) {
c5c77ba1 3807 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3808 return -EFAULT;
c5c77ba1
JK
3809 }
3810
a4ab1ade 3811 down(&hif_drv->hSemGetRSSI);
c5c77ba1 3812
91109e11 3813 if (!ps8Rssi) {
c5c77ba1 3814 PRINT_ER("RSS pointer value is null");
e6e12661 3815 return -EFAULT;
c5c77ba1
JK
3816 }
3817
144b7b23 3818 *ps8Rssi = rssi;
c5c77ba1 3819
31390eec 3820 return result;
c5c77ba1
JK
3821}
3822
a4ab1ade 3823s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
c5c77ba1 3824{
143eb95a 3825 struct host_if_msg msg;
31390eec 3826 s32 result = 0;
c5c77ba1 3827
c09389ac 3828 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3829 msg.id = HOST_IF_MSG_GET_LINKSPEED;
a4ab1ade 3830 msg.drv = hif_drv;
c5c77ba1 3831
31390eec
LK
3832 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3833 if (result) {
c5c77ba1 3834 PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
e6e12661 3835 return -EFAULT;
c5c77ba1
JK
3836 }
3837
a4ab1ade 3838 down(&hif_drv->hSemGetLINKSPEED);
c5c77ba1 3839
91109e11 3840 if (!ps8lnkspd) {
c5c77ba1 3841 PRINT_ER("LINKSPEED pointer value is null");
e6e12661 3842 return -EFAULT;
c5c77ba1
JK
3843 }
3844
75327a02 3845 *ps8lnkspd = link_speed;
c5c77ba1 3846
31390eec 3847 return result;
c5c77ba1
JK
3848}
3849
a4ab1ade 3850s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
c5c77ba1 3851{
31390eec 3852 s32 result = 0;
143eb95a 3853 struct host_if_msg msg;
c5c77ba1 3854
c09389ac 3855 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3856 msg.id = HOST_IF_MSG_GET_STATISTICS;
e60831e9 3857 msg.body.data = (char *)pstrStatistics;
a4ab1ade 3858 msg.drv = hif_drv;
ae4dfa57 3859
31390eec
LK
3860 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3861 if (result) {
c5c77ba1 3862 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3863 return -EFAULT;
c5c77ba1
JK
3864 }
3865
2d25af87 3866 down(&hif_sema_wait_response);
31390eec 3867 return result;
c5c77ba1
JK
3868}
3869
a4ab1ade
TC
3870s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
3871 u8 u8ScanType, u8 *pu8ChnlFreqList,
3872 u8 u8ChnlListLen, const u8 *pu8IEs,
3873 size_t IEsLen, wilc_scan_result ScanResult,
3874 void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
c5c77ba1 3875{
31390eec 3876 s32 result = 0;
143eb95a 3877 struct host_if_msg msg;
c5c77ba1 3878
91109e11 3879 if (!hif_drv || !ScanResult) {
a4ab1ade 3880 PRINT_ER("hif_drv or ScanResult = NULL\n");
24db713f
LK
3881 return -EFAULT;
3882 }
c5c77ba1 3883
143eb95a 3884 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3885
a9f812a6 3886 msg.id = HOST_IF_MSG_SCAN;
c5c77ba1 3887
91109e11 3888 if (pstrHiddenNetwork) {
629b9ca0
LK
3889 msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
3890 msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
c5c77ba1
JK
3891
3892 } else
3893 PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
3894
a4ab1ade 3895 msg.drv = hif_drv;
42568898 3896 msg.body.scan_info.src = u8ScanSource;
1e276c88 3897 msg.body.scan_info.type = u8ScanType;
c17c6da6 3898 msg.body.scan_info.result = ScanResult;
5f2b50c8 3899 msg.body.scan_info.arg = pvUserArg;
4528bdb5 3900
f97bd9ca 3901 msg.body.scan_info.ch_list_len = u8ChnlListLen;
82eeb0ad
LK
3902 msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL);
3903 memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen);
c5c77ba1 3904
7b1f76cd 3905 msg.body.scan_info.ies_len = IEsLen;
d6f19aa5
LK
3906 msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3907 memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen);
c5c77ba1 3908
31390eec
LK
3909 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3910 if (result) {
24db713f
LK
3911 PRINT_ER("Error in sending message queue\n");
3912 return -EINVAL;
c5c77ba1
JK
3913 }
3914
c5c77ba1 3915 PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
a4ab1ade
TC
3916 hif_drv->hScanTimer.data = (unsigned long)hif_drv;
3917 mod_timer(&hif_drv->hScanTimer,
9eb06643 3918 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
c5c77ba1 3919
31390eec 3920 return result;
c5c77ba1 3921}
ae4dfa57 3922
a4ab1ade
TC
3923s32 hif_set_cfg(struct host_if_drv *hif_drv,
3924 struct cfg_param_val *pstrCfgParamVal)
c5c77ba1 3925{
31390eec 3926 s32 result = 0;
143eb95a 3927 struct host_if_msg msg;
c5c77ba1 3928
a4ab1ade
TC
3929 if (!hif_drv) {
3930 PRINT_ER("hif_drv NULL\n");
24db713f
LK
3931 return -EFAULT;
3932 }
ae4dfa57 3933
143eb95a 3934 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3935 msg.id = HOST_IF_MSG_CFG_PARAMS;
221371e5 3936 msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
a4ab1ade 3937 msg.drv = hif_drv;
c5c77ba1 3938
31390eec 3939 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3940
31390eec 3941 return result;
c5c77ba1
JK
3942}
3943
a4ab1ade 3944s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
c5c77ba1 3945{
31390eec 3946 s32 result = 0;
c5c77ba1 3947
a4ab1ade 3948 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 3949
a4ab1ade
TC
3950 if (!hif_drv) {
3951 PRINT_ER("hif_drv NULL\n");
24db713f 3952 return -EFAULT;
c5c77ba1
JK
3953 }
3954 PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
3955 switch (u16WID) {
c5c77ba1 3956 case WID_BSS_TYPE:
a4ab1ade 3957 *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type;
c5c77ba1
JK
3958 break;
3959
3960 case WID_AUTH_TYPE:
a4ab1ade 3961 *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type;
c5c77ba1
JK
3962 break;
3963
3964 case WID_AUTH_TIMEOUT:
a4ab1ade 3965 *pu16WID_Value = hif_drv->strCfgValues.auth_timeout;
c5c77ba1
JK
3966 break;
3967
3968 case WID_POWER_MANAGEMENT:
a4ab1ade 3969 *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode;
c5c77ba1
JK
3970 break;
3971
3972 case WID_SHORT_RETRY_LIMIT:
a4ab1ade 3973 *pu16WID_Value = hif_drv->strCfgValues.short_retry_limit;
c5c77ba1
JK
3974 break;
3975
3976 case WID_LONG_RETRY_LIMIT:
a4ab1ade 3977 *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit;
c5c77ba1
JK
3978 break;
3979
3980 case WID_FRAG_THRESHOLD:
a4ab1ade 3981 *pu16WID_Value = hif_drv->strCfgValues.frag_threshold;
c5c77ba1
JK
3982 break;
3983
3984 case WID_RTS_THRESHOLD:
a4ab1ade 3985 *pu16WID_Value = hif_drv->strCfgValues.rts_threshold;
c5c77ba1
JK
3986 break;
3987
3988 case WID_PREAMBLE:
a4ab1ade 3989 *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type;
c5c77ba1
JK
3990 break;
3991
3992 case WID_SHORT_SLOT_ALLOWED:
a4ab1ade 3993 *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed;
c5c77ba1
JK
3994 break;
3995
3996 case WID_11N_TXOP_PROT_DISABLE:
a4ab1ade 3997 *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled;
c5c77ba1
JK
3998 break;
3999
4000 case WID_BEACON_INTERVAL:
a4ab1ade 4001 *pu16WID_Value = hif_drv->strCfgValues.beacon_interval;
c5c77ba1
JK
4002 break;
4003
4004 case WID_DTIM_PERIOD:
a4ab1ade 4005 *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period;
c5c77ba1
JK
4006 break;
4007
4008 case WID_SITE_SURVEY:
a4ab1ade 4009 *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled;
c5c77ba1
JK
4010 break;
4011
4012 case WID_SITE_SURVEY_SCAN_TIME:
a4ab1ade 4013 *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time;
c5c77ba1
JK
4014 break;
4015
4016 case WID_ACTIVE_SCAN_TIME:
a4ab1ade 4017 *pu16WID_Value = hif_drv->strCfgValues.active_scan_time;
c5c77ba1
JK
4018 break;
4019
4020 case WID_PASSIVE_SCAN_TIME:
a4ab1ade 4021 *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time;
c5c77ba1
JK
4022 break;
4023
4024 case WID_CURRENT_TX_RATE:
a4ab1ade 4025 *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate;
c5c77ba1
JK
4026 break;
4027
4028 default:
4029 break;
4030 }
4031
a4ab1ade 4032 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4033
31390eec 4034 return result;
c5c77ba1
JK
4035}
4036
93dee8ee 4037static void GetPeriodicRSSI(unsigned long arg)
c5c77ba1 4038{
a4ab1ade 4039 struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
78c87591 4040
a4ab1ade 4041 if (!hif_drv) {
c5c77ba1
JK
4042 PRINT_ER("Driver handler is NULL\n");
4043 return;
4044 }
4045
a4ab1ade 4046 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) {
31390eec 4047 s32 result = 0;
143eb95a 4048 struct host_if_msg msg;
c5c77ba1 4049
143eb95a 4050 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4051
a9f812a6 4052 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 4053 msg.drv = hif_drv;
c5c77ba1 4054
31390eec
LK
4055 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4056 if (result) {
c5c77ba1
JK
4057 PRINT_ER("Failed to send get host channel param's message queue ");
4058 return;
4059 }
4060 }
262f55e1
LK
4061 periodic_rssi.data = (unsigned long)hif_drv;
4062 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4063}
4064
d5382219 4065s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
c5c77ba1 4066{
5b09bd32 4067 s32 result = 0;
a4ab1ade 4068 struct host_if_drv *hif_drv;
d42ab083 4069 int err;
d5382219
GL
4070 perInterface_wlan_t *nic;
4071 struct wilc *wilc;
4072
4073 nic = netdev_priv(dev);
4074 wilc = nic->wilc;
c5c77ba1 4075
c5c77ba1
JK
4076 PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
4077
ca8540e4 4078 scan_while_connected = false;
c5c77ba1 4079
2d25af87 4080 sema_init(&hif_sema_wait_response, 0);
c5c77ba1 4081
a4ab1ade
TC
4082 hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
4083 if (!hif_drv) {
5b09bd32 4084 result = -ENOMEM;
17db84eb 4085 goto _fail_;
c5c77ba1 4086 }
a4ab1ade
TC
4087 *hif_drv_handler = hif_drv;
4088 err = add_handler_in_list(hif_drv);
d42ab083 4089 if (err) {
5b09bd32 4090 result = -EFAULT;
d42ab083
JK
4091 goto _fail_timer_2;
4092 }
c5c77ba1 4093
72ed4dc7 4094 g_obtainingIP = false;
c5c77ba1 4095
a4ab1ade 4096 PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
c5c77ba1 4097 if (clients_count == 0) {
834e0cb0 4098 sema_init(&hif_sema_thread, 0);
27ff2168 4099 sema_init(&hif_sema_driver, 0);
440e8993 4100 sema_init(&hif_sema_deinit, 1);
83383ea3
AB
4101 }
4102
a4ab1ade
TC
4103 sema_init(&hif_drv->hSemTestKeyBlock, 0);
4104 sema_init(&hif_drv->hSemTestDisconnectBlock, 0);
4105 sema_init(&hif_drv->hSemGetRSSI, 0);
4106 sema_init(&hif_drv->hSemGetLINKSPEED, 0);
4107 sema_init(&hif_drv->hSemGetCHNL, 0);
4108 sema_init(&hif_drv->hSemInactiveTime, 0);
c5c77ba1 4109
c5c77ba1
JK
4110 PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
4111
4112 if (clients_count == 0) {
cb067dcf 4113 result = wilc_mq_create(&hif_msg_q);
c5c77ba1 4114
5b09bd32 4115 if (result < 0) {
c5c77ba1
JK
4116 PRINT_ER("Failed to creat MQ\n");
4117 goto _fail_;
4118 }
c2115d8e 4119
d5382219
GL
4120 hif_thread_handler = kthread_run(hostIFthread, wilc,
4121 "WILC_kthread");
c2115d8e
LK
4122
4123 if (IS_ERR(hif_thread_handler)) {
c5c77ba1 4124 PRINT_ER("Failed to creat Thread\n");
5b09bd32 4125 result = -EFAULT;
c5c77ba1
JK
4126 goto _fail_mq_;
4127 }
262f55e1 4128 setup_timer(&periodic_rssi, GetPeriodicRSSI,
a4ab1ade 4129 (unsigned long)hif_drv);
262f55e1 4130 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4131 }
4132
a4ab1ade 4133 setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0);
c5c77ba1 4134
a4ab1ade 4135 setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0);
c5c77ba1 4136
a4ab1ade 4137 setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0);
c5c77ba1 4138
bafaa696 4139 sema_init(&hif_drv->gtOsCfgValuesSem, 1);
a4ab1ade 4140 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4141
a4ab1ade 4142 hif_drv->enuHostIFstate = HOST_IF_IDLE;
a4ab1ade
TC
4143 hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
4144 hif_drv->strCfgValues.scan_source = DEFAULT_SCAN;
4145 hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
4146 hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
4147 hif_drv->strCfgValues.curr_tx_rate = AUTORATE;
c5c77ba1 4148
a4ab1ade 4149 hif_drv->u64P2p_MgmtTimeout = 0;
c5c77ba1 4150
c5c77ba1
JK
4151 PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n",
4152
a4ab1ade
TC
4153 hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source,
4154 hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time,
4155 hif_drv->strCfgValues.curr_tx_rate);
c5c77ba1 4156
a4ab1ade 4157 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4158
ae4dfa57 4159 clients_count++;
c5c77ba1 4160
5b09bd32 4161 return result;
c5c77ba1 4162
c5c77ba1 4163_fail_timer_2:
a4ab1ade
TC
4164 up(&hif_drv->gtOsCfgValuesSem);
4165 del_timer_sync(&hif_drv->hConnectTimer);
4166 del_timer_sync(&hif_drv->hScanTimer);
c2115d8e 4167 kthread_stop(hif_thread_handler);
c5c77ba1 4168_fail_mq_:
cb067dcf 4169 wilc_mq_destroy(&hif_msg_q);
c5c77ba1 4170_fail_:
5b09bd32 4171 return result;
c5c77ba1 4172}
c5c77ba1 4173
a4ab1ade 4174s32 host_int_deinit(struct host_if_drv *hif_drv)
c5c77ba1 4175{
31390eec 4176 s32 result = 0;
143eb95a 4177 struct host_if_msg msg;
d42ab083 4178 int ret;
c5c77ba1 4179
a4ab1ade
TC
4180 if (!hif_drv) {
4181 PRINT_ER("hif_drv = NULL\n");
c5c77ba1
JK
4182 return 0;
4183 }
4184
440e8993 4185 down(&hif_sema_deinit);
c5c77ba1 4186
a4ab1ade 4187 terminated_handle = hif_drv;
c5c77ba1
JK
4188 PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
4189
d1666e2a 4190 if (del_timer_sync(&hif_drv->hScanTimer))
03b2d5e7 4191 PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
c5c77ba1 4192
d1666e2a 4193 if (del_timer_sync(&hif_drv->hConnectTimer))
03b2d5e7 4194 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1 4195
262f55e1 4196 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4197 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1 4198
a4ab1ade 4199 del_timer_sync(&hif_drv->hRemainOnChannel);
c5c77ba1 4200
218dc407 4201 host_int_set_wfi_drv_handler(NULL);
27ff2168 4202 down(&hif_sema_driver);
c5c77ba1 4203
a4ab1ade
TC
4204 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
4205 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
4206 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
c5c77ba1 4207
a4ab1ade 4208 hif_drv->strWILC_UsrScanReq.pfUserScanResult = NULL;
c5c77ba1 4209 }
c5c77ba1 4210
a4ab1ade 4211 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 4212
ca8540e4 4213 scan_while_connected = false;
c5c77ba1 4214
143eb95a 4215 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4216
4217 if (clients_count == 1) {
262f55e1 4218 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4219 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
262f55e1 4220
a9f812a6 4221 msg.id = HOST_IF_MSG_EXIT;
a4ab1ade 4222 msg.drv = hif_drv;
c5c77ba1 4223
31390eec
LK
4224 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4225 if (result != 0)
4226 PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
c5c77ba1 4227
834e0cb0 4228 down(&hif_sema_thread);
c5c77ba1 4229
cb067dcf 4230 wilc_mq_destroy(&hif_msg_q);
c5c77ba1
JK
4231 }
4232
bafaa696 4233 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4234
a4ab1ade 4235 ret = remove_handler_in_list(hif_drv);
d42ab083 4236 if (ret)
31390eec 4237 result = -ENOENT;
d42ab083 4238
a4ab1ade 4239 kfree(hif_drv);
c5c77ba1 4240
ae4dfa57 4241 clients_count--;
b1413b60 4242 terminated_handle = NULL;
440e8993 4243 up(&hif_sema_deinit);
31390eec 4244 return result;
c5c77ba1
JK
4245}
4246
4e4467fd 4247void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4248{
31390eec 4249 s32 result = 0;
143eb95a 4250 struct host_if_msg msg;
d42ab083 4251 int id;
a4ab1ade 4252 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4253
d42ab083 4254 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4255 hif_drv = get_handler_from_id(id);
c5c77ba1 4256
a4ab1ade
TC
4257 if (!hif_drv || hif_drv == terminated_handle) {
4258 PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
c5c77ba1
JK
4259 return;
4260 }
4261
143eb95a 4262 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4263
a9f812a6 4264 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
a4ab1ade 4265 msg.drv = hif_drv;
c5c77ba1 4266
3bffac68 4267 msg.body.net_info.len = u32Length;
b021b80b
LK
4268 msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4269 memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4270
31390eec
LK
4271 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4272 if (result)
4273 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
c5c77ba1
JK
4274}
4275
4e4467fd 4276void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4277{
31390eec 4278 s32 result = 0;
143eb95a 4279 struct host_if_msg msg;
d42ab083 4280 int id;
a4ab1ade 4281 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4282
440e8993 4283 down(&hif_sema_deinit);
c5c77ba1 4284
d42ab083 4285 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4286 hif_drv = get_handler_from_id(id);
03b2d5e7 4287 PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
c5c77ba1 4288
a4ab1ade 4289 if (!hif_drv || hif_drv == terminated_handle) {
c5c77ba1 4290 PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
440e8993 4291 up(&hif_sema_deinit);
c5c77ba1
JK
4292 return;
4293 }
4294
a4ab1ade 4295 if (!hif_drv->strWILC_UsrConnReq.pfUserConnectResult) {
c5c77ba1 4296 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
440e8993 4297 up(&hif_sema_deinit);
c5c77ba1
JK
4298 return;
4299 }
4300
143eb95a 4301 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4302
a9f812a6 4303 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
a4ab1ade 4304 msg.drv = hif_drv;
c5c77ba1 4305
f94f4889 4306 msg.body.async_info.len = u32Length;
33722ac7
LK
4307 msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4308 memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4309
31390eec
LK
4310 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4311 if (result)
4312 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
c5c77ba1 4313
440e8993 4314 up(&hif_sema_deinit);
c5c77ba1
JK
4315}
4316
4e4467fd 4317void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4318{
31390eec 4319 s32 result = 0;
143eb95a 4320 struct host_if_msg msg;
d42ab083 4321 int id;
a4ab1ade 4322 struct host_if_drv *hif_drv = NULL;
78c87591 4323
d42ab083 4324 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4325 hif_drv = get_handler_from_id(id);
c5c77ba1 4326
a4ab1ade 4327 PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
c5c77ba1 4328
a4ab1ade 4329 if (!hif_drv || hif_drv == terminated_handle)
c5c77ba1 4330 return;
c5c77ba1 4331
a4ab1ade 4332 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
143eb95a 4333 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4334
a9f812a6 4335 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
a4ab1ade 4336 msg.drv = hif_drv;
c5c77ba1 4337
31390eec
LK
4338 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4339 if (result)
4340 PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
c5c77ba1
JK
4341 }
4342
c5c77ba1 4343 return;
c5c77ba1
JK
4344}
4345
a4ab1ade
TC
4346s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
4347 u32 u32duration, u16 chan,
4348 wilc_remain_on_chan_expired RemainOnChanExpired,
4349 wilc_remain_on_chan_ready RemainOnChanReady,
4350 void *pvUserArg)
c5c77ba1 4351{
31390eec 4352 s32 result = 0;
143eb95a 4353 struct host_if_msg msg;
c5c77ba1 4354
a4ab1ade 4355 if (!hif_drv) {
24db713f
LK
4356 PRINT_ER("driver is null\n");
4357 return -EFAULT;
4358 }
c5c77ba1 4359
143eb95a 4360 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4361
a9f812a6 4362 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
070d365c
TC
4363 msg.body.remain_on_ch.u16Channel = chan;
4364 msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
4365 msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
4366 msg.body.remain_on_ch.pVoid = pvUserArg;
4367 msg.body.remain_on_ch.u32duration = u32duration;
4368 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
a4ab1ade 4369 msg.drv = hif_drv;
143eb95a 4370
31390eec
LK
4371 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4372 if (result)
24db713f 4373 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4374
31390eec 4375 return result;
c5c77ba1
JK
4376}
4377
a4ab1ade 4378s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
c5c77ba1 4379{
31390eec 4380 s32 result = 0;
143eb95a 4381 struct host_if_msg msg;
c5c77ba1 4382
a4ab1ade 4383 if (!hif_drv) {
24db713f
LK
4384 PRINT_ER("driver is null\n");
4385 return -EFAULT;
4386 }
c5c77ba1 4387
a4ab1ade 4388 del_timer(&hif_drv->hRemainOnChannel);
c5c77ba1 4389
143eb95a 4390 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 4391 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
a4ab1ade 4392 msg.drv = hif_drv;
070d365c 4393 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
c5c77ba1 4394
31390eec
LK
4395 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4396 if (result)
24db713f 4397 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4398
31390eec 4399 return result;
c5c77ba1
JK
4400}
4401
a4ab1ade 4402s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
c5c77ba1 4403{
31390eec 4404 s32 result = 0;
143eb95a 4405 struct host_if_msg msg;
c5c77ba1 4406
a4ab1ade 4407 if (!hif_drv) {
24db713f
LK
4408 PRINT_ER("driver is null\n");
4409 return -EFAULT;
4410 }
c5c77ba1 4411
143eb95a 4412 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4413
a9f812a6 4414 msg.id = HOST_IF_MSG_REGISTER_FRAME;
c5c77ba1
JK
4415 switch (u16FrameType) {
4416 case ACTION:
4417 PRINT_D(HOSTINF_DBG, "ACTION\n");
5c4008db 4418 msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
c5c77ba1
JK
4419 break;
4420
4421 case PROBE_REQ:
4422 PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
5c4008db 4423 msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
c5c77ba1
JK
4424 break;
4425
4426 default:
4427 PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
4428 break;
4429 }
5c4008db
TC
4430 msg.body.reg_frame.u16FrameType = u16FrameType;
4431 msg.body.reg_frame.bReg = bReg;
a4ab1ade 4432 msg.drv = hif_drv;
c5c77ba1 4433
31390eec
LK
4434 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4435 if (result)
24db713f 4436 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4437
31390eec 4438 return result;
c5c77ba1 4439}
c5c77ba1 4440
a4ab1ade
TC
4441s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
4442 u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
4443 u32 u32TailLen, u8 *pu8Tail)
c5c77ba1 4444{
31390eec 4445 s32 result = 0;
143eb95a 4446 struct host_if_msg msg;
a98491e5 4447 struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
c5c77ba1 4448
a4ab1ade 4449 if (!hif_drv) {
24db713f
LK
4450 PRINT_ER("driver is null\n");
4451 return -EFAULT;
4452 }
c5c77ba1 4453
143eb95a 4454 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4455
4456 PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
4457
a9f812a6 4458 msg.id = HOST_IF_MSG_ADD_BEACON;
a4ab1ade 4459 msg.drv = hif_drv;
12262dda 4460 pstrSetBeaconParam->interval = u32Interval;
e76ab770 4461 pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
51c66185 4462 pstrSetBeaconParam->head_len = u32HeadLen;
543f5b13 4463 pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL);
91109e11 4464 if (!pstrSetBeaconParam->head) {
31390eec 4465 result = -ENOMEM;
24db713f
LK
4466 goto ERRORHANDLER;
4467 }
030c57e2 4468 pstrSetBeaconParam->tail_len = u32TailLen;
c5c77ba1 4469
c5c77ba1 4470 if (u32TailLen > 0) {
543f5b13
SB
4471 pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen,
4472 GFP_KERNEL);
91109e11 4473 if (!pstrSetBeaconParam->tail) {
31390eec 4474 result = -ENOMEM;
24db713f
LK
4475 goto ERRORHANDLER;
4476 }
c5c77ba1 4477 } else {
7dbcb6d3 4478 pstrSetBeaconParam->tail = NULL;
c5c77ba1
JK
4479 }
4480
31390eec
LK
4481 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4482 if (result)
24db713f 4483 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4484
24db713f 4485ERRORHANDLER:
31390eec 4486 if (result) {
95f840fb 4487 kfree(pstrSetBeaconParam->head);
c5c77ba1 4488
95f840fb 4489 kfree(pstrSetBeaconParam->tail);
c5c77ba1
JK
4490 }
4491
31390eec 4492 return result;
c5c77ba1
JK
4493}
4494
a4ab1ade 4495s32 host_int_del_beacon(struct host_if_drv *hif_drv)
c5c77ba1 4496{
31390eec 4497 s32 result = 0;
143eb95a 4498 struct host_if_msg msg;
c5c77ba1 4499
a4ab1ade 4500 if (!hif_drv) {
24db713f
LK
4501 PRINT_ER("driver is null\n");
4502 return -EFAULT;
4503 }
c5c77ba1 4504
a9f812a6 4505 msg.id = HOST_IF_MSG_DEL_BEACON;
a4ab1ade 4506 msg.drv = hif_drv;
c5c77ba1
JK
4507 PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
4508
31390eec
LK
4509 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4510 if (result)
7dc1d0cc 4511 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4512
31390eec 4513 return result;
c5c77ba1
JK
4514}
4515
a4ab1ade 4516s32 host_int_add_station(struct host_if_drv *hif_drv,
6a89ba9c 4517 struct add_sta_param *pstrStaParams)
c5c77ba1 4518{
31390eec 4519 s32 result = 0;
143eb95a 4520 struct host_if_msg msg;
ca8f47f8 4521 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1 4522
a4ab1ade 4523 if (!hif_drv) {
24db713f
LK
4524 PRINT_ER("driver is null\n");
4525 return -EFAULT;
4526 }
c5c77ba1 4527
143eb95a 4528 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4529
4530 PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
4531
a9f812a6 4532 msg.id = HOST_IF_MSG_ADD_STATION;
a4ab1ade 4533 msg.drv = hif_drv;
c5c77ba1 4534
6a89ba9c 4535 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4536 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4537 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
c09389ac 4538
7ae43363
LK
4539 if (!rates)
4540 return -ENOMEM;
c5c77ba1 4541
d00d2ba3 4542 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4543 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4544 }
4545
31390eec
LK
4546 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4547 if (result)
24db713f 4548 PRINT_ER("wilc_mq_send fail\n");
31390eec 4549 return result;
c5c77ba1
JK
4550}
4551
a4ab1ade 4552s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr)
c5c77ba1 4553{
31390eec 4554 s32 result = 0;
143eb95a 4555 struct host_if_msg msg;
889c25be 4556 struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
c5c77ba1 4557
a4ab1ade 4558 if (!hif_drv) {
24db713f
LK
4559 PRINT_ER("driver is null\n");
4560 return -EFAULT;
4561 }
c5c77ba1 4562
143eb95a 4563 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4564
4565 PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
4566
a9f812a6 4567 msg.id = HOST_IF_MSG_DEL_STATION;
a4ab1ade 4568 msg.drv = hif_drv;
c5c77ba1 4569
91109e11 4570 if (!pu8MacAddr)
e4839d39 4571 memset(pstrDelStationMsg->mac_addr, 255, ETH_ALEN);
c5c77ba1 4572 else
e4839d39 4573 memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN);
c5c77ba1 4574
31390eec
LK
4575 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4576 if (result)
24db713f 4577 PRINT_ER("wilc_mq_send fail\n");
31390eec 4578 return result;
c5c77ba1 4579}
ae4dfa57 4580
a4ab1ade 4581s32 host_int_del_allstation(struct host_if_drv *hif_drv,
441dc609 4582 u8 pu8MacAddr[][ETH_ALEN])
c5c77ba1 4583{
31390eec 4584 s32 result = 0;
143eb95a 4585 struct host_if_msg msg;
b0c1e80e 4586 struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
63d03e47 4587 u8 au8Zero_Buff[ETH_ALEN] = {0};
4e4467fd 4588 u32 i;
63d03e47 4589 u8 u8AssocNumb = 0;
c5c77ba1 4590
a4ab1ade 4591 if (!hif_drv) {
24db713f
LK
4592 PRINT_ER("driver is null\n");
4593 return -EFAULT;
4594 }
c5c77ba1 4595
143eb95a 4596 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4597
4598 PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
4599
a9f812a6 4600 msg.id = HOST_IF_MSG_DEL_ALL_STA;
a4ab1ade 4601 msg.drv = hif_drv;
c5c77ba1 4602
c5c77ba1
JK
4603 for (i = 0; i < MAX_NUM_STA; i++) {
4604 if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
e51b9216
LK
4605 memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN);
4606 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4607 pstrDelAllStationMsg->del_all_sta[i][0],
4608 pstrDelAllStationMsg->del_all_sta[i][1],
4609 pstrDelAllStationMsg->del_all_sta[i][2],
4610 pstrDelAllStationMsg->del_all_sta[i][3],
4611 pstrDelAllStationMsg->del_all_sta[i][4],
4612 pstrDelAllStationMsg->del_all_sta[i][5]);
c5c77ba1
JK
4613 u8AssocNumb++;
4614 }
4615 }
4616 if (!u8AssocNumb) {
4617 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
31390eec 4618 return result;
c5c77ba1
JK
4619 }
4620
8ba1803f 4621 pstrDelAllStationMsg->assoc_sta = u8AssocNumb;
31390eec 4622 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 4623
31390eec 4624 if (result)
24db713f 4625 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4626
2d25af87 4627 down(&hif_sema_wait_response);
c5c77ba1 4628
31390eec 4629 return result;
c5c77ba1
JK
4630}
4631
a4ab1ade 4632s32 host_int_edit_station(struct host_if_drv *hif_drv,
6a89ba9c 4633 struct add_sta_param *pstrStaParams)
c5c77ba1 4634{
31390eec 4635 s32 result = 0;
143eb95a 4636 struct host_if_msg msg;
ca8f47f8 4637 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1 4638
a4ab1ade 4639 if (!hif_drv) {
24db713f
LK
4640 PRINT_ER("driver is null\n");
4641 return -EFAULT;
4642 }
c5c77ba1
JK
4643
4644 PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
4645
143eb95a 4646 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4647
a9f812a6 4648 msg.id = HOST_IF_MSG_EDIT_STATION;
a4ab1ade 4649 msg.drv = hif_drv;
c5c77ba1 4650
6a89ba9c 4651 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4652 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4653 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
c09389ac 4654
7ae43363
LK
4655 if (!rates)
4656 return -ENOMEM;
4657
d00d2ba3 4658 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4659 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4660 }
4661
31390eec
LK
4662 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4663 if (result)
24db713f
LK
4664 PRINT_ER("wilc_mq_send fail\n");
4665
31390eec 4666 return result;
c5c77ba1 4667}
108b3439 4668
a4ab1ade
TC
4669s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
4670 bool bIsEnabled,
4671 u32 u32Timeout)
c5c77ba1 4672{
31390eec 4673 s32 result = 0;
143eb95a 4674 struct host_if_msg msg;
49e1f81b 4675 struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
c5c77ba1 4676
03b2d5e7 4677 PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
c5c77ba1 4678
a4ab1ade 4679 if (!hif_drv) {
24db713f
LK
4680 PRINT_ER("driver is null\n");
4681 return -EFAULT;
4682 }
c5c77ba1
JK
4683
4684 PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
4685
143eb95a 4686 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4687
a9f812a6 4688 msg.id = HOST_IF_MSG_POWER_MGMT;
a4ab1ade 4689 msg.drv = hif_drv;
c5c77ba1 4690
33c70c1b 4691 pstrPowerMgmtParam->enabled = bIsEnabled;
937918ff 4692 pstrPowerMgmtParam->timeout = u32Timeout;
c5c77ba1 4693
31390eec
LK
4694 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4695 if (result)
24db713f 4696 PRINT_ER("wilc_mq_send fail\n");
31390eec 4697 return result;
c5c77ba1
JK
4698}
4699
a4ab1ade
TC
4700s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
4701 bool bIsEnabled,
4702 u32 u32count)
c5c77ba1 4703{
31390eec 4704 s32 result = 0;
143eb95a 4705 struct host_if_msg msg;
a079cf4d 4706 struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
c5c77ba1 4707
a4ab1ade 4708 if (!hif_drv) {
24db713f
LK
4709 PRINT_ER("driver is null\n");
4710 return -EFAULT;
4711 }
c5c77ba1
JK
4712
4713 PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
4714
143eb95a 4715 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4716
a9f812a6 4717 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
a4ab1ade 4718 msg.drv = hif_drv;
c5c77ba1 4719
bae636eb 4720 pstrMulticastFilterParam->enabled = bIsEnabled;
adab2f71 4721 pstrMulticastFilterParam->cnt = u32count;
c5c77ba1 4722
31390eec
LK
4723 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4724 if (result)
24db713f 4725 PRINT_ER("wilc_mq_send fail\n");
31390eec 4726 return result;
c5c77ba1
JK
4727}
4728
c5c77ba1
JK
4729static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
4730{
e0a12217 4731 struct join_bss_param *pNewJoinBssParam = NULL;
63d03e47 4732 u8 *pu8IEs;
d85f5326
CL
4733 u16 u16IEsLen;
4734 u16 index = 0;
63d03e47
GKH
4735 u8 suppRatesNo = 0;
4736 u8 extSuppRatesNo;
d85f5326 4737 u16 jumpOffset;
63d03e47
GKH
4738 u8 pcipherCount;
4739 u8 authCount;
4740 u8 pcipherTotalCount = 0;
4741 u8 authTotalCount = 0;
4742 u8 i, j;
c5c77ba1
JK
4743
4744 pu8IEs = ptstrNetworkInfo->pu8IEs;
4745 u16IEsLen = ptstrNetworkInfo->u16IEsLen;
4746
b156f1ed 4747 pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
91109e11 4748 if (pNewJoinBssParam) {
c5c77ba1
JK
4749 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
4750 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
4751 pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
d00d2ba3 4752 memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
d00d2ba3 4753 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
619d27b8 4754 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen;
2cc46837
CL
4755 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4756 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
c5c77ba1 4757
c5c77ba1 4758 while (index < u16IEsLen) {
c5c77ba1 4759 if (pu8IEs[index] == SUPP_RATES_IE) {
c5c77ba1
JK
4760 suppRatesNo = pu8IEs[index + 1];
4761 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
ae4dfa57 4762 index += 2;
c5c77ba1 4763
d1666e2a 4764 for (i = 0; i < suppRatesNo; i++)
c5c77ba1 4765 pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
d1666e2a 4766
c5c77ba1
JK
4767 index += suppRatesNo;
4768 continue;
ae4dfa57 4769 } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
c5c77ba1
JK
4770 extSuppRatesNo = pu8IEs[index + 1];
4771 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4772 pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4773 else
4774 pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4775 index += 2;
d1666e2a 4776 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
c5c77ba1 4777 pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
d1666e2a 4778
c5c77ba1
JK
4779 index += extSuppRatesNo;
4780 continue;
ae4dfa57 4781 } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
0be1eb74 4782 pNewJoinBssParam->ht_capable = true;
ae4dfa57 4783 index += pu8IEs[index + 1] + 2;
c5c77ba1 4784 continue;
ae4dfa57 4785 } else if ((pu8IEs[index] == WMM_IE) &&
c5c77ba1 4786 (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
ae4dfa57
LK
4787 (pu8IEs[index + 4] == 0xF2) &&
4788 (pu8IEs[index + 5] == 0x02) &&
4789 ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
c5c77ba1 4790 (pu8IEs[index + 7] == 0x01)) {
0be1eb74 4791 pNewJoinBssParam->wmm_cap = true;
c5c77ba1 4792
ffda203c 4793 if (pu8IEs[index + 8] & BIT(7))
0be1eb74 4794 pNewJoinBssParam->uapsd_cap = true;
c5c77ba1
JK
4795 index += pu8IEs[index + 1] + 2;
4796 continue;
ae4dfa57 4797 } else if ((pu8IEs[index] == P2P_IE) &&
c5c77ba1 4798 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
ae4dfa57
LK
4799 (pu8IEs[index + 4] == 0x9a) &&
4800 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
d85f5326 4801 u16 u16P2P_count;
78c87591 4802
c5c77ba1 4803 pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
7a8d51d7 4804 pNewJoinBssParam->noa_enabled = 1;
cc179008 4805 pNewJoinBssParam->idx = pu8IEs[index + 9];
c5c77ba1 4806
ffda203c 4807 if (pu8IEs[index + 10] & BIT(7)) {
d72b33ca 4808 pNewJoinBssParam->opp_enabled = 1;
99b66945 4809 pNewJoinBssParam->ct_window = pu8IEs[index + 10];
d72b33ca
LK
4810 } else {
4811 pNewJoinBssParam->opp_enabled = 0;
4812 }
ae4dfa57 4813
03b2d5e7 4814 PRINT_D(GENERIC_DBG, "P2P Dump\n");
c5c77ba1 4815 for (i = 0; i < pu8IEs[index + 7]; i++)
03b2d5e7 4816 PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
c5c77ba1 4817
c21047ed 4818 pNewJoinBssParam->cnt = pu8IEs[index + 11];
c5c77ba1
JK
4819 u16P2P_count = index + 12;
4820
109e6cab 4821 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4822 u16P2P_count += 4;
4823
1d8b76b3 4824 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4825 u16P2P_count += 4;
4826
4be55e22 4827 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4828
4829 index += pu8IEs[index + 1] + 2;
4830 continue;
4831
ae4dfa57 4832 } else if ((pu8IEs[index] == RSN_IE) ||
c5c77ba1
JK
4833 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4834 (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4835 (pu8IEs[index + 5] == 0x01))) {
d85f5326 4836 u16 rsnIndex = index;
ae4dfa57 4837
c5c77ba1
JK
4838 if (pu8IEs[rsnIndex] == RSN_IE) {
4839 pNewJoinBssParam->mode_802_11i = 2;
ae4dfa57 4840 } else {
c5c77ba1
JK
4841 if (pNewJoinBssParam->mode_802_11i == 0)
4842 pNewJoinBssParam->mode_802_11i = 1;
c5c77ba1
JK
4843 rsnIndex += 4;
4844 }
ae4dfa57
LK
4845
4846 rsnIndex += 7;
c5c77ba1
JK
4847 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4848 rsnIndex++;
ae4dfa57 4849 jumpOffset = pu8IEs[rsnIndex] * 4;
c5c77ba1 4850 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4851 rsnIndex += 2;
c5c77ba1 4852
d1666e2a 4853 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
c5c77ba1 4854 pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
d1666e2a 4855
c5c77ba1
JK
4856 pcipherTotalCount += pcipherCount;
4857 rsnIndex += jumpOffset;
4858
4859 jumpOffset = pu8IEs[rsnIndex] * 4;
4860
c5c77ba1 4861 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4862 rsnIndex += 2;
c5c77ba1 4863
d1666e2a 4864 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
c5c77ba1 4865 pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
d1666e2a 4866
c5c77ba1
JK
4867 authTotalCount += authCount;
4868 rsnIndex += jumpOffset;
ae4dfa57 4869
c5c77ba1
JK
4870 if (pu8IEs[index] == RSN_IE) {
4871 pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4872 pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4873 rsnIndex += 2;
4874 }
f717c0eb 4875 pNewJoinBssParam->rsn_found = true;
ae4dfa57 4876 index += pu8IEs[index + 1] + 2;
c5c77ba1
JK
4877 continue;
4878 } else
ae4dfa57 4879 index += pu8IEs[index + 1] + 2;
c5c77ba1 4880 }
c5c77ba1
JK
4881 }
4882
4883 return (void *)pNewJoinBssParam;
c5c77ba1
JK
4884}
4885
4886void host_int_freeJoinParams(void *pJoinParams)
4887{
91109e11 4888 if ((struct bss_param *)pJoinParams)
e0a12217 4889 kfree((struct bss_param *)pJoinParams);
c5c77ba1
JK
4890 else
4891 PRINT_ER("Unable to FREE null pointer\n");
4892}
c5c77ba1 4893
a4ab1ade 4894s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
c5c77ba1 4895{
31390eec 4896 s32 result = 0;
143eb95a 4897 struct host_if_msg msg;
c833b474 4898 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 4899
a4ab1ade 4900 if (!hif_drv) {
24db713f
LK
4901 PRINT_ER("driver is null\n");
4902 return -EFAULT;
4903 }
c5c77ba1 4904
143eb95a 4905 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4906
a9f812a6 4907 msg.id = HOST_IF_MSG_DEL_BA_SESSION;
c5c77ba1
JK
4908
4909 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4910 pBASessionInfo->u8Ted = TID;
a4ab1ade 4911 msg.drv = hif_drv;
c5c77ba1 4912
31390eec
LK
4913 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4914 if (result)
24db713f 4915 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4916
2d25af87 4917 down(&hif_sema_wait_response);
c5c77ba1 4918
31390eec 4919 return result;
c5c77ba1
JK
4920}
4921
a4ab1ade
TC
4922s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
4923 char *pBSSID,
4924 char TID)
c5c77ba1 4925{
31390eec 4926 s32 result = 0;
143eb95a 4927 struct host_if_msg msg;
c833b474 4928 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 4929
a4ab1ade 4930 if (!hif_drv) {
24db713f
LK
4931 PRINT_ER("driver is null\n");
4932 return -EFAULT;
4933 }
c5c77ba1 4934
143eb95a 4935 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4936
a9f812a6 4937 msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
c5c77ba1
JK
4938
4939 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4940 pBASessionInfo->u8Ted = TID;
a4ab1ade 4941 msg.drv = hif_drv;
c5c77ba1 4942
31390eec
LK
4943 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4944 if (result)
24db713f 4945 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4946
2d25af87 4947 down(&hif_sema_wait_response);
c5c77ba1 4948
31390eec 4949 return result;
c5c77ba1
JK
4950}
4951
a4ab1ade 4952s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 4953{
31390eec 4954 s32 result = 0;
143eb95a 4955 struct host_if_msg msg;
c5c77ba1 4956
c5c77ba1
JK
4957 return 0;
4958
a4ab1ade 4959 if (!hif_drv) {
24db713f
LK
4960 PRINT_ER("driver is null\n");
4961 return -EFAULT;
4962 }
c5c77ba1 4963
143eb95a 4964 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4965
a9f812a6 4966 msg.id = HOST_IF_MSG_SET_IPADDRESS;
c5c77ba1 4967
78675be5 4968 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 4969 msg.drv = hif_drv;
fb2d65ed 4970 msg.body.ip_info.idx = idx;
c5c77ba1 4971
31390eec
LK
4972 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4973 if (result)
24db713f 4974 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4975
31390eec 4976 return result;
c5c77ba1
JK
4977}
4978
a4ab1ade 4979s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 4980{
31390eec 4981 s32 result = 0;
143eb95a 4982 struct host_if_msg msg;
c5c77ba1 4983
a4ab1ade 4984 if (!hif_drv) {
24db713f
LK
4985 PRINT_ER("driver is null\n");
4986 return -EFAULT;
4987 }
c5c77ba1 4988
143eb95a 4989 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4990
a9f812a6 4991 msg.id = HOST_IF_MSG_GET_IPADDRESS;
c5c77ba1 4992
78675be5 4993 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 4994 msg.drv = hif_drv;
fb2d65ed 4995 msg.body.ip_info.idx = idx;
c5c77ba1 4996
31390eec
LK
4997 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4998 if (result)
24db713f 4999 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 5000
31390eec 5001 return result;
c5c77ba1 5002}