]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/staging/wilc1000/host_interface.c
staging: wilc1000: rename u8WepKeylen in host_int_add_wep_key_bss_ap
[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;
c96debf1 384 wid.val = (s8 *)&pstrHostIfSetOperationMode->mode;
45102f83 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
c96debf1 390 if ((pstrHostIfSetOperationMode->mode) == 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 }
ae5e4522 479 memcpy(mac_buf, pstrHostIfSetMacAddress->mac_addr, 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;
6ceba0af 506 wid.val = pstrHostIfGetMacAddress->mac_addr;
45102f83 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
70793b2a
LK
825 hif_drv->usr_scan_req.pfUserScanResult = pstrHostIFscanAttr->result;
826 hif_drv->usr_scan_req.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
70793b2a 844 hif_drv->usr_scan_req.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
70793b2a
LK
970 if (hif_drv->usr_scan_req.pfUserScanResult) {
971 hif_drv->usr_scan_req.pfUserScanResult(enuEvent, NULL,
972 hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
973 hif_drv->usr_scan_req.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) {
f8b17132
LK
1007 hif_drv->usr_conn_req.pu8bssid = kmalloc(6, GFP_KERNEL);
1008 memcpy(hif_drv->usr_conn_req.pu8bssid, pstrHostIFconnectAttr->bssid, 6);
c5c77ba1
JK
1009 }
1010
f8b17132 1011 hif_drv->usr_conn_req.ssidLen = pstrHostIFconnectAttr->ssid_len;
91109e11 1012 if (pstrHostIFconnectAttr->ssid) {
f8b17132
LK
1013 hif_drv->usr_conn_req.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
1014 memcpy(hif_drv->usr_conn_req.pu8ssid,
8c8360b3
LK
1015 pstrHostIFconnectAttr->ssid,
1016 pstrHostIFconnectAttr->ssid_len);
f8b17132 1017 hif_drv->usr_conn_req.pu8ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
c5c77ba1
JK
1018 }
1019
f8b17132 1020 hif_drv->usr_conn_req.ConnReqIEsLen = pstrHostIFconnectAttr->ies_len;
91109e11 1021 if (pstrHostIFconnectAttr->ies) {
f8b17132
LK
1022 hif_drv->usr_conn_req.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1023 memcpy(hif_drv->usr_conn_req.pu8ConnReqIEs,
8c8360b3
LK
1024 pstrHostIFconnectAttr->ies,
1025 pstrHostIFconnectAttr->ies_len);
c5c77ba1
JK
1026 }
1027
f8b17132
LK
1028 hif_drv->usr_conn_req.u8security = pstrHostIFconnectAttr->security;
1029 hif_drv->usr_conn_req.tenuAuth_type = pstrHostIFconnectAttr->auth_type;
1030 hif_drv->usr_conn_req.pfUserConnectResult = pstrHostIFconnectAttr->result;
1031 hif_drv->usr_conn_req.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;
f8b17132
LK
1054 strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.pu8ConnReqIEs;
1055 strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ConnReqIEsLen;
c5c77ba1
JK
1056 u32WidsCount++;
1057
f7bbd9cf 1058 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
f8b17132 1059 info_element_size = hif_drv->usr_conn_req.ConnReqIEsLen;
dfef7b84 1060 info_element = kmalloc(info_element_size, GFP_KERNEL);
f8b17132 1061 memcpy(info_element, hif_drv->usr_conn_req.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);
f8b17132 1068 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.u8security;
c5c77ba1
JK
1069 u32WidsCount++;
1070
f7bbd9cf 1071 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
f8b17132 1072 mode_11i = hif_drv->usr_conn_req.u8security;
c5c77ba1 1073
f8b17132 1074 PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", hif_drv->usr_conn_req.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);
f8b17132 1079 strWIDList[u32WidsCount].val = (s8 *)(&hif_drv->usr_conn_req.tenuAuth_type);
c5c77ba1
JK
1080 u32WidsCount++;
1081
f7bbd9cf 1082 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
f8b17132 1083 auth_type = (u8)hif_drv->usr_conn_req.tenuAuth_type;
c5c77ba1 1084
f8b17132 1085 PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", hif_drv->usr_conn_req.tenuAuth_type);
c5c77ba1 1086 PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n",
f8b17132 1087 hif_drv->usr_conn_req.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;
f8b17132 1144 hif_drv->usr_conn_req.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
f8b17132
LK
1334 if (hif_drv->usr_conn_req.pfUserConnectResult) {
1335 if (hif_drv->usr_conn_req.pu8bssid) {
d00d2ba3 1336 memcpy(strConnectInfo.au8bssid,
f8b17132 1337 hif_drv->usr_conn_req.pu8bssid, 6);
c5c77ba1
JK
1338 }
1339
f8b17132
LK
1340 if (hif_drv->usr_conn_req.pu8ConnReqIEs) {
1341 strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen;
1342 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL);
d00d2ba3 1343 memcpy(strConnectInfo.pu8ReqIEs,
f8b17132
LK
1344 hif_drv->usr_conn_req.pu8ConnReqIEs,
1345 hif_drv->usr_conn_req.ConnReqIEsLen);
c5c77ba1
JK
1346 }
1347
f8b17132
LK
1348 hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1349 &strConnectInfo,
1350 MAC_DISCONNECTED,
1351 NULL,
1352 hif_drv->usr_conn_req.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
f8b17132
LK
1372 hif_drv->usr_conn_req.ssidLen = 0;
1373 kfree(hif_drv->usr_conn_req.pu8ssid);
1374 kfree(hif_drv->usr_conn_req.pu8bssid);
1375 hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1376 kfree(hif_drv->usr_conn_req.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
70793b2a 1405 if (hif_drv->usr_scan_req.pfUserScanResult) {
c5c77ba1 1406 PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n");
b021b80b 1407 parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
91109e11 1408 if ((!pstrNetworkInfo) ||
70793b2a 1409 (!hif_drv->usr_scan_req.pfUserScanResult)) {
24db713f 1410 PRINT_ER("driver is null\n");
31390eec 1411 result = -EINVAL;
24db713f 1412 goto done;
c5c77ba1
JK
1413 }
1414
70793b2a
LK
1415 for (i = 0; i < hif_drv->usr_scan_req.u32RcvdChCount; i++) {
1416 if ((hif_drv->usr_scan_req.astrFoundNetworkInfo[i].au8bssid) &&
91109e11 1417 (pstrNetworkInfo->au8bssid)) {
70793b2a 1418 if (memcmp(hif_drv->usr_scan_req.astrFoundNetworkInfo[i].au8bssid,
8c8360b3 1419 pstrNetworkInfo->au8bssid, 6) == 0) {
70793b2a 1420 if (pstrNetworkInfo->s8rssi <= hif_drv->usr_scan_req.astrFoundNetworkInfo[i].s8rssi) {
c5c77ba1
JK
1421 PRINT_D(HOSTINF_DBG, "Network previously discovered\n");
1422 goto done;
1423 } else {
70793b2a 1424 hif_drv->usr_scan_req.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
70793b2a
LK
1435 if (hif_drv->usr_scan_req.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
1436 hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi;
c5c77ba1 1437
70793b2a 1438 if (hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid &&
91109e11 1439 pstrNetworkInfo->au8bssid) {
70793b2a 1440 memcpy(hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid,
8c8360b3 1441 pstrNetworkInfo->au8bssid, 6);
c5c77ba1 1442
70793b2a 1443 hif_drv->usr_scan_req.u32RcvdChCount++;
c5c77ba1 1444
72ed4dc7 1445 pstrNetworkInfo->bNewNetwork = true;
c5c77ba1 1446 pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
c5c77ba1 1447
70793b2a
LK
1448 hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1449 hif_drv->usr_scan_req.u32UserScanPvoid,
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;
70793b2a
LK
1457 hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1458 hif_drv->usr_scan_req.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) ||
70793b2a 1499 hif_drv->usr_scan_req.pfUserScanResult) {
91109e11 1500 if (!pstrRcvdGnrlAsyncInfo->buffer ||
f8b17132 1501 !hif_drv->usr_conn_req.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
f8b17132 1576 if (hif_drv->usr_conn_req.pu8bssid) {
c5c77ba1 1577 PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n");
f8b17132 1578 memcpy(strConnectInfo.au8bssid, hif_drv->usr_conn_req.pu8bssid, 6);
c5c77ba1
JK
1579
1580 if ((u8MacStatus == MAC_CONNECTED) &&
1581 (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
a4ab1ade 1582 memcpy(hif_drv->au8AssociatedBSSID,
f8b17132 1583 hif_drv->usr_conn_req.pu8bssid, ETH_ALEN);
c5c77ba1
JK
1584 }
1585 }
1586
f8b17132
LK
1587 if (hif_drv->usr_conn_req.pu8ConnReqIEs) {
1588 strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen;
1589 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL);
d00d2ba3 1590 memcpy(strConnectInfo.pu8ReqIEs,
f8b17132
LK
1591 hif_drv->usr_conn_req.pu8ConnReqIEs,
1592 hif_drv->usr_conn_req.ConnReqIEsLen);
c5c77ba1
JK
1593 }
1594
a4ab1ade 1595 del_timer(&hif_drv->hConnectTimer);
f8b17132
LK
1596 hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1597 &strConnectInfo,
1598 u8MacStatus,
1599 NULL,
1600 hif_drv->usr_conn_req.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;
f8b17132
LK
1624 hif_drv->usr_conn_req.ssidLen = 0;
1625 kfree(hif_drv->usr_conn_req.pu8ssid);
1626 kfree(hif_drv->usr_conn_req.pu8bssid);
1627 hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1628 kfree(hif_drv->usr_conn_req.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
70793b2a 1635 if (hif_drv->usr_scan_req.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
f8b17132 1645 if (hif_drv->usr_conn_req.pfUserConnectResult) {
72ed4dc7 1646 g_obtainingIP = false;
a4ab1ade 1647 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1 1648
f8b17132
LK
1649 hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1650 NULL,
1651 0,
1652 &strDisconnectNotifInfo,
1653 hif_drv->usr_conn_req.u32UserConnectPvoid);
c5c77ba1 1654 } else {
03b2d5e7 1655 PRINT_ER("Connect result callback function is NULL\n");
c5c77ba1
JK
1656 }
1657
a4ab1ade 1658 eth_zero_addr(hif_drv->au8AssociatedBSSID);
c5c77ba1 1659
f8b17132
LK
1660 hif_drv->usr_conn_req.ssidLen = 0;
1661 kfree(hif_drv->usr_conn_req.pu8ssid);
1662 kfree(hif_drv->usr_conn_req.pu8bssid);
1663 hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1664 kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
c5c77ba1 1665
91109e11 1666 if (join_req && join_req_drv == hif_drv) {
044a6410
LK
1667 kfree(join_req);
1668 join_req = NULL;
c5c77ba1 1669 }
48ce2465 1670
91109e11 1671 if (info_element && join_req_drv == hif_drv) {
48ce2465
LK
1672 kfree(info_element);
1673 info_element = NULL;
c5c77ba1
JK
1674 }
1675
a4ab1ade 1676 hif_drv->enuHostIFstate = HOST_IF_IDLE;
ca8540e4 1677 scan_while_connected = false;
c5c77ba1
JK
1678
1679 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
70793b2a 1680 (hif_drv->usr_scan_req.pfUserScanResult)) {
c5c77ba1 1681 PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n");
03b2d5e7 1682 PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n");
ae4dfa57 1683
a4ab1ade 1684 del_timer(&hif_drv->hScanTimer);
70793b2a 1685 if (hif_drv->usr_scan_req.pfUserScanResult)
a4ab1ade 1686 Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
c5c77ba1 1687 }
c5c77ba1
JK
1688 }
1689
95f840fb
SB
1690 kfree(pstrRcvdGnrlAsyncInfo->buffer);
1691 pstrRcvdGnrlAsyncInfo->buffer = NULL;
c5c77ba1 1692
31390eec 1693 return result;
c5c77ba1
JK
1694}
1695
a4ab1ade 1696static int Handle_Key(struct host_if_drv *hif_drv,
c98387a5 1697 struct key_attr *pstrHostIFkeyAttr)
c5c77ba1 1698{
31390eec 1699 s32 result = 0;
45102f83 1700 struct wid wid;
e9e0c260 1701 struct wid strWIDList[5];
63d03e47
GKH
1702 u8 i;
1703 u8 *pu8keybuf;
ca356ada
CL
1704 s8 s8idxarray[1];
1705 s8 ret = 0;
c5c77ba1 1706
8e9f427a 1707 switch (pstrHostIFkeyAttr->type) {
c5c77ba1
JK
1708 case WEP:
1709
0d17e382 1710 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
c5c77ba1 1711 PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
bafaa696 1712 PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", pstrHostIFkeyAttr->attr.wep.index);
daaf16ba 1713 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1714 strWIDList[0].type = WID_CHAR;
2fd3e443 1715 strWIDList[0].size = sizeof(char);
bafaa696 1716 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
c5c77ba1 1717
daaf16ba 1718 strWIDList[1].id = WID_AUTH_TYPE;
416d8321 1719 strWIDList[1].type = WID_CHAR;
2fd3e443 1720 strWIDList[1].size = sizeof(char);
bafaa696 1721 strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
c5c77ba1 1722
daaf16ba 1723 strWIDList[2].id = (u16)WID_KEY_ID;
416d8321 1724 strWIDList[2].type = WID_CHAR;
c5c77ba1 1725
bafaa696 1726 strWIDList[2].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
2fd3e443 1727 strWIDList[2].size = sizeof(char);
c5c77ba1 1728
543f5b13
SB
1729 pu8keybuf = kmemdup(pstrHostIFkeyAttr->attr.wep.key,
1730 pstrHostIFkeyAttr->attr.wep.key_len,
1731 GFP_KERNEL);
c5c77ba1
JK
1732
1733 if (pu8keybuf == NULL) {
1734 PRINT_ER("No buffer to send Key\n");
9081987d 1735 return -ENOMEM;
c5c77ba1
JK
1736 }
1737
73b2e381 1738 kfree(pstrHostIFkeyAttr->attr.wep.key);
c5c77ba1 1739
daaf16ba 1740 strWIDList[3].id = (u16)WID_WEP_KEY_VALUE;
416d8321 1741 strWIDList[3].type = WID_STR;
73b2e381 1742 strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len;
900bb4a6 1743 strWIDList[3].val = (s8 *)pu8keybuf;
c5c77ba1 1744
31390eec 1745 result = send_config_pkt(SET_CFG, strWIDList, 4,
8c8360b3 1746 get_id_from_handler(hif_drv));
49188af2 1747 kfree(pu8keybuf);
c5c77ba1 1748 }
c5c77ba1 1749
0d17e382 1750 if (pstrHostIFkeyAttr->action & ADDKEY) {
c5c77ba1 1751 PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
73b2e381 1752 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
91109e11 1753 if (!pu8keybuf) {
c5c77ba1 1754 PRINT_ER("No buffer to send Key\n");
9081987d 1755 return -ENOMEM;
c5c77ba1 1756 }
73b2e381
LK
1757 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1758 memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1759 memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
8c8360b3 1760 pstrHostIFkeyAttr->attr.wep.key_len);
73b2e381 1761 kfree(pstrHostIFkeyAttr->attr.wep.key);
c5c77ba1 1762
45102f83
LK
1763 wid.id = (u16)WID_ADD_WEP_KEY;
1764 wid.type = WID_STR;
1765 wid.val = (s8 *)pu8keybuf;
1766 wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
c5c77ba1 1767
45102f83 1768 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1769 get_id_from_handler(hif_drv));
49188af2 1770 kfree(pu8keybuf);
0d17e382 1771 } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
c5c77ba1 1772 PRINT_D(HOSTINF_DBG, "Removing key\n");
45102f83
LK
1773 wid.id = (u16)WID_REMOVE_WEP_KEY;
1774 wid.type = WID_STR;
c5c77ba1 1775
73b2e381 1776 s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
45102f83
LK
1777 wid.val = s8idxarray;
1778 wid.size = 1;
c5c77ba1 1779
45102f83 1780 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1781 get_id_from_handler(hif_drv));
c5c77ba1 1782 } else {
45102f83
LK
1783 wid.id = (u16)WID_KEY_ID;
1784 wid.type = WID_CHAR;
1785 wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1786 wid.size = sizeof(char);
c5c77ba1
JK
1787
1788 PRINT_D(HOSTINF_DBG, "Setting default key index\n");
1789
45102f83 1790 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1791 get_id_from_handler(hif_drv));
c5c77ba1 1792 }
a4ab1ade 1793 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1794 break;
1795
1796 case WPARxGtk:
0d17e382 1797 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
b156f1ed 1798 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
91109e11 1799 if (!pu8keybuf) {
c5c77ba1 1800 PRINT_ER("No buffer to send RxGTK Key\n");
9081987d 1801 ret = -ENOMEM;
c5c77ba1
JK
1802 goto _WPARxGtk_end_case_;
1803 }
1804
91109e11 1805 if (pstrHostIFkeyAttr->attr.wpa.seq)
0e74c009 1806 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
c5c77ba1 1807
e2dfbac5 1808 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1809 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1810 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1811 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1812
daaf16ba 1813 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1814 strWIDList[0].type = WID_CHAR;
2fd3e443 1815 strWIDList[0].size = sizeof(char);
bafaa696 1816 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
c5c77ba1 1817
daaf16ba 1818 strWIDList[1].id = (u16)WID_ADD_RX_GTK;
416d8321 1819 strWIDList[1].type = WID_STR;
900bb4a6 1820 strWIDList[1].val = (s8 *)pu8keybuf;
2fd3e443 1821 strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
c5c77ba1 1822
31390eec 1823 result = send_config_pkt(SET_CFG, strWIDList, 2,
8c8360b3 1824 get_id_from_handler(hif_drv));
c5c77ba1 1825
49188af2 1826 kfree(pu8keybuf);
a4ab1ade 1827 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1828 }
1829
0d17e382 1830 if (pstrHostIFkeyAttr->action & ADDKEY) {
c5c77ba1
JK
1831 PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
1832
b156f1ed 1833 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
c5c77ba1
JK
1834 if (pu8keybuf == NULL) {
1835 PRINT_ER("No buffer to send RxGTK Key\n");
9081987d 1836 ret = -ENOMEM;
c5c77ba1
JK
1837 goto _WPARxGtk_end_case_;
1838 }
1839
a4ab1ade
TC
1840 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
1841 memcpy(pu8keybuf, hif_drv->au8AssociatedBSSID, ETH_ALEN);
78174ada 1842 else
03b2d5e7 1843 PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED\n");
c5c77ba1 1844
0e74c009 1845 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
e2dfbac5 1846 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1847 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1848 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1849 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1850
45102f83
LK
1851 wid.id = (u16)WID_ADD_RX_GTK;
1852 wid.type = WID_STR;
1853 wid.val = (s8 *)pu8keybuf;
1854 wid.size = RX_MIC_KEY_MSG_LEN;
c5c77ba1 1855
45102f83 1856 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1857 get_id_from_handler(hif_drv));
c5c77ba1 1858
49188af2 1859 kfree(pu8keybuf);
a4ab1ade 1860 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1861 }
1862_WPARxGtk_end_case_:
124968fc 1863 kfree(pstrHostIFkeyAttr->attr.wpa.key);
0e74c009 1864 kfree(pstrHostIFkeyAttr->attr.wpa.seq);
9081987d 1865 if (ret)
c5c77ba1
JK
1866 return ret;
1867
1868 break;
1869
1870 case WPAPtk:
0d17e382 1871 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
f3052587 1872 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
91109e11 1873 if (!pu8keybuf) {
c5c77ba1 1874 PRINT_ER("No buffer to send PTK Key\n");
9081987d 1875 ret = -ENOMEM;
c5c77ba1 1876 goto _WPAPtk_end_case_;
c5c77ba1
JK
1877 }
1878
248080aa 1879 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
e2dfbac5 1880 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1881 memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1882 memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1883 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1884
daaf16ba 1885 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1886 strWIDList[0].type = WID_CHAR;
2fd3e443 1887 strWIDList[0].size = sizeof(char);
bafaa696 1888 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
c5c77ba1 1889
daaf16ba 1890 strWIDList[1].id = (u16)WID_ADD_PTK;
416d8321 1891 strWIDList[1].type = WID_STR;
900bb4a6 1892 strWIDList[1].val = (s8 *)pu8keybuf;
2fd3e443 1893 strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
c5c77ba1 1894
31390eec 1895 result = send_config_pkt(SET_CFG, strWIDList, 2,
8c8360b3 1896 get_id_from_handler(hif_drv));
49188af2 1897 kfree(pu8keybuf);
a4ab1ade 1898 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1 1899 }
0d17e382 1900 if (pstrHostIFkeyAttr->action & ADDKEY) {
f3052587 1901 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
91109e11 1902 if (!pu8keybuf) {
c5c77ba1 1903 PRINT_ER("No buffer to send PTK Key\n");
9081987d 1904 ret = -ENOMEM;
c5c77ba1 1905 goto _WPAPtk_end_case_;
c5c77ba1
JK
1906 }
1907
248080aa 1908 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
6acf2919 1909 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1910 memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1911 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1912
45102f83
LK
1913 wid.id = (u16)WID_ADD_PTK;
1914 wid.type = WID_STR;
1915 wid.val = (s8 *)pu8keybuf;
1916 wid.size = PTK_KEY_MSG_LEN;
c5c77ba1 1917
45102f83 1918 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1919 get_id_from_handler(hif_drv));
49188af2 1920 kfree(pu8keybuf);
a4ab1ade 1921 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1922 }
1923
1924_WPAPtk_end_case_:
124968fc 1925 kfree(pstrHostIFkeyAttr->attr.wpa.key);
9081987d 1926 if (ret)
c5c77ba1
JK
1927 return ret;
1928
1929 break;
1930
c5c77ba1
JK
1931 case PMKSA:
1932
1933 PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n");
1934
73b2e381 1935 pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
91109e11 1936 if (!pu8keybuf) {
c5c77ba1 1937 PRINT_ER("No buffer to send PMKSA Key\n");
9081987d 1938 return -ENOMEM;
c5c77ba1
JK
1939 }
1940
73b2e381 1941 pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
c5c77ba1 1942
73b2e381
LK
1943 for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1944 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1945 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
c5c77ba1
JK
1946 }
1947
45102f83
LK
1948 wid.id = (u16)WID_PMKID_INFO;
1949 wid.type = WID_STR;
1950 wid.val = (s8 *)pu8keybuf;
1951 wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
c5c77ba1 1952
45102f83 1953 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1954 get_id_from_handler(hif_drv));
c5c77ba1 1955
49188af2 1956 kfree(pu8keybuf);
c5c77ba1
JK
1957 break;
1958 }
1959
31390eec 1960 if (result)
c5c77ba1
JK
1961 PRINT_ER("Failed to send key config packet\n");
1962
31390eec 1963 return result;
c5c77ba1
JK
1964}
1965
a4ab1ade 1966static void Handle_Disconnect(struct host_if_drv *hif_drv)
c5c77ba1 1967{
45102f83 1968 struct wid wid;
c5c77ba1 1969
31390eec 1970 s32 result = 0;
d85f5326 1971 u16 u16DummyReasonCode = 0;
c5c77ba1 1972
45102f83
LK
1973 wid.id = (u16)WID_DISCONNECT;
1974 wid.type = WID_CHAR;
1975 wid.val = (s8 *)&u16DummyReasonCode;
1976 wid.size = sizeof(char);
c5c77ba1 1977
c5c77ba1
JK
1978 PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1979
72ed4dc7 1980 g_obtainingIP = false;
a4ab1ade 1981 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1 1982
281dd5ac 1983 eth_zero_addr(u8ConnectedSSID);
c5c77ba1 1984
45102f83 1985 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 1986 get_id_from_handler(hif_drv));
c5c77ba1 1987
31390eec 1988 if (result) {
c5c77ba1 1989 PRINT_ER("Failed to send dissconect config packet\n");
c5c77ba1
JK
1990 } else {
1991 tstrDisconnectNotifInfo strDisconnectNotifInfo;
1992
2cc46837 1993 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
c5c77ba1
JK
1994
1995 strDisconnectNotifInfo.u16reason = 0;
1996 strDisconnectNotifInfo.ie = NULL;
1997 strDisconnectNotifInfo.ie_len = 0;
1998
70793b2a 1999 if (hif_drv->usr_scan_req.pfUserScanResult) {
a4ab1ade 2000 del_timer(&hif_drv->hScanTimer);
70793b2a
LK
2001 hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
2002 hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
c5c77ba1 2003
70793b2a 2004 hif_drv->usr_scan_req.pfUserScanResult = NULL;
c5c77ba1
JK
2005 }
2006
f8b17132 2007 if (hif_drv->usr_conn_req.pfUserConnectResult) {
a4ab1ade 2008 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
c5c77ba1 2009 PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n");
a4ab1ade 2010 del_timer(&hif_drv->hConnectTimer);
c5c77ba1
JK
2011 }
2012
f8b17132
LK
2013 hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
2014 0, &strDisconnectNotifInfo, hif_drv->usr_conn_req.u32UserConnectPvoid);
c5c77ba1 2015 } else {
f8b17132 2016 PRINT_ER("usr_conn_req.pfUserConnectResult = NULL\n");
c5c77ba1
JK
2017 }
2018
ca8540e4 2019 scan_while_connected = false;
c5c77ba1 2020
a4ab1ade 2021 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 2022
a4ab1ade 2023 eth_zero_addr(hif_drv->au8AssociatedBSSID);
c5c77ba1 2024
f8b17132
LK
2025 hif_drv->usr_conn_req.ssidLen = 0;
2026 kfree(hif_drv->usr_conn_req.pu8ssid);
2027 kfree(hif_drv->usr_conn_req.pu8bssid);
2028 hif_drv->usr_conn_req.ConnReqIEsLen = 0;
2029 kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
c5c77ba1 2030
91109e11 2031 if (join_req && join_req_drv == hif_drv) {
044a6410
LK
2032 kfree(join_req);
2033 join_req = NULL;
c5c77ba1 2034 }
48ce2465 2035
91109e11 2036 if (info_element && join_req_drv == hif_drv) {
48ce2465
LK
2037 kfree(info_element);
2038 info_element = NULL;
c5c77ba1 2039 }
c5c77ba1
JK
2040 }
2041
a4ab1ade 2042 up(&hif_drv->hSemTestDisconnectBlock);
c5c77ba1
JK
2043}
2044
a4ab1ade 2045void resolve_disconnect_aberration(struct host_if_drv *hif_drv)
c5c77ba1 2046{
a4ab1ade 2047 if (!hif_drv)
c5c77ba1 2048 return;
a4ab1ade 2049 if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (hif_drv->enuHostIFstate == HOST_IF_CONNECTING)) {
c5c77ba1 2050 PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n");
a4ab1ade 2051 host_int_disconnect(hif_drv, 1);
c5c77ba1
JK
2052 }
2053}
c5c77ba1 2054
a4ab1ade 2055static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
c5c77ba1 2056{
31390eec 2057 s32 result = 0;
45102f83 2058 struct wid wid;
78c87591 2059
45102f83
LK
2060 wid.id = (u16)WID_CURRENT_CHANNEL;
2061 wid.type = WID_CHAR;
2062 wid.val = (s8 *)&ch_no;
2063 wid.size = sizeof(char);
c5c77ba1
JK
2064
2065 PRINT_D(HOSTINF_DBG, "Getting channel value\n");
2066
45102f83 2067 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2068 get_id_from_handler(hif_drv));
ae4dfa57 2069
31390eec 2070 if (result) {
c5c77ba1 2071 PRINT_ER("Failed to get channel number\n");
31390eec 2072 result = -EFAULT;
c5c77ba1
JK
2073 }
2074
a4ab1ade 2075 up(&hif_drv->hSemGetCHNL);
c5c77ba1 2076
31390eec 2077 return result;
c5c77ba1
JK
2078}
2079
a4ab1ade 2080static void Handle_GetRssi(struct host_if_drv *hif_drv)
c5c77ba1 2081{
31390eec 2082 s32 result = 0;
45102f83 2083 struct wid wid;
c5c77ba1 2084
45102f83
LK
2085 wid.id = (u16)WID_RSSI;
2086 wid.type = WID_CHAR;
2087 wid.val = &rssi;
2088 wid.size = sizeof(char);
c5c77ba1 2089
c5c77ba1
JK
2090 PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
2091
45102f83 2092 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2093 get_id_from_handler(hif_drv));
31390eec 2094 if (result) {
c5c77ba1 2095 PRINT_ER("Failed to get RSSI value\n");
31390eec 2096 result = -EFAULT;
c5c77ba1
JK
2097 }
2098
a4ab1ade 2099 up(&hif_drv->hSemGetRSSI);
c5c77ba1
JK
2100}
2101
a4ab1ade 2102static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
c5c77ba1 2103{
31390eec 2104 s32 result = 0;
45102f83 2105 struct wid wid;
c5c77ba1 2106
75327a02 2107 link_speed = 0;
c5c77ba1 2108
45102f83
LK
2109 wid.id = (u16)WID_LINKSPEED;
2110 wid.type = WID_CHAR;
2111 wid.val = &link_speed;
2112 wid.size = sizeof(char);
ae4dfa57 2113
c5c77ba1
JK
2114 PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
2115
45102f83 2116 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2117 get_id_from_handler(hif_drv));
31390eec 2118 if (result) {
c5c77ba1 2119 PRINT_ER("Failed to get LINKSPEED value\n");
31390eec 2120 result = -EFAULT;
c5c77ba1
JK
2121 }
2122
bafaa696 2123 up(&hif_drv->hSemGetLINKSPEED);
c5c77ba1
JK
2124}
2125
a4ab1ade 2126s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
c5c77ba1 2127{
e9e0c260 2128 struct wid strWIDList[5];
31390eec 2129 u32 u32WidsCount = 0, result = 0;
c5c77ba1 2130
daaf16ba 2131 strWIDList[u32WidsCount].id = WID_LINKSPEED;
416d8321 2132 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 2133 strWIDList[u32WidsCount].size = sizeof(char);
bafaa696 2134 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u8LinkSpeed;
c5c77ba1
JK
2135 u32WidsCount++;
2136
daaf16ba 2137 strWIDList[u32WidsCount].id = WID_RSSI;
416d8321 2138 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 2139 strWIDList[u32WidsCount].size = sizeof(char);
bafaa696 2140 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->s8RSSI;
c5c77ba1
JK
2141 u32WidsCount++;
2142
daaf16ba 2143 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
416d8321 2144 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2145 strWIDList[u32WidsCount].size = sizeof(u32);
bafaa696 2146 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxCount;
c5c77ba1
JK
2147 u32WidsCount++;
2148
daaf16ba 2149 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
416d8321 2150 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2151 strWIDList[u32WidsCount].size = sizeof(u32);
bafaa696 2152 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32RxCount;
c5c77ba1
JK
2153 u32WidsCount++;
2154
daaf16ba 2155 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
416d8321 2156 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2157 strWIDList[u32WidsCount].size = sizeof(u32);
bafaa696 2158 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxFailureCount;
c5c77ba1
JK
2159 u32WidsCount++;
2160
31390eec 2161 result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount,
8c8360b3 2162 get_id_from_handler(hif_drv));
c5c77ba1 2163
31390eec 2164 if (result)
c5c77ba1 2165 PRINT_ER("Failed to send scan paramters config packet\n");
24db713f 2166
2d25af87 2167 up(&hif_sema_wait_response);
c5c77ba1 2168 return 0;
c5c77ba1
JK
2169}
2170
a4ab1ade 2171static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
3d1eac04 2172 struct sta_inactive_t *strHostIfStaInactiveT)
c5c77ba1 2173{
31390eec 2174 s32 result = 0;
63d03e47 2175 u8 *stamac;
45102f83 2176 struct wid wid;
c5c77ba1 2177
45102f83
LK
2178 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
2179 wid.type = WID_STR;
2180 wid.size = ETH_ALEN;
2181 wid.val = kmalloc(wid.size, GFP_KERNEL);
c5c77ba1 2182
45102f83 2183 stamac = wid.val;
d00d2ba3 2184 memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
c5c77ba1 2185
c5c77ba1
JK
2186 PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
2187
45102f83 2188 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2189 get_id_from_handler(hif_drv));
ae4dfa57 2190
31390eec 2191 if (result) {
c5c77ba1 2192 PRINT_ER("Failed to SET incative time\n");
24db713f 2193 return -EFAULT;
c5c77ba1
JK
2194 }
2195
45102f83
LK
2196 wid.id = (u16)WID_GET_INACTIVE_TIME;
2197 wid.type = WID_INT;
2198 wid.val = (s8 *)&inactive_time;
2199 wid.size = sizeof(u32);
c5c77ba1 2200
45102f83 2201 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 2202 get_id_from_handler(hif_drv));
ae4dfa57 2203
31390eec 2204 if (result) {
c5c77ba1 2205 PRINT_ER("Failed to get incative time\n");
24db713f 2206 return -EFAULT;
c5c77ba1
JK
2207 }
2208
ad26906f 2209 PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time);
c5c77ba1 2210
a4ab1ade 2211 up(&hif_drv->hSemInactiveTime);
c5c77ba1 2212
31390eec 2213 return result;
c5c77ba1
JK
2214}
2215
a4ab1ade 2216static void Handle_AddBeacon(struct host_if_drv *hif_drv,
7f33fecd 2217 struct beacon_attr *pstrSetBeaconParam)
c5c77ba1 2218{
31390eec 2219 s32 result = 0;
45102f83 2220 struct wid wid;
63d03e47 2221 u8 *pu8CurrByte;
78c87591 2222
c5c77ba1
JK
2223 PRINT_D(HOSTINF_DBG, "Adding BEACON\n");
2224
45102f83
LK
2225 wid.id = (u16)WID_ADD_BEACON;
2226 wid.type = WID_BIN;
2227 wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
2228 wid.val = kmalloc(wid.size, GFP_KERNEL);
2229 if (!wid.val)
24db713f 2230 goto ERRORHANDLER;
c5c77ba1 2231
45102f83 2232 pu8CurrByte = wid.val;
12262dda
LK
2233 *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2234 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2235 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2236 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
c5c77ba1 2237
e76ab770
LK
2238 *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2239 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2240 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2241 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
c5c77ba1 2242
51c66185
LK
2243 *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2244 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2245 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2246 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
c5c77ba1 2247
8ce528b9 2248 memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
51c66185 2249 pu8CurrByte += pstrSetBeaconParam->head_len;
c5c77ba1 2250
030c57e2
LK
2251 *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2252 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2253 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2254 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
c5c77ba1 2255
7dbcb6d3
LK
2256 if (pstrSetBeaconParam->tail > 0)
2257 memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
030c57e2 2258 pu8CurrByte += pstrSetBeaconParam->tail_len;
c5c77ba1 2259
45102f83 2260 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2261 get_id_from_handler(hif_drv));
31390eec 2262 if (result)
c5c77ba1 2263 PRINT_ER("Failed to send add beacon config packet\n");
c5c77ba1 2264
24db713f 2265ERRORHANDLER:
45102f83 2266 kfree(wid.val);
8ce528b9 2267 kfree(pstrSetBeaconParam->head);
7dbcb6d3 2268 kfree(pstrSetBeaconParam->tail);
c5c77ba1
JK
2269}
2270
a4ab1ade 2271static void Handle_DelBeacon(struct host_if_drv *hif_drv)
c5c77ba1 2272{
31390eec 2273 s32 result = 0;
45102f83 2274 struct wid wid;
63d03e47 2275 u8 *pu8CurrByte;
78c87591 2276
45102f83
LK
2277 wid.id = (u16)WID_DEL_BEACON;
2278 wid.type = WID_CHAR;
2279 wid.size = sizeof(char);
2280 wid.val = &del_beacon;
c5c77ba1 2281
45102f83 2282 if (!wid.val)
24db713f 2283 return;
c5c77ba1 2284
45102f83 2285 pu8CurrByte = wid.val;
c5c77ba1
JK
2286
2287 PRINT_D(HOSTINF_DBG, "Deleting BEACON\n");
c5c77ba1 2288
45102f83 2289 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2290 get_id_from_handler(hif_drv));
31390eec 2291 if (result)
c5c77ba1 2292 PRINT_ER("Failed to send delete beacon config packet\n");
c5c77ba1
JK
2293}
2294
6a89ba9c
TC
2295static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2296 struct add_sta_param *pstrStationParam)
c5c77ba1 2297{
63d03e47 2298 u8 *pu8CurrByte;
c5c77ba1
JK
2299
2300 pu8CurrByte = pu8Buffer;
2301
2302 PRINT_D(HOSTINF_DBG, "Packing STA params\n");
d00d2ba3 2303 memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN);
c5c77ba1
JK
2304 pu8CurrByte += ETH_ALEN;
2305
2306 *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF;
2307 *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF;
2308
2309 *pu8CurrByte++ = pstrStationParam->u8NumRates;
2b9d5b48 2310 if (pstrStationParam->u8NumRates > 0)
d00d2ba3 2311 memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates);
c5c77ba1
JK
2312 pu8CurrByte += pstrStationParam->u8NumRates;
2313
2314 *pu8CurrByte++ = pstrStationParam->bIsHTSupported;
2315 *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF;
2316 *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF;
2317
2318 *pu8CurrByte++ = pstrStationParam->u8AmpduParams;
d00d2ba3 2319 memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE);
c5c77ba1
JK
2320 pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2321
2322 *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF;
2323 *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF;
2324
2325 *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF;
2326 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF;
2327 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF;
2328 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF;
2329
2330 *pu8CurrByte++ = pstrStationParam->u8ASELCap;
2331
2332 *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF;
2333 *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF;
2334
2335 *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF;
2336 *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF;
2337
2338 return pu8CurrByte - pu8Buffer;
2339}
2340
a4ab1ade 2341static void Handle_AddStation(struct host_if_drv *hif_drv,
6a89ba9c 2342 struct add_sta_param *pstrStationParam)
c5c77ba1 2343{
31390eec 2344 s32 result = 0;
45102f83 2345 struct wid wid;
63d03e47 2346 u8 *pu8CurrByte;
78c87591 2347
c5c77ba1 2348 PRINT_D(HOSTINF_DBG, "Handling add station\n");
45102f83
LK
2349 wid.id = (u16)WID_ADD_STA;
2350 wid.type = WID_BIN;
2351 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
c5c77ba1 2352
45102f83
LK
2353 wid.val = kmalloc(wid.size, GFP_KERNEL);
2354 if (!wid.val)
24db713f 2355 goto ERRORHANDLER;
c5c77ba1 2356
45102f83 2357 pu8CurrByte = wid.val;
c5c77ba1
JK
2358 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2359
45102f83 2360 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2361 get_id_from_handler(hif_drv));
31390eec 2362 if (result != 0)
c5c77ba1 2363 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2364
24db713f 2365ERRORHANDLER:
969effe9 2366 kfree(pstrStationParam->pu8Rates);
45102f83 2367 kfree(wid.val);
c5c77ba1
JK
2368}
2369
a4ab1ade 2370static void Handle_DelAllSta(struct host_if_drv *hif_drv,
b4e644e4 2371 struct del_all_sta *pstrDelAllStaParam)
c5c77ba1 2372{
31390eec 2373 s32 result = 0;
45102f83 2374 struct wid wid;
63d03e47 2375 u8 *pu8CurrByte;
63d03e47 2376 u8 i;
3703480b 2377 u8 au8Zero_Buff[6] = {0};
78c87591 2378
45102f83
LK
2379 wid.id = (u16)WID_DEL_ALL_STA;
2380 wid.type = WID_STR;
2381 wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
c5c77ba1 2382
03b2d5e7 2383 PRINT_D(HOSTINF_DBG, "Handling delete station\n");
c5c77ba1 2384
45102f83
LK
2385 wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2386 if (!wid.val)
24db713f 2387 goto ERRORHANDLER;
c5c77ba1 2388
45102f83 2389 pu8CurrByte = wid.val;
c5c77ba1 2390
8ba1803f 2391 *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
c5c77ba1
JK
2392
2393 for (i = 0; i < MAX_NUM_STA; i++) {
e51b9216
LK
2394 if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2395 memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
c5c77ba1
JK
2396 else
2397 continue;
2398
2399 pu8CurrByte += ETH_ALEN;
2400 }
2401
45102f83 2402 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2403 get_id_from_handler(hif_drv));
31390eec 2404 if (result)
83cc9be5 2405 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2406
24db713f 2407ERRORHANDLER:
45102f83 2408 kfree(wid.val);
c5c77ba1 2409
2d25af87 2410 up(&hif_sema_wait_response);
c5c77ba1
JK
2411}
2412
a4ab1ade 2413static void Handle_DelStation(struct host_if_drv *hif_drv,
fb93a1e1 2414 struct del_sta *pstrDelStaParam)
c5c77ba1 2415{
31390eec 2416 s32 result = 0;
45102f83 2417 struct wid wid;
63d03e47 2418 u8 *pu8CurrByte;
c5c77ba1 2419
45102f83
LK
2420 wid.id = (u16)WID_REMOVE_STA;
2421 wid.type = WID_BIN;
2422 wid.size = ETH_ALEN;
c5c77ba1 2423
03b2d5e7 2424 PRINT_D(HOSTINF_DBG, "Handling delete station\n");
c5c77ba1 2425
45102f83
LK
2426 wid.val = kmalloc(wid.size, GFP_KERNEL);
2427 if (!wid.val)
24db713f 2428 goto ERRORHANDLER;
c5c77ba1 2429
45102f83 2430 pu8CurrByte = wid.val;
c5c77ba1 2431
e4839d39 2432 memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
c5c77ba1 2433
45102f83 2434 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2435 get_id_from_handler(hif_drv));
31390eec 2436 if (result)
83cc9be5 2437 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2438
24db713f 2439ERRORHANDLER:
45102f83 2440 kfree(wid.val);
c5c77ba1
JK
2441}
2442
a4ab1ade 2443static void Handle_EditStation(struct host_if_drv *hif_drv,
6a89ba9c 2444 struct add_sta_param *pstrStationParam)
c5c77ba1 2445{
31390eec 2446 s32 result = 0;
45102f83 2447 struct wid wid;
63d03e47 2448 u8 *pu8CurrByte;
c5c77ba1 2449
45102f83
LK
2450 wid.id = (u16)WID_EDIT_STA;
2451 wid.type = WID_BIN;
2452 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
c5c77ba1
JK
2453
2454 PRINT_D(HOSTINF_DBG, "Handling edit station\n");
45102f83
LK
2455 wid.val = kmalloc(wid.size, GFP_KERNEL);
2456 if (!wid.val)
24db713f 2457 goto ERRORHANDLER;
c5c77ba1 2458
45102f83 2459 pu8CurrByte = wid.val;
c5c77ba1
JK
2460 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2461
45102f83 2462 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2463 get_id_from_handler(hif_drv));
31390eec 2464 if (result)
c5c77ba1 2465 PRINT_ER("Failed to send edit station config packet\n");
c5c77ba1 2466
24db713f 2467ERRORHANDLER:
969effe9 2468 kfree(pstrStationParam->pu8Rates);
45102f83 2469 kfree(wid.val);
c5c77ba1 2470}
c5c77ba1 2471
a4ab1ade 2472static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
2f9c03f5 2473 struct remain_ch *pstrHostIfRemainOnChan)
c5c77ba1 2474{
31390eec 2475 s32 result = 0;
63d03e47 2476 u8 u8remain_on_chan_flag;
45102f83 2477 struct wid wid;
c5c77ba1 2478
5beef2ca 2479 if (!hif_drv->remain_on_ch_pending) {
d61f8e1e
LK
2480 hif_drv->remain_on_ch.pVoid = pstrHostIfRemainOnChan->pVoid;
2481 hif_drv->remain_on_ch.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired;
2482 hif_drv->remain_on_ch.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady;
2483 hif_drv->remain_on_ch.u16Channel = pstrHostIfRemainOnChan->u16Channel;
2484 hif_drv->remain_on_ch.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID;
c5c77ba1 2485 } else {
d61f8e1e 2486 pstrHostIfRemainOnChan->u16Channel = hif_drv->remain_on_ch.u16Channel;
c5c77ba1
JK
2487 }
2488
70793b2a 2489 if (hif_drv->usr_scan_req.pfUserScanResult) {
c5c77ba1 2490 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n");
5beef2ca 2491 hif_drv->remain_on_ch_pending = 1;
31390eec 2492 result = -EBUSY;
24db713f 2493 goto ERRORHANDLER;
c5c77ba1 2494 }
a4ab1ade 2495 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
c5c77ba1 2496 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n");
31390eec 2497 result = -EBUSY;
24db713f 2498 goto ERRORHANDLER;
c5c77ba1
JK
2499 }
2500
c5c77ba1
JK
2501 if (g_obtainingIP || connecting) {
2502 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
31390eec 2503 result = -EBUSY;
24db713f 2504 goto ERRORHANDLER;
c5c77ba1 2505 }
c5c77ba1
JK
2506
2507 PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel);
2508
72ed4dc7 2509 u8remain_on_chan_flag = true;
45102f83
LK
2510 wid.id = (u16)WID_REMAIN_ON_CHAN;
2511 wid.type = WID_STR;
2512 wid.size = 2;
2513 wid.val = kmalloc(wid.size, GFP_KERNEL);
2514 if (!wid.val) {
31390eec 2515 result = -ENOMEM;
24db713f
LK
2516 goto ERRORHANDLER;
2517 }
c5c77ba1 2518
45102f83
LK
2519 wid.val[0] = u8remain_on_chan_flag;
2520 wid.val[1] = (s8)pstrHostIfRemainOnChan->u16Channel;
c5c77ba1 2521
45102f83 2522 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2523 get_id_from_handler(hif_drv));
31390eec 2524 if (result != 0)
c5c77ba1 2525 PRINT_ER("Failed to set remain on channel\n");
c5c77ba1 2526
24db713f 2527ERRORHANDLER:
c5c77ba1
JK
2528 {
2529 P2P_LISTEN_STATE = 1;
a4ab1ade
TC
2530 hif_drv->hRemainOnChannel.data = (unsigned long)hif_drv;
2531 mod_timer(&hif_drv->hRemainOnChannel,
9eb06643
GKH
2532 jiffies +
2533 msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration));
c5c77ba1 2534
d61f8e1e
LK
2535 if (hif_drv->remain_on_ch.pRemainOnChanReady)
2536 hif_drv->remain_on_ch.pRemainOnChanReady(hif_drv->remain_on_ch.pVoid);
c5c77ba1 2537
5beef2ca
LK
2538 if (hif_drv->remain_on_ch_pending)
2539 hif_drv->remain_on_ch_pending = 0;
c5c77ba1 2540 }
31390eec
LK
2541
2542 return result;
c5c77ba1
JK
2543}
2544
a4ab1ade 2545static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
bc37c5df 2546 struct reg_frame *pstrHostIfRegisterFrame)
c5c77ba1 2547{
31390eec 2548 s32 result = 0;
45102f83 2549 struct wid wid;
63d03e47 2550 u8 *pu8CurrByte;
c5c77ba1
JK
2551
2552 PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType);
2553
45102f83
LK
2554 wid.id = (u16)WID_REGISTER_FRAME;
2555 wid.type = WID_STR;
2556 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2557 if (!wid.val)
24db713f 2558 return -ENOMEM;
c5c77ba1 2559
45102f83 2560 pu8CurrByte = wid.val;
c5c77ba1
JK
2561
2562 *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg;
2563 *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid;
bafaa696
LK
2564 memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->u16FrameType,
2565 sizeof(u16));
c5c77ba1 2566
45102f83 2567 wid.size = sizeof(u16) + 2;
c5c77ba1 2568
45102f83 2569 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2570 get_id_from_handler(hif_drv));
31390eec 2571 if (result) {
c5c77ba1 2572 PRINT_ER("Failed to frame register config packet\n");
31390eec 2573 result = -EINVAL;
c5c77ba1
JK
2574 }
2575
31390eec 2576 return result;
c5c77ba1
JK
2577}
2578
a4ab1ade 2579static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv,
2f9c03f5 2580 struct remain_ch *pstrHostIfRemainOnChan)
c5c77ba1 2581{
63d03e47 2582 u8 u8remain_on_chan_flag;
45102f83 2583 struct wid wid;
31390eec 2584 s32 result = 0;
c5c77ba1
JK
2585
2586 PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n");
2587
c5c77ba1 2588 if (P2P_LISTEN_STATE) {
72ed4dc7 2589 u8remain_on_chan_flag = false;
45102f83
LK
2590 wid.id = (u16)WID_REMAIN_ON_CHAN;
2591 wid.type = WID_STR;
2592 wid.size = 2;
2593 wid.val = kmalloc(wid.size, GFP_KERNEL);
c5c77ba1 2594
45102f83 2595 if (!wid.val)
c5c77ba1 2596 PRINT_ER("Failed to allocate memory\n");
c5c77ba1 2597
45102f83
LK
2598 wid.val[0] = u8remain_on_chan_flag;
2599 wid.val[1] = FALSE_FRMWR_CHANNEL;
c5c77ba1 2600
45102f83 2601 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2602 get_id_from_handler(hif_drv));
31390eec 2603 if (result != 0) {
c5c77ba1
JK
2604 PRINT_ER("Failed to set remain on channel\n");
2605 goto _done_;
2606 }
2607
d61f8e1e
LK
2608 if (hif_drv->remain_on_ch.pRemainOnChanExpired) {
2609 hif_drv->remain_on_ch.pRemainOnChanExpired(hif_drv->remain_on_ch.pVoid,
2610 pstrHostIfRemainOnChan->u32ListenSessionID);
c5c77ba1
JK
2611 }
2612 P2P_LISTEN_STATE = 0;
2613 } else {
2614 PRINT_D(GENERIC_DBG, "Not in listen state\n");
31390eec 2615 result = -EFAULT;
c5c77ba1
JK
2616 }
2617
2618_done_:
31390eec 2619 return result;
c5c77ba1
JK
2620}
2621
93dee8ee 2622static void ListenTimerCB(unsigned long arg)
c5c77ba1 2623{
31390eec 2624 s32 result = 0;
143eb95a 2625 struct host_if_msg msg;
a4ab1ade 2626 struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
ae4dfa57 2627
a4ab1ade 2628 del_timer(&hif_drv->hRemainOnChannel);
c5c77ba1 2629
143eb95a 2630 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 2631 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
a4ab1ade 2632 msg.drv = hif_drv;
d61f8e1e 2633 msg.body.remain_on_ch.u32ListenSessionID = hif_drv->remain_on_ch.u32ListenSessionID;
c5c77ba1 2634
31390eec
LK
2635 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2636 if (result)
24db713f 2637 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 2638}
c5c77ba1 2639
a4ab1ade 2640static void Handle_PowerManagement(struct host_if_drv *hif_drv,
5a008f1c 2641 struct power_mgmt_param *strPowerMgmtParam)
c5c77ba1 2642{
31390eec 2643 s32 result = 0;
45102f83 2644 struct wid wid;
ca356ada 2645 s8 s8PowerMode;
78c87591 2646
45102f83 2647 wid.id = (u16)WID_POWER_MANAGEMENT;
c5c77ba1 2648
047e6646 2649 if (strPowerMgmtParam->enabled)
c5c77ba1 2650 s8PowerMode = MIN_FAST_PS;
78174ada 2651 else
c5c77ba1 2652 s8PowerMode = NO_POWERSAVE;
c5c77ba1 2653 PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode);
45102f83
LK
2654 wid.val = &s8PowerMode;
2655 wid.size = sizeof(char);
c5c77ba1
JK
2656
2657 PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
2658
45102f83 2659 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2660 get_id_from_handler(hif_drv));
31390eec 2661 if (result)
c5c77ba1 2662 PRINT_ER("Failed to send power management config packet\n");
c5c77ba1
JK
2663}
2664
a4ab1ade 2665static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
641210ac 2666 struct set_multicast *strHostIfSetMulti)
c5c77ba1 2667{
31390eec 2668 s32 result = 0;
45102f83 2669 struct wid wid;
63d03e47 2670 u8 *pu8CurrByte;
c5c77ba1
JK
2671
2672 PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n");
2673
45102f83
LK
2674 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2675 wid.type = WID_BIN;
2676 wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2677 wid.val = kmalloc(wid.size, GFP_KERNEL);
2678 if (!wid.val)
24db713f 2679 goto ERRORHANDLER;
c5c77ba1 2680
45102f83 2681 pu8CurrByte = wid.val;
bae636eb
LK
2682 *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2683 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
2684 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
2685 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
c5c77ba1 2686
adab2f71
LK
2687 *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2688 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2689 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2690 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
c5c77ba1 2691
adab2f71
LK
2692 if ((strHostIfSetMulti->cnt) > 0)
2693 memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->cnt) * ETH_ALEN));
c5c77ba1 2694
45102f83 2695 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2696 get_id_from_handler(hif_drv));
31390eec 2697 if (result)
c5c77ba1 2698 PRINT_ER("Failed to send setup multicast config packet\n");
c5c77ba1 2699
24db713f 2700ERRORHANDLER:
45102f83 2701 kfree(wid.val);
c5c77ba1
JK
2702}
2703
a4ab1ade 2704static s32 Handle_AddBASession(struct host_if_drv *hif_drv,
54265472 2705 struct ba_session_info *strHostIfBASessionInfo)
c5c77ba1 2706{
31390eec 2707 s32 result = 0;
45102f83 2708 struct wid wid;
c5c77ba1
JK
2709 int AddbaTimeout = 100;
2710 char *ptr = NULL;
c5c77ba1 2711
03b2d5e7 2712 PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n",
c5c77ba1
JK
2713 strHostIfBASessionInfo->au8Bssid[0],
2714 strHostIfBASessionInfo->au8Bssid[1],
2715 strHostIfBASessionInfo->au8Bssid[2],
2716 strHostIfBASessionInfo->u16BufferSize,
2717 strHostIfBASessionInfo->u16SessionTimeout,
2718 strHostIfBASessionInfo->u8Ted);
2719
45102f83
LK
2720 wid.id = (u16)WID_11E_P_ACTION_REQ;
2721 wid.type = WID_STR;
2722 wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2723 wid.size = BLOCK_ACK_REQ_SIZE;
2724 ptr = wid.val;
c5c77ba1
JK
2725 *ptr++ = 0x14;
2726 *ptr++ = 0x3;
2727 *ptr++ = 0x0;
d00d2ba3 2728 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1
JK
2729 ptr += ETH_ALEN;
2730 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2731 *ptr++ = 1;
c5c77ba1
JK
2732 *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2733 *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF);
c5c77ba1
JK
2734 *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF);
2735 *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
c5c77ba1
JK
2736 *ptr++ = (AddbaTimeout & 0xFF);
2737 *ptr++ = ((AddbaTimeout >> 16) & 0xFF);
c5c77ba1 2738 *ptr++ = 8;
c5c77ba1
JK
2739 *ptr++ = 0;
2740
45102f83 2741 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2742 get_id_from_handler(hif_drv));
31390eec 2743 if (result)
c5c77ba1
JK
2744 PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
2745
45102f83
LK
2746 wid.id = (u16)WID_11E_P_ACTION_REQ;
2747 wid.type = WID_STR;
2748 wid.size = 15;
2749 ptr = wid.val;
c5c77ba1
JK
2750 *ptr++ = 15;
2751 *ptr++ = 7;
2752 *ptr++ = 0x2;
d00d2ba3 2753 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1 2754 ptr += ETH_ALEN;
c5c77ba1 2755 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2756 *ptr++ = 8;
c5c77ba1
JK
2757 *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2758 *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
c5c77ba1 2759 *ptr++ = 3;
45102f83 2760 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2761 get_id_from_handler(hif_drv));
c5c77ba1 2762
45102f83 2763 kfree(wid.val);
c5c77ba1 2764
31390eec 2765 return result;
c5c77ba1
JK
2766}
2767
a4ab1ade 2768static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv,
54265472 2769 struct ba_session_info *strHostIfBASessionInfo)
c5c77ba1 2770{
31390eec 2771 s32 result = 0;
45102f83 2772 struct wid wid;
c5c77ba1 2773 char *ptr = NULL;
c5c77ba1 2774
03b2d5e7 2775 PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n",
c5c77ba1
JK
2776 strHostIfBASessionInfo->au8Bssid[0],
2777 strHostIfBASessionInfo->au8Bssid[1],
2778 strHostIfBASessionInfo->au8Bssid[2],
2779 strHostIfBASessionInfo->u8Ted);
2780
45102f83
LK
2781 wid.id = (u16)WID_DEL_ALL_RX_BA;
2782 wid.type = WID_STR;
2783 wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2784 wid.size = BLOCK_ACK_REQ_SIZE;
2785 ptr = wid.val;
c5c77ba1
JK
2786 *ptr++ = 0x14;
2787 *ptr++ = 0x3;
2788 *ptr++ = 0x2;
d00d2ba3 2789 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1
JK
2790 ptr += ETH_ALEN;
2791 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2792 *ptr++ = 0;
ae4dfa57 2793 *ptr++ = 32;
c5c77ba1 2794
45102f83 2795 result = send_config_pkt(SET_CFG, &wid, 1,
8c8360b3 2796 get_id_from_handler(hif_drv));
31390eec 2797 if (result)
c5c77ba1
JK
2798 PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
2799
45102f83 2800 kfree(wid.val);
c5c77ba1 2801
2d25af87 2802 up(&hif_sema_wait_response);
c5c77ba1 2803
31390eec 2804 return result;
c5c77ba1
JK
2805}
2806
1999bd52 2807static int hostIFthread(void *pvArg)
c5c77ba1 2808{
4e4467fd 2809 u32 u32Ret;
143eb95a 2810 struct host_if_msg msg;
a4ab1ade 2811 struct host_if_drv *hif_drv;
c5c77ba1 2812
143eb95a 2813 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
2814
2815 while (1) {
cb067dcf 2816 wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
a4ab1ade 2817 hif_drv = (struct host_if_drv *)msg.drv;
a9f812a6 2818 if (msg.id == HOST_IF_MSG_EXIT) {
c5c77ba1
JK
2819 PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
2820 break;
2821 }
2822
c5c77ba1
JK
2823 if ((!g_wilc_initialized)) {
2824 PRINT_D(GENERIC_DBG, "--WAIT--");
80e29c7a 2825 usleep_range(200 * 1000, 200 * 1000);
cb067dcf 2826 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
2827 continue;
2828 }
2829
91109e11 2830 if (msg.id == HOST_IF_MSG_CONNECT &&
70793b2a 2831 hif_drv->usr_scan_req.pfUserScanResult) {
c5c77ba1 2832 PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
cb067dcf 2833 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
80e29c7a 2834 usleep_range(2 * 1000, 2 * 1000);
c5c77ba1
JK
2835 continue;
2836 }
2837
a9f812a6 2838 switch (msg.id) {
c5c77ba1
JK
2839 case HOST_IF_MSG_Q_IDLE:
2840 Handle_wait_msg_q_empty();
2841 break;
2842
2843 case HOST_IF_MSG_SCAN:
2482a79f 2844 Handle_Scan(msg.drv, &msg.body.scan_info);
c5c77ba1
JK
2845 break;
2846
2847 case HOST_IF_MSG_CONNECT:
2482a79f 2848 Handle_Connect(msg.drv, &msg.body.con_info);
c5c77ba1
JK
2849 break;
2850
c5c77ba1 2851 case HOST_IF_MSG_FLUSH_CONNECT:
2482a79f 2852 Handle_FlushConnect(msg.drv);
c5c77ba1
JK
2853 break;
2854
2855 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2482a79f 2856 Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info);
c5c77ba1
JK
2857 break;
2858
2859 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2482a79f 2860 Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info);
c5c77ba1
JK
2861 break;
2862
2863 case HOST_IF_MSG_KEY:
2482a79f 2864 Handle_Key(msg.drv, &msg.body.key_info);
c5c77ba1
JK
2865 break;
2866
2867 case HOST_IF_MSG_CFG_PARAMS:
2868
2482a79f 2869 Handle_CfgParam(msg.drv, &msg.body.cfg_info);
c5c77ba1
JK
2870 break;
2871
2872 case HOST_IF_MSG_SET_CHANNEL:
2482a79f 2873 Handle_SetChannel(msg.drv, &msg.body.channel_info);
c5c77ba1
JK
2874 break;
2875
2876 case HOST_IF_MSG_DISCONNECT:
2482a79f 2877 Handle_Disconnect(msg.drv);
c5c77ba1
JK
2878 break;
2879
2880 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
a4ab1ade 2881 del_timer(&hif_drv->hScanTimer);
c5c77ba1
JK
2882 PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
2883
2b9d5b48 2884 if (!linux_wlan_get_num_conn_ifcs())
c5c77ba1 2885 chip_sleep_manually(INFINITE_SLEEP_TIME);
c5c77ba1 2886
2482a79f 2887 Handle_ScanDone(msg.drv, SCAN_EVENT_DONE);
c5c77ba1 2888
5beef2ca 2889 if (hif_drv->remain_on_ch_pending)
2482a79f 2890 Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
2891
2892 break;
2893
2894 case HOST_IF_MSG_GET_RSSI:
2482a79f 2895 Handle_GetRssi(msg.drv);
c5c77ba1
JK
2896 break;
2897
2898 case HOST_IF_MSG_GET_LINKSPEED:
2482a79f 2899 Handle_GetLinkspeed(msg.drv);
c5c77ba1
JK
2900 break;
2901
2902 case HOST_IF_MSG_GET_STATISTICS:
03e7b9c4 2903 Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data);
c5c77ba1
JK
2904 break;
2905
2906 case HOST_IF_MSG_GET_CHNL:
2482a79f 2907 Handle_GetChnl(msg.drv);
c5c77ba1
JK
2908 break;
2909
c5c77ba1 2910 case HOST_IF_MSG_ADD_BEACON:
2482a79f 2911 Handle_AddBeacon(msg.drv, &msg.body.beacon_info);
c5c77ba1
JK
2912 break;
2913
2914 case HOST_IF_MSG_DEL_BEACON:
2482a79f 2915 Handle_DelBeacon(msg.drv);
c5c77ba1
JK
2916 break;
2917
2918 case HOST_IF_MSG_ADD_STATION:
2482a79f 2919 Handle_AddStation(msg.drv, &msg.body.add_sta_info);
c5c77ba1
JK
2920 break;
2921
2922 case HOST_IF_MSG_DEL_STATION:
2482a79f 2923 Handle_DelStation(msg.drv, &msg.body.del_sta_info);
c5c77ba1
JK
2924 break;
2925
2926 case HOST_IF_MSG_EDIT_STATION:
2482a79f 2927 Handle_EditStation(msg.drv, &msg.body.edit_sta_info);
c5c77ba1
JK
2928 break;
2929
2930 case HOST_IF_MSG_GET_INACTIVETIME:
2482a79f 2931 Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info);
c5c77ba1
JK
2932 break;
2933
c5c77ba1
JK
2934 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2935 PRINT_D(HOSTINF_DBG, "Scan Timeout\n");
2936
2482a79f 2937 Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED);
c5c77ba1
JK
2938 break;
2939
2940 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
03b2d5e7 2941 PRINT_D(HOSTINF_DBG, "Connect Timeout\n");
2482a79f 2942 Handle_ConnectTimeout(msg.drv);
c5c77ba1
JK
2943 break;
2944
2945 case HOST_IF_MSG_POWER_MGMT:
2482a79f 2946 Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info);
c5c77ba1
JK
2947 break;
2948
2949 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2482a79f 2950 Handle_SetWfiDrvHandler(msg.drv,
5e4377e6 2951 &msg.body.drv);
c5c77ba1
JK
2952 break;
2953
2954 case HOST_IF_MSG_SET_OPERATION_MODE:
2482a79f 2955 Handle_SetOperationMode(msg.drv, &msg.body.mode);
c5c77ba1
JK
2956 break;
2957
2958 case HOST_IF_MSG_SET_IPADDRESS:
2959 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
78675be5 2960 Handle_set_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
c5c77ba1
JK
2961 break;
2962
2963 case HOST_IF_MSG_GET_IPADDRESS:
2964 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
78675be5 2965 Handle_get_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
c5c77ba1
JK
2966 break;
2967
c5c77ba1 2968 case HOST_IF_MSG_SET_MAC_ADDRESS:
2482a79f 2969 Handle_SetMacAddress(msg.drv, &msg.body.set_mac_info);
c5c77ba1
JK
2970 break;
2971
c5c77ba1 2972 case HOST_IF_MSG_GET_MAC_ADDRESS:
2482a79f 2973 Handle_GetMacAddress(msg.drv, &msg.body.get_mac_info);
c5c77ba1
JK
2974 break;
2975
c5c77ba1
JK
2976 case HOST_IF_MSG_REMAIN_ON_CHAN:
2977 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n");
2482a79f 2978 Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
2979 break;
2980
2981 case HOST_IF_MSG_REGISTER_FRAME:
2982 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n");
2482a79f 2983 Handle_RegisterFrame(msg.drv, &msg.body.reg_frame);
c5c77ba1
JK
2984 break;
2985
2986 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2482a79f 2987 Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
2988 break;
2989
c5c77ba1
JK
2990 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2991 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n");
2482a79f 2992 Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info);
c5c77ba1
JK
2993 break;
2994
c5c77ba1 2995 case HOST_IF_MSG_ADD_BA_SESSION:
2482a79f 2996 Handle_AddBASession(msg.drv, &msg.body.session_info);
c5c77ba1
JK
2997 break;
2998
2999 case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
2482a79f 3000 Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info);
c5c77ba1
JK
3001 break;
3002
3003 case HOST_IF_MSG_DEL_ALL_STA:
2482a79f 3004 Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info);
c5c77ba1
JK
3005 break;
3006
3007 default:
03b2d5e7 3008 PRINT_ER("[Host Interface] undefined Received Msg ID\n");
c5c77ba1
JK
3009 break;
3010 }
3011 }
3012
3013 PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n");
834e0cb0 3014 up(&hif_sema_thread);
1999bd52 3015 return 0;
c5c77ba1
JK
3016}
3017
93dee8ee 3018static void TimerCB_Scan(unsigned long arg)
c5c77ba1 3019{
93dee8ee 3020 void *pvArg = (void *)arg;
143eb95a 3021 struct host_if_msg msg;
c5c77ba1 3022
143eb95a 3023 memset(&msg, 0, sizeof(struct host_if_msg));
2482a79f 3024 msg.drv = pvArg;
a9f812a6 3025 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
c5c77ba1 3026
cb067dcf 3027 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
3028}
3029
93dee8ee 3030static void TimerCB_Connect(unsigned long arg)
c5c77ba1 3031{
93dee8ee 3032 void *pvArg = (void *)arg;
143eb95a 3033 struct host_if_msg msg;
c5c77ba1 3034
143eb95a 3035 memset(&msg, 0, sizeof(struct host_if_msg));
2482a79f 3036 msg.drv = pvArg;
a9f812a6 3037 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
c5c77ba1 3038
cb067dcf 3039 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
3040}
3041
a4ab1ade 3042s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
c5c77ba1 3043{
45102f83 3044 struct wid wid;
c5c77ba1 3045
45102f83
LK
3046 wid.id = (u16)WID_REMOVE_KEY;
3047 wid.type = WID_STR;
3048 wid.val = (s8 *)pu8StaAddress;
3049 wid.size = 6;
c5c77ba1 3050
b68d820b 3051 return 0;
c5c77ba1
JK
3052}
3053
a4ab1ade 3054int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
c5c77ba1 3055{
9e5e8b44 3056 int result = 0;
143eb95a 3057 struct host_if_msg msg;
c5c77ba1 3058
a4ab1ade 3059 if (!hif_drv) {
9e5e8b44 3060 result = -EFAULT;
24db713f 3061 PRINT_ER("Failed to send setup multicast config packet\n");
9e5e8b44 3062 return result;
24db713f 3063 }
c5c77ba1 3064
143eb95a 3065 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3066
a9f812a6 3067 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3068 msg.body.key_info.type = WEP;
0d17e382 3069 msg.body.key_info.action = REMOVEKEY;
a4ab1ade 3070 msg.drv = hif_drv;
73b2e381 3071 msg.body.key_info.attr.wep.index = index;
c5c77ba1 3072
cb067dcf 3073 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
9e5e8b44 3074 if (result)
03b2d5e7 3075 PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
a4ab1ade 3076 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3077
9e5e8b44 3078 return result;
c5c77ba1
JK
3079}
3080
df8b4830 3081int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index)
c5c77ba1 3082{
5b41c7c9 3083 int result = 0;
143eb95a 3084 struct host_if_msg msg;
c5c77ba1 3085
a4ab1ade 3086 if (!hif_drv) {
31390eec 3087 result = -EFAULT;
24db713f 3088 PRINT_ER("driver is null\n");
31390eec 3089 return result;
24db713f 3090 }
c5c77ba1 3091
143eb95a 3092 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3093
a9f812a6 3094 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3095 msg.body.key_info.type = WEP;
0d17e382 3096 msg.body.key_info.action = DEFAULTKEY;
a4ab1ade 3097 msg.drv = hif_drv;
e91d0349 3098 msg.body.key_info.attr.wep.index = index;
c5c77ba1 3099
31390eec
LK
3100 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3101 if (result)
c5c77ba1 3102 PRINT_ER("Error in sending message queue : Default key index\n");
a4ab1ade 3103 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3104
31390eec 3105 return result;
c5c77ba1
JK
3106}
3107
66b8cb89 3108int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
fba778b1 3109 const u8 *key,
dbc53194 3110 u8 len,
0b2cc3e5 3111 u8 index)
c5c77ba1 3112{
66b8cb89 3113 int result = 0;
143eb95a 3114 struct host_if_msg msg;
c5c77ba1 3115
a4ab1ade 3116 if (!hif_drv) {
24db713f 3117 PRINT_ER("driver is null\n");
77178807 3118 return -EFAULT;
24db713f 3119 }
c5c77ba1 3120
143eb95a 3121 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3122
a9f812a6 3123 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3124 msg.body.key_info.type = WEP;
0d17e382 3125 msg.body.key_info.action = ADDKEY;
a4ab1ade 3126 msg.drv = hif_drv;
1cc0c328
CL
3127 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
3128 if (!msg.body.key_info.attr.wep.key)
3129 return -ENOMEM;
3130
dbc53194 3131 msg.body.key_info.attr.wep.key_len = len;
0b2cc3e5 3132 msg.body.key_info.attr.wep.index = index;
c5c77ba1 3133
31390eec
LK
3134 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3135 if (result)
c5c77ba1 3136 PRINT_ER("Error in sending message queue :WEP Key\n");
a4ab1ade 3137 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3138
31390eec 3139 return result;
c5c77ba1
JK
3140}
3141
641c20a6 3142int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
8111725a 3143 const u8 *key,
a5389b07 3144 u8 len,
a4ab1ade
TC
3145 u8 u8Keyidx,
3146 u8 u8mode,
3147 enum AUTHTYPE tenuAuth_type)
c5c77ba1 3148{
641c20a6 3149 int result = 0;
143eb95a 3150 struct host_if_msg msg;
fd741461 3151 int i;
c5c77ba1 3152
a4ab1ade 3153 if (!hif_drv) {
24db713f 3154 PRINT_ER("driver is null\n");
77178807 3155 return -EFAULT;
24db713f 3156 }
c5c77ba1 3157
143eb95a 3158 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
3159
3160 if (INFO) {
a5389b07 3161 for (i = 0; i < len; i++)
8111725a 3162 PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", key[i]);
c5c77ba1 3163 }
a9f812a6 3164 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3165 msg.body.key_info.type = WEP;
0d17e382 3166 msg.body.key_info.action = ADDKEY_AP;
a4ab1ade 3167 msg.drv = hif_drv;
a5389b07
CL
3168 msg.body.key_info.attr.wep.key = kmalloc(len, GFP_KERNEL);
3169 memcpy(msg.body.key_info.attr.wep.key, key, len);
3170 msg.body.key_info.attr.wep.key_len = len;
73b2e381
LK
3171 msg.body.key_info.attr.wep.index = u8Keyidx;
3172 msg.body.key_info.attr.wep.mode = u8mode;
3173 msg.body.key_info.attr.wep.auth_type = tenuAuth_type;
ae4dfa57 3174
31390eec 3175 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3176
31390eec 3177 if (result)
c5c77ba1 3178 PRINT_ER("Error in sending message queue :WEP Key\n");
a4ab1ade 3179 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3180
31390eec 3181 return result;
c5c77ba1 3182}
108b3439 3183
a4ab1ade
TC
3184s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
3185 u8 u8PtkKeylen, const u8 *mac_addr,
3186 const u8 *pu8RxMic, const u8 *pu8TxMic,
3187 u8 mode, u8 u8Ciphermode, u8 u8Idx)
c5c77ba1 3188{
31390eec 3189 s32 result = 0;
143eb95a 3190 struct host_if_msg msg;
63d03e47 3191 u8 u8KeyLen = u8PtkKeylen;
4e4467fd 3192 u32 i;
78c87591 3193
a4ab1ade 3194 if (!hif_drv) {
24db713f 3195 PRINT_ER("driver is null\n");
77178807 3196 return -EFAULT;
24db713f 3197 }
91109e11
LK
3198
3199 if (pu8RxMic)
c5c77ba1 3200 u8KeyLen += RX_MIC_KEY_LEN;
91109e11
LK
3201
3202 if (pu8TxMic)
c5c77ba1 3203 u8KeyLen += TX_MIC_KEY_LEN;
c5c77ba1 3204
143eb95a 3205 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3206
a9f812a6 3207 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3208 msg.body.key_info.type = WPAPtk;
c5c77ba1 3209 if (mode == AP_MODE) {
0d17e382 3210 msg.body.key_info.action = ADDKEY_AP;
e2dfbac5 3211 msg.body.key_info.attr.wpa.index = u8Idx;
c5c77ba1 3212 }
c5c77ba1 3213 if (mode == STATION_MODE)
0d17e382 3214 msg.body.key_info.action = ADDKEY;
c5c77ba1 3215
124968fc
LK
3216 msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
3217 memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
c5c77ba1 3218
91109e11 3219 if (pu8RxMic) {
124968fc 3220 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
c5c77ba1
JK
3221 if (INFO) {
3222 for (i = 0; i < RX_MIC_KEY_LEN; i++)
3223 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
3224 }
3225 }
91109e11 3226 if (pu8TxMic) {
124968fc 3227 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
c5c77ba1
JK
3228 if (INFO) {
3229 for (i = 0; i < TX_MIC_KEY_LEN; i++)
3230 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
3231 }
3232 }
3233
6acf2919 3234 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
248080aa 3235 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
7b2ebb28 3236 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
a4ab1ade 3237 msg.drv = hif_drv;
c5c77ba1 3238
31390eec 3239 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3240
31390eec 3241 if (result)
c5c77ba1
JK
3242 PRINT_ER("Error in sending message queue: PTK Key\n");
3243
a4ab1ade 3244 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3245
31390eec 3246 return result;
c5c77ba1
JK
3247}
3248
a4ab1ade
TC
3249s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
3250 u8 u8GtkKeylen, u8 u8KeyIdx,
3251 u32 u32KeyRSClen, const u8 *KeyRSC,
3252 const u8 *pu8RxMic, const u8 *pu8TxMic,
3253 u8 mode, u8 u8Ciphermode)
c5c77ba1 3254{
31390eec 3255 s32 result = 0;
143eb95a 3256 struct host_if_msg msg;
63d03e47 3257 u8 u8KeyLen = u8GtkKeylen;
c5c77ba1 3258
a4ab1ade 3259 if (!hif_drv) {
24db713f 3260 PRINT_ER("driver is null\n");
77178807 3261 return -EFAULT;
24db713f 3262 }
143eb95a 3263 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3264
91109e11 3265 if (pu8RxMic)
c5c77ba1 3266 u8KeyLen += RX_MIC_KEY_LEN;
91109e11
LK
3267
3268 if (pu8TxMic)
c5c77ba1 3269 u8KeyLen += TX_MIC_KEY_LEN;
91109e11
LK
3270
3271 if (KeyRSC) {
0e74c009
LK
3272 msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
3273 memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
c5c77ba1
JK
3274 }
3275
a9f812a6 3276 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3277 msg.body.key_info.type = WPARxGtk;
a4ab1ade 3278 msg.drv = hif_drv;
c5c77ba1 3279
c5c77ba1 3280 if (mode == AP_MODE) {
0d17e382 3281 msg.body.key_info.action = ADDKEY_AP;
7b2ebb28 3282 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
c5c77ba1 3283 }
c5c77ba1 3284 if (mode == STATION_MODE)
0d17e382 3285 msg.body.key_info.action = ADDKEY;
c5c77ba1 3286
124968fc
LK
3287 msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
3288 memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
c5c77ba1 3289
d1666e2a
LK
3290 if (pu8RxMic)
3291 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic,
3292 RX_MIC_KEY_LEN);
91109e11 3293
d1666e2a
LK
3294 if (pu8TxMic)
3295 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic,
3296 TX_MIC_KEY_LEN);
c5c77ba1 3297
e2dfbac5 3298 msg.body.key_info.attr.wpa.index = u8KeyIdx;
6acf2919 3299 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
dacc594d 3300 msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
c5c77ba1 3301
31390eec
LK
3302 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3303 if (result)
c5c77ba1 3304 PRINT_ER("Error in sending message queue: RX GTK\n");
ae4dfa57 3305
a4ab1ade 3306 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3307
31390eec 3308 return result;
c5c77ba1 3309}
c5c77ba1 3310
a4ab1ade 3311s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
c5c77ba1 3312{
31390eec 3313 s32 result = 0;
143eb95a 3314 struct host_if_msg msg;
4e4467fd 3315 u32 i;
c5c77ba1 3316
a4ab1ade 3317 if (!hif_drv) {
24db713f 3318 PRINT_ER("driver is null\n");
77178807 3319 return -EFAULT;
24db713f 3320 }
c5c77ba1 3321
143eb95a 3322 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3323
a9f812a6 3324 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3325 msg.body.key_info.type = PMKSA;
0d17e382 3326 msg.body.key_info.action = ADDKEY;
a4ab1ade 3327 msg.drv = hif_drv;
c5c77ba1
JK
3328
3329 for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
8c8360b3
LK
3330 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3331 &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN);
3332 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3333 &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN);
c5c77ba1
JK
3334 }
3335
31390eec
LK
3336 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3337 if (result)
c5c77ba1
JK
3338 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3339
31390eec 3340 return result;
c5c77ba1
JK
3341}
3342
a4ab1ade
TC
3343s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
3344 u8 *pu8PmkidInfoArray,
3345 u32 u32PmkidInfoLen)
c5c77ba1 3346{
45102f83 3347 struct wid wid;
c5c77ba1 3348
45102f83
LK
3349 wid.id = (u16)WID_PMKID_INFO;
3350 wid.type = WID_STR;
3351 wid.size = u32PmkidInfoLen;
3352 wid.val = pu8PmkidInfoArray;
c5c77ba1 3353
b68d820b 3354 return 0;
c5c77ba1
JK
3355}
3356
a4ab1ade
TC
3357s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3358 u8 *pu8PassPhrase,
3359 u8 u8Psklength)
c5c77ba1 3360{
45102f83 3361 struct wid wid;
c5c77ba1 3362
c5c77ba1 3363 if ((u8Psklength > 7) && (u8Psklength < 65)) {
45102f83
LK
3364 wid.id = (u16)WID_11I_PSK;
3365 wid.type = WID_STR;
3366 wid.val = pu8PassPhrase;
3367 wid.size = u8Psklength;
c5c77ba1
JK
3368 }
3369
b68d820b 3370 return 0;
c5c77ba1 3371}
ae4dfa57 3372
a4ab1ade 3373s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3374{
31390eec 3375 s32 result = 0;
143eb95a 3376 struct host_if_msg msg;
c5c77ba1 3377
143eb95a 3378 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3379
a9f812a6 3380 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
6ceba0af 3381 msg.body.get_mac_info.mac_addr = pu8MacAddress;
a4ab1ade 3382 msg.drv = hif_drv;
ae4dfa57 3383
31390eec
LK
3384 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3385 if (result) {
c5c77ba1 3386 PRINT_ER("Failed to send get mac address\n");
e6e12661 3387 return -EFAULT;
c5c77ba1
JK
3388 }
3389
2d25af87 3390 down(&hif_sema_wait_response);
31390eec 3391 return result;
c5c77ba1
JK
3392}
3393
a4ab1ade 3394s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3395{
31390eec 3396 s32 result = 0;
143eb95a 3397 struct host_if_msg msg;
c5c77ba1
JK
3398
3399 PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
3400
143eb95a 3401 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3402 msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
ae5e4522 3403 memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN);
a4ab1ade 3404 msg.drv = hif_drv;
c5c77ba1 3405
31390eec
LK
3406 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3407 if (result)
c5c77ba1 3408 PRINT_ER("Failed to send message queue: Set mac address\n");
c5c77ba1 3409
31390eec 3410 return result;
c5c77ba1
JK
3411}
3412
a4ab1ade
TC
3413s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3414 u8 *pu8PassPhrase, u8 u8Psklength)
c5c77ba1 3415{
45102f83 3416 struct wid wid;
c5c77ba1 3417
45102f83
LK
3418 wid.id = (u16)WID_11I_PSK;
3419 wid.type = WID_STR;
3420 wid.size = u8Psklength;
3421 wid.val = pu8PassPhrase;
c5c77ba1 3422
b68d820b 3423 return 0;
c5c77ba1
JK
3424}
3425
a4ab1ade 3426s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
c5c77ba1 3427{
45102f83 3428 struct wid wid;
c5c77ba1 3429
45102f83
LK
3430 wid.id = (u16)WID_START_SCAN_REQ;
3431 wid.type = WID_CHAR;
3432 wid.val = (s8 *)&scanSource;
3433 wid.size = sizeof(char);
c5c77ba1 3434
b68d820b 3435 return 0;
c5c77ba1
JK
3436}
3437
a4ab1ade 3438s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
c5c77ba1 3439{
45102f83 3440 struct wid wid;
c5c77ba1 3441
45102f83
LK
3442 wid.id = (u16)WID_START_SCAN_REQ;
3443 wid.type = WID_CHAR;
3444 wid.val = (s8 *)pu8ScanSource;
3445 wid.size = sizeof(char);
c5c77ba1 3446
b68d820b 3447 return 0;
c5c77ba1
JK
3448}
3449
a4ab1ade
TC
3450s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
3451 const u8 *pu8ssid, size_t ssidLen,
3452 const u8 *pu8IEs, size_t IEsLen,
3453 wilc_connect_result pfConnectResult, void *pvUserArg,
3454 u8 u8security, enum AUTHTYPE tenuAuth_type,
3455 u8 u8channel, void *pJoinParams)
c5c77ba1 3456{
31390eec 3457 s32 result = 0;
143eb95a 3458 struct host_if_msg msg;
c5c77ba1 3459
91109e11 3460 if (!hif_drv || !pfConnectResult) {
24db713f 3461 PRINT_ER("Driver is null\n");
77178807 3462 return -EFAULT;
24db713f 3463 }
c5c77ba1 3464
91109e11 3465 if (!pJoinParams) {
c5c77ba1 3466 PRINT_ER("Unable to Join - JoinParams is NULL\n");
24db713f 3467 return -EFAULT;
c5c77ba1 3468 }
24db713f 3469
143eb95a 3470 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3471
a9f812a6 3472 msg.id = HOST_IF_MSG_CONNECT;
c5c77ba1 3473
a64fd677 3474 msg.body.con_info.security = u8security;
61b4fd02 3475 msg.body.con_info.auth_type = tenuAuth_type;
0d1527e6 3476 msg.body.con_info.ch = u8channel;
6abcc11d 3477 msg.body.con_info.result = pfConnectResult;
8f38db89 3478 msg.body.con_info.arg = pvUserArg;
f2bed2ca 3479 msg.body.con_info.params = pJoinParams;
a4ab1ade 3480 msg.drv = hif_drv ;
c5c77ba1 3481
91109e11 3482 if (pu8bssid) {
9254db07
LK
3483 msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
3484 memcpy(msg.body.con_info.bssid, pu8bssid, 6);
c5c77ba1
JK
3485 }
3486
91109e11 3487 if (pu8ssid) {
8b3c9fa6 3488 msg.body.con_info.ssid_len = ssidLen;
f7bbd9cf
LK
3489 msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL);
3490 memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen);
c5c77ba1
JK
3491 }
3492
91109e11 3493 if (pu8IEs) {
b59d5c5b 3494 msg.body.con_info.ies_len = IEsLen;
2ea158c4
LK
3495 msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3496 memcpy(msg.body.con_info.ies, pu8IEs, IEsLen);
c5c77ba1 3497 }
a4ab1ade
TC
3498 if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING)
3499 hif_drv->enuHostIFstate = HOST_IF_CONNECTING;
78174ada 3500 else
a4ab1ade 3501 PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate);
c5c77ba1 3502
31390eec
LK
3503 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3504 if (result) {
c5c77ba1 3505 PRINT_ER("Failed to send message queue: Set join request\n");
24db713f 3506 return -EFAULT;
c5c77ba1
JK
3507 }
3508
a4ab1ade
TC
3509 hif_drv->hConnectTimer.data = (unsigned long)hif_drv;
3510 mod_timer(&hif_drv->hConnectTimer,
9eb06643 3511 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
c5c77ba1 3512
31390eec 3513 return result;
c5c77ba1
JK
3514}
3515
a4ab1ade 3516s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
c5c77ba1 3517{
31390eec 3518 s32 result = 0;
143eb95a 3519 struct host_if_msg msg;
c5c77ba1 3520
77178807
LK
3521 if (!join_req)
3522 return -EFAULT;
c5c77ba1 3523
a4ab1ade 3524 if (!hif_drv) {
24db713f 3525 PRINT_ER("Driver is null\n");
77178807 3526 return -EFAULT;
24db713f 3527 }
c5c77ba1 3528
a9f812a6 3529 msg.id = HOST_IF_MSG_FLUSH_CONNECT;
a4ab1ade 3530 msg.drv = hif_drv;
c5c77ba1 3531
31390eec
LK
3532 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3533 if (result) {
c5c77ba1 3534 PRINT_ER("Failed to send message queue: Flush join request\n");
24db713f 3535 return -EFAULT;
c5c77ba1
JK
3536 }
3537
31390eec 3538 return result;
c5c77ba1
JK
3539}
3540
a4ab1ade 3541s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
c5c77ba1 3542{
31390eec 3543 s32 result = 0;
143eb95a 3544 struct host_if_msg msg;
c5c77ba1 3545
a4ab1ade 3546 if (!hif_drv) {
24db713f
LK
3547 PRINT_ER("Driver is null\n");
3548 return -EFAULT;
c5c77ba1
JK
3549 }
3550
143eb95a 3551 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3552
a9f812a6 3553 msg.id = HOST_IF_MSG_DISCONNECT;
a4ab1ade 3554 msg.drv = hif_drv;
c5c77ba1 3555
31390eec
LK
3556 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3557 if (result)
c5c77ba1 3558 PRINT_ER("Failed to send message queue: disconnect\n");
ae4dfa57 3559
a4ab1ade 3560 down(&hif_drv->hSemTestDisconnectBlock);
c5c77ba1 3561
31390eec 3562 return result;
c5c77ba1
JK
3563}
3564
a4ab1ade 3565s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
c5c77ba1 3566{
45102f83 3567 struct wid wid;
c5c77ba1 3568
45102f83
LK
3569 wid.id = (u16)WID_DISCONNECT;
3570 wid.type = WID_CHAR;
3571 wid.val = (s8 *)&assoc_id;
3572 wid.size = sizeof(char);
c5c77ba1 3573
b68d820b 3574 return 0;
c5c77ba1
JK
3575}
3576
8c8360b3
LK
3577s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
3578 u8 *pu8AssocReqInfo,
3579 u32 u32AssocReqInfoLen)
c5c77ba1 3580{
45102f83 3581 struct wid wid;
c5c77ba1 3582
45102f83
LK
3583 wid.id = (u16)WID_ASSOC_REQ_INFO;
3584 wid.type = WID_STR;
3585 wid.val = pu8AssocReqInfo;
3586 wid.size = u32AssocReqInfoLen;
c5c77ba1 3587
b68d820b 3588 return 0;
c5c77ba1
JK
3589}
3590
8c8360b3
LK
3591s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
3592 u8 *pu8AssocRespInfo,
3593 u32 u32MaxAssocRespInfoLen,
3594 u32 *pu32RcvdAssocRespInfoLen)
c5c77ba1 3595{
31390eec 3596 s32 result = 0;
45102f83 3597 struct wid wid;
c5c77ba1 3598
a4ab1ade 3599 if (!hif_drv) {
24db713f
LK
3600 PRINT_ER("Driver is null\n");
3601 return -EFAULT;
c5c77ba1
JK
3602 }
3603
45102f83
LK
3604 wid.id = (u16)WID_ASSOC_RES_INFO;
3605 wid.type = WID_STR;
3606 wid.val = pu8AssocRespInfo;
3607 wid.size = u32MaxAssocRespInfoLen;
c5c77ba1 3608
45102f83 3609 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 3610 get_id_from_handler(hif_drv));
31390eec 3611 if (result) {
c5c77ba1 3612 *pu32RcvdAssocRespInfoLen = 0;
24db713f
LK
3613 PRINT_ER("Failed to send association response config packet\n");
3614 return -EINVAL;
c5c77ba1 3615 } else {
45102f83 3616 *pu32RcvdAssocRespInfoLen = wid.size;
c5c77ba1
JK
3617 }
3618
31390eec 3619 return result;
c5c77ba1
JK
3620}
3621
8c8360b3
LK
3622s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
3623 u8 *pu8RxPowerLevel,
3624 u32 u32RxPowerLevelLen)
c5c77ba1 3625{
45102f83 3626 struct wid wid;
c5c77ba1 3627
45102f83
LK
3628 wid.id = (u16)WID_RX_POWER_LEVEL;
3629 wid.type = WID_STR;
3630 wid.val = pu8RxPowerLevel;
3631 wid.size = u32RxPowerLevelLen;
c5c77ba1 3632
b68d820b 3633 return 0;
c5c77ba1
JK
3634}
3635
a4ab1ade 3636int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
c5c77ba1 3637{
792fb25b 3638 int result;
143eb95a 3639 struct host_if_msg msg;
c5c77ba1 3640
a4ab1ade 3641 if (!hif_drv) {
24db713f
LK
3642 PRINT_ER("driver is null\n");
3643 return -EFAULT;
3644 }
c5c77ba1 3645
143eb95a 3646 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3647 msg.id = HOST_IF_MSG_SET_CHANNEL;
730ee059 3648 msg.body.channel_info.set_ch = channel;
a4ab1ade 3649 msg.drv = hif_drv;
c5c77ba1 3650
cb067dcf 3651 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
1ef58e42 3652 if (result) {
24db713f 3653 PRINT_ER("wilc mq send fail\n");
792fb25b 3654 return -EINVAL;
c5c77ba1
JK
3655 }
3656
792fb25b 3657 return 0;
c5c77ba1
JK
3658}
3659
244efb1f 3660int host_int_wait_msg_queue_idle(void)
c5c77ba1 3661{
6d6c9bbb 3662 int result = 0;
143eb95a 3663 struct host_if_msg msg;
c09389ac 3664
143eb95a 3665 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3666 msg.id = HOST_IF_MSG_Q_IDLE;
cb067dcf 3667 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
6d6c9bbb 3668 if (result) {
24db713f 3669 PRINT_ER("wilc mq send fail\n");
6d6c9bbb 3670 result = -EINVAL;
c5c77ba1
JK
3671 }
3672
2d25af87 3673 down(&hif_sema_wait_response);
c5c77ba1 3674
6d6c9bbb 3675 return result;
c5c77ba1
JK
3676}
3677
a4ab1ade 3678int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
c5c77ba1 3679{
a094101c 3680 int result = 0;
143eb95a 3681 struct host_if_msg msg;
c09389ac 3682
143eb95a 3683 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3684 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
a7f3b12f 3685 msg.body.drv.handler = get_id_from_handler(hif_drv);
a4ab1ade 3686 msg.drv = hif_drv;
c5c77ba1 3687
cb067dcf 3688 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a094101c 3689 if (result) {
24db713f 3690 PRINT_ER("wilc mq send fail\n");
a094101c 3691 result = -EINVAL;
c5c77ba1
JK
3692 }
3693
a094101c 3694 return result;
c5c77ba1
JK
3695}
3696
a4ab1ade 3697int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
c5c77ba1 3698{
a0c1ee0c 3699 int result = 0;
143eb95a 3700 struct host_if_msg msg;
c09389ac 3701
143eb95a 3702 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3703 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
c96debf1 3704 msg.body.mode.mode = mode;
a4ab1ade 3705 msg.drv = hif_drv;
c5c77ba1 3706
cb067dcf 3707 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a0c1ee0c 3708 if (result) {
24db713f 3709 PRINT_ER("wilc mq send fail\n");
a0c1ee0c 3710 result = -EINVAL;
c5c77ba1
JK
3711 }
3712
a0c1ee0c 3713 return result;
c5c77ba1
JK
3714}
3715
a4ab1ade 3716s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
c5c77ba1 3717{
31390eec 3718 s32 result = 0;
143eb95a 3719 struct host_if_msg msg;
c5c77ba1 3720
a4ab1ade 3721 if (!hif_drv) {
24db713f
LK
3722 PRINT_ER("driver is null\n");
3723 return -EFAULT;
c5c77ba1
JK
3724 }
3725
143eb95a 3726 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3727
a9f812a6 3728 msg.id = HOST_IF_MSG_GET_CHNL;
a4ab1ade 3729 msg.drv = hif_drv;
c5c77ba1 3730
31390eec
LK
3731 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3732 if (result)
24db713f 3733 PRINT_ER("wilc mq send fail\n");
a4ab1ade 3734 down(&hif_drv->hSemGetCHNL);
c5c77ba1 3735
95ebb0ff 3736 *pu8ChNo = ch_no;
c5c77ba1 3737
31390eec 3738 return result;
c5c77ba1
JK
3739}
3740
a4ab1ade
TC
3741s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
3742 const u8 *mac, u32 *pu32InactiveTime)
c5c77ba1 3743{
31390eec 3744 s32 result = 0;
143eb95a 3745 struct host_if_msg msg;
c5c77ba1 3746
a4ab1ade 3747 if (!hif_drv) {
24db713f
LK
3748 PRINT_ER("driver is null\n");
3749 return -EFAULT;
c5c77ba1
JK
3750 }
3751
143eb95a 3752 memset(&msg, 0, sizeof(struct host_if_msg));
8c8360b3 3753 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
c5c77ba1 3754
a9f812a6 3755 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
a4ab1ade 3756 msg.drv = hif_drv;
c5c77ba1 3757
31390eec
LK
3758 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3759 if (result)
c5c77ba1
JK
3760 PRINT_ER("Failed to send get host channel param's message queue ");
3761
a4ab1ade 3762 down(&hif_drv->hSemInactiveTime);
c5c77ba1 3763
ad26906f 3764 *pu32InactiveTime = inactive_time;
c5c77ba1 3765
31390eec 3766 return result;
c5c77ba1 3767}
108b3439 3768
a4ab1ade 3769s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
c5c77ba1 3770{
31390eec 3771 s32 result = 0;
45102f83 3772 struct wid wid;
c5c77ba1 3773
a4ab1ade 3774 if (!hif_drv) {
24db713f
LK
3775 PRINT_ER("driver is null\n");
3776 return -EFAULT;
c5c77ba1
JK
3777 }
3778
45102f83
LK
3779 wid.id = (u16)WID_MEMORY_ADDRESS;
3780 wid.type = WID_INT;
3781 wid.val = (s8 *)pu32TestMemAddr;
3782 wid.size = sizeof(u32);
c5c77ba1 3783
45102f83 3784 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 3785 get_id_from_handler(hif_drv));
ae4dfa57 3786
31390eec 3787 if (result) {
24db713f
LK
3788 PRINT_ER("Failed to get wid value\n");
3789 return -EINVAL;
c5c77ba1
JK
3790 } else {
3791 PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
c5c77ba1
JK
3792 }
3793
31390eec 3794 return result;
c5c77ba1
JK
3795}
3796
a4ab1ade 3797s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
c5c77ba1 3798{
31390eec 3799 s32 result = 0;
143eb95a 3800 struct host_if_msg msg;
c5c77ba1 3801
c09389ac 3802 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3803 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 3804 msg.drv = hif_drv;
c5c77ba1 3805
31390eec
LK
3806 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3807 if (result) {
c5c77ba1 3808 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3809 return -EFAULT;
c5c77ba1
JK
3810 }
3811
a4ab1ade 3812 down(&hif_drv->hSemGetRSSI);
c5c77ba1 3813
91109e11 3814 if (!ps8Rssi) {
c5c77ba1 3815 PRINT_ER("RSS pointer value is null");
e6e12661 3816 return -EFAULT;
c5c77ba1
JK
3817 }
3818
144b7b23 3819 *ps8Rssi = rssi;
c5c77ba1 3820
31390eec 3821 return result;
c5c77ba1
JK
3822}
3823
a4ab1ade 3824s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
c5c77ba1 3825{
143eb95a 3826 struct host_if_msg msg;
31390eec 3827 s32 result = 0;
c5c77ba1 3828
c09389ac 3829 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3830 msg.id = HOST_IF_MSG_GET_LINKSPEED;
a4ab1ade 3831 msg.drv = hif_drv;
c5c77ba1 3832
31390eec
LK
3833 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3834 if (result) {
c5c77ba1 3835 PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
e6e12661 3836 return -EFAULT;
c5c77ba1
JK
3837 }
3838
a4ab1ade 3839 down(&hif_drv->hSemGetLINKSPEED);
c5c77ba1 3840
91109e11 3841 if (!ps8lnkspd) {
c5c77ba1 3842 PRINT_ER("LINKSPEED pointer value is null");
e6e12661 3843 return -EFAULT;
c5c77ba1
JK
3844 }
3845
75327a02 3846 *ps8lnkspd = link_speed;
c5c77ba1 3847
31390eec 3848 return result;
c5c77ba1
JK
3849}
3850
a4ab1ade 3851s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
c5c77ba1 3852{
31390eec 3853 s32 result = 0;
143eb95a 3854 struct host_if_msg msg;
c5c77ba1 3855
c09389ac 3856 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3857 msg.id = HOST_IF_MSG_GET_STATISTICS;
e60831e9 3858 msg.body.data = (char *)pstrStatistics;
a4ab1ade 3859 msg.drv = hif_drv;
ae4dfa57 3860
31390eec
LK
3861 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3862 if (result) {
c5c77ba1 3863 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3864 return -EFAULT;
c5c77ba1
JK
3865 }
3866
2d25af87 3867 down(&hif_sema_wait_response);
31390eec 3868 return result;
c5c77ba1
JK
3869}
3870
a4ab1ade
TC
3871s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
3872 u8 u8ScanType, u8 *pu8ChnlFreqList,
3873 u8 u8ChnlListLen, const u8 *pu8IEs,
3874 size_t IEsLen, wilc_scan_result ScanResult,
3875 void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
c5c77ba1 3876{
31390eec 3877 s32 result = 0;
143eb95a 3878 struct host_if_msg msg;
c5c77ba1 3879
91109e11 3880 if (!hif_drv || !ScanResult) {
a4ab1ade 3881 PRINT_ER("hif_drv or ScanResult = NULL\n");
24db713f
LK
3882 return -EFAULT;
3883 }
c5c77ba1 3884
143eb95a 3885 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3886
a9f812a6 3887 msg.id = HOST_IF_MSG_SCAN;
c5c77ba1 3888
91109e11 3889 if (pstrHiddenNetwork) {
629b9ca0
LK
3890 msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
3891 msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
c5c77ba1
JK
3892
3893 } else
3894 PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
3895
a4ab1ade 3896 msg.drv = hif_drv;
42568898 3897 msg.body.scan_info.src = u8ScanSource;
1e276c88 3898 msg.body.scan_info.type = u8ScanType;
c17c6da6 3899 msg.body.scan_info.result = ScanResult;
5f2b50c8 3900 msg.body.scan_info.arg = pvUserArg;
4528bdb5 3901
f97bd9ca 3902 msg.body.scan_info.ch_list_len = u8ChnlListLen;
82eeb0ad
LK
3903 msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL);
3904 memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen);
c5c77ba1 3905
7b1f76cd 3906 msg.body.scan_info.ies_len = IEsLen;
d6f19aa5
LK
3907 msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3908 memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen);
c5c77ba1 3909
31390eec
LK
3910 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3911 if (result) {
24db713f
LK
3912 PRINT_ER("Error in sending message queue\n");
3913 return -EINVAL;
c5c77ba1
JK
3914 }
3915
c5c77ba1 3916 PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
a4ab1ade
TC
3917 hif_drv->hScanTimer.data = (unsigned long)hif_drv;
3918 mod_timer(&hif_drv->hScanTimer,
9eb06643 3919 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
c5c77ba1 3920
31390eec 3921 return result;
c5c77ba1 3922}
ae4dfa57 3923
a4ab1ade
TC
3924s32 hif_set_cfg(struct host_if_drv *hif_drv,
3925 struct cfg_param_val *pstrCfgParamVal)
c5c77ba1 3926{
31390eec 3927 s32 result = 0;
143eb95a 3928 struct host_if_msg msg;
c5c77ba1 3929
a4ab1ade
TC
3930 if (!hif_drv) {
3931 PRINT_ER("hif_drv NULL\n");
24db713f
LK
3932 return -EFAULT;
3933 }
ae4dfa57 3934
143eb95a 3935 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3936 msg.id = HOST_IF_MSG_CFG_PARAMS;
221371e5 3937 msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
a4ab1ade 3938 msg.drv = hif_drv;
c5c77ba1 3939
31390eec 3940 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3941
31390eec 3942 return result;
c5c77ba1
JK
3943}
3944
a4ab1ade 3945s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
c5c77ba1 3946{
31390eec 3947 s32 result = 0;
c5c77ba1 3948
a4ab1ade 3949 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 3950
a4ab1ade
TC
3951 if (!hif_drv) {
3952 PRINT_ER("hif_drv NULL\n");
24db713f 3953 return -EFAULT;
c5c77ba1
JK
3954 }
3955 PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
3956 switch (u16WID) {
c5c77ba1 3957 case WID_BSS_TYPE:
a4ab1ade 3958 *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type;
c5c77ba1
JK
3959 break;
3960
3961 case WID_AUTH_TYPE:
a4ab1ade 3962 *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type;
c5c77ba1
JK
3963 break;
3964
3965 case WID_AUTH_TIMEOUT:
a4ab1ade 3966 *pu16WID_Value = hif_drv->strCfgValues.auth_timeout;
c5c77ba1
JK
3967 break;
3968
3969 case WID_POWER_MANAGEMENT:
a4ab1ade 3970 *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode;
c5c77ba1
JK
3971 break;
3972
3973 case WID_SHORT_RETRY_LIMIT:
a4ab1ade 3974 *pu16WID_Value = hif_drv->strCfgValues.short_retry_limit;
c5c77ba1
JK
3975 break;
3976
3977 case WID_LONG_RETRY_LIMIT:
a4ab1ade 3978 *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit;
c5c77ba1
JK
3979 break;
3980
3981 case WID_FRAG_THRESHOLD:
a4ab1ade 3982 *pu16WID_Value = hif_drv->strCfgValues.frag_threshold;
c5c77ba1
JK
3983 break;
3984
3985 case WID_RTS_THRESHOLD:
a4ab1ade 3986 *pu16WID_Value = hif_drv->strCfgValues.rts_threshold;
c5c77ba1
JK
3987 break;
3988
3989 case WID_PREAMBLE:
a4ab1ade 3990 *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type;
c5c77ba1
JK
3991 break;
3992
3993 case WID_SHORT_SLOT_ALLOWED:
a4ab1ade 3994 *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed;
c5c77ba1
JK
3995 break;
3996
3997 case WID_11N_TXOP_PROT_DISABLE:
a4ab1ade 3998 *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled;
c5c77ba1
JK
3999 break;
4000
4001 case WID_BEACON_INTERVAL:
a4ab1ade 4002 *pu16WID_Value = hif_drv->strCfgValues.beacon_interval;
c5c77ba1
JK
4003 break;
4004
4005 case WID_DTIM_PERIOD:
a4ab1ade 4006 *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period;
c5c77ba1
JK
4007 break;
4008
4009 case WID_SITE_SURVEY:
a4ab1ade 4010 *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled;
c5c77ba1
JK
4011 break;
4012
4013 case WID_SITE_SURVEY_SCAN_TIME:
a4ab1ade 4014 *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time;
c5c77ba1
JK
4015 break;
4016
4017 case WID_ACTIVE_SCAN_TIME:
a4ab1ade 4018 *pu16WID_Value = hif_drv->strCfgValues.active_scan_time;
c5c77ba1
JK
4019 break;
4020
4021 case WID_PASSIVE_SCAN_TIME:
a4ab1ade 4022 *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time;
c5c77ba1
JK
4023 break;
4024
4025 case WID_CURRENT_TX_RATE:
a4ab1ade 4026 *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate;
c5c77ba1
JK
4027 break;
4028
4029 default:
4030 break;
4031 }
4032
a4ab1ade 4033 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4034
31390eec 4035 return result;
c5c77ba1
JK
4036}
4037
93dee8ee 4038static void GetPeriodicRSSI(unsigned long arg)
c5c77ba1 4039{
a4ab1ade 4040 struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
78c87591 4041
a4ab1ade 4042 if (!hif_drv) {
c5c77ba1
JK
4043 PRINT_ER("Driver handler is NULL\n");
4044 return;
4045 }
4046
a4ab1ade 4047 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) {
31390eec 4048 s32 result = 0;
143eb95a 4049 struct host_if_msg msg;
c5c77ba1 4050
143eb95a 4051 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4052
a9f812a6 4053 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 4054 msg.drv = hif_drv;
c5c77ba1 4055
31390eec
LK
4056 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4057 if (result) {
c5c77ba1
JK
4058 PRINT_ER("Failed to send get host channel param's message queue ");
4059 return;
4060 }
4061 }
262f55e1
LK
4062 periodic_rssi.data = (unsigned long)hif_drv;
4063 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4064}
4065
d5382219 4066s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
c5c77ba1 4067{
5b09bd32 4068 s32 result = 0;
a4ab1ade 4069 struct host_if_drv *hif_drv;
d42ab083 4070 int err;
d5382219
GL
4071 perInterface_wlan_t *nic;
4072 struct wilc *wilc;
4073
4074 nic = netdev_priv(dev);
4075 wilc = nic->wilc;
c5c77ba1 4076
c5c77ba1
JK
4077 PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
4078
ca8540e4 4079 scan_while_connected = false;
c5c77ba1 4080
2d25af87 4081 sema_init(&hif_sema_wait_response, 0);
c5c77ba1 4082
a4ab1ade
TC
4083 hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
4084 if (!hif_drv) {
5b09bd32 4085 result = -ENOMEM;
17db84eb 4086 goto _fail_;
c5c77ba1 4087 }
a4ab1ade
TC
4088 *hif_drv_handler = hif_drv;
4089 err = add_handler_in_list(hif_drv);
d42ab083 4090 if (err) {
5b09bd32 4091 result = -EFAULT;
d42ab083
JK
4092 goto _fail_timer_2;
4093 }
c5c77ba1 4094
72ed4dc7 4095 g_obtainingIP = false;
c5c77ba1 4096
a4ab1ade 4097 PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
c5c77ba1 4098 if (clients_count == 0) {
834e0cb0 4099 sema_init(&hif_sema_thread, 0);
27ff2168 4100 sema_init(&hif_sema_driver, 0);
440e8993 4101 sema_init(&hif_sema_deinit, 1);
83383ea3
AB
4102 }
4103
a4ab1ade
TC
4104 sema_init(&hif_drv->hSemTestKeyBlock, 0);
4105 sema_init(&hif_drv->hSemTestDisconnectBlock, 0);
4106 sema_init(&hif_drv->hSemGetRSSI, 0);
4107 sema_init(&hif_drv->hSemGetLINKSPEED, 0);
4108 sema_init(&hif_drv->hSemGetCHNL, 0);
4109 sema_init(&hif_drv->hSemInactiveTime, 0);
c5c77ba1 4110
c5c77ba1
JK
4111 PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
4112
4113 if (clients_count == 0) {
cb067dcf 4114 result = wilc_mq_create(&hif_msg_q);
c5c77ba1 4115
5b09bd32 4116 if (result < 0) {
c5c77ba1
JK
4117 PRINT_ER("Failed to creat MQ\n");
4118 goto _fail_;
4119 }
c2115d8e 4120
d5382219
GL
4121 hif_thread_handler = kthread_run(hostIFthread, wilc,
4122 "WILC_kthread");
c2115d8e
LK
4123
4124 if (IS_ERR(hif_thread_handler)) {
c5c77ba1 4125 PRINT_ER("Failed to creat Thread\n");
5b09bd32 4126 result = -EFAULT;
c5c77ba1
JK
4127 goto _fail_mq_;
4128 }
262f55e1 4129 setup_timer(&periodic_rssi, GetPeriodicRSSI,
a4ab1ade 4130 (unsigned long)hif_drv);
262f55e1 4131 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4132 }
4133
a4ab1ade 4134 setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0);
c5c77ba1 4135
a4ab1ade 4136 setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0);
c5c77ba1 4137
a4ab1ade 4138 setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0);
c5c77ba1 4139
bafaa696 4140 sema_init(&hif_drv->gtOsCfgValuesSem, 1);
a4ab1ade 4141 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4142
a4ab1ade 4143 hif_drv->enuHostIFstate = HOST_IF_IDLE;
a4ab1ade
TC
4144 hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
4145 hif_drv->strCfgValues.scan_source = DEFAULT_SCAN;
4146 hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
4147 hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
4148 hif_drv->strCfgValues.curr_tx_rate = AUTORATE;
c5c77ba1 4149
a4ab1ade 4150 hif_drv->u64P2p_MgmtTimeout = 0;
c5c77ba1 4151
c5c77ba1
JK
4152 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",
4153
a4ab1ade
TC
4154 hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source,
4155 hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time,
4156 hif_drv->strCfgValues.curr_tx_rate);
c5c77ba1 4157
a4ab1ade 4158 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4159
ae4dfa57 4160 clients_count++;
c5c77ba1 4161
5b09bd32 4162 return result;
c5c77ba1 4163
c5c77ba1 4164_fail_timer_2:
a4ab1ade
TC
4165 up(&hif_drv->gtOsCfgValuesSem);
4166 del_timer_sync(&hif_drv->hConnectTimer);
4167 del_timer_sync(&hif_drv->hScanTimer);
c2115d8e 4168 kthread_stop(hif_thread_handler);
c5c77ba1 4169_fail_mq_:
cb067dcf 4170 wilc_mq_destroy(&hif_msg_q);
c5c77ba1 4171_fail_:
5b09bd32 4172 return result;
c5c77ba1 4173}
c5c77ba1 4174
a4ab1ade 4175s32 host_int_deinit(struct host_if_drv *hif_drv)
c5c77ba1 4176{
31390eec 4177 s32 result = 0;
143eb95a 4178 struct host_if_msg msg;
d42ab083 4179 int ret;
c5c77ba1 4180
a4ab1ade
TC
4181 if (!hif_drv) {
4182 PRINT_ER("hif_drv = NULL\n");
c5c77ba1
JK
4183 return 0;
4184 }
4185
440e8993 4186 down(&hif_sema_deinit);
c5c77ba1 4187
a4ab1ade 4188 terminated_handle = hif_drv;
c5c77ba1
JK
4189 PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
4190
d1666e2a 4191 if (del_timer_sync(&hif_drv->hScanTimer))
03b2d5e7 4192 PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
c5c77ba1 4193
d1666e2a 4194 if (del_timer_sync(&hif_drv->hConnectTimer))
03b2d5e7 4195 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1 4196
262f55e1 4197 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4198 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1 4199
a4ab1ade 4200 del_timer_sync(&hif_drv->hRemainOnChannel);
c5c77ba1 4201
218dc407 4202 host_int_set_wfi_drv_handler(NULL);
27ff2168 4203 down(&hif_sema_driver);
c5c77ba1 4204
70793b2a
LK
4205 if (hif_drv->usr_scan_req.pfUserScanResult) {
4206 hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
4207 hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
c5c77ba1 4208
70793b2a 4209 hif_drv->usr_scan_req.pfUserScanResult = NULL;
c5c77ba1 4210 }
c5c77ba1 4211
a4ab1ade 4212 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 4213
ca8540e4 4214 scan_while_connected = false;
c5c77ba1 4215
143eb95a 4216 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4217
4218 if (clients_count == 1) {
262f55e1 4219 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4220 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
262f55e1 4221
a9f812a6 4222 msg.id = HOST_IF_MSG_EXIT;
a4ab1ade 4223 msg.drv = hif_drv;
c5c77ba1 4224
31390eec
LK
4225 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4226 if (result != 0)
4227 PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
c5c77ba1 4228
834e0cb0 4229 down(&hif_sema_thread);
c5c77ba1 4230
cb067dcf 4231 wilc_mq_destroy(&hif_msg_q);
c5c77ba1
JK
4232 }
4233
bafaa696 4234 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4235
a4ab1ade 4236 ret = remove_handler_in_list(hif_drv);
d42ab083 4237 if (ret)
31390eec 4238 result = -ENOENT;
d42ab083 4239
a4ab1ade 4240 kfree(hif_drv);
c5c77ba1 4241
ae4dfa57 4242 clients_count--;
b1413b60 4243 terminated_handle = NULL;
440e8993 4244 up(&hif_sema_deinit);
31390eec 4245 return result;
c5c77ba1
JK
4246}
4247
4e4467fd 4248void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4249{
31390eec 4250 s32 result = 0;
143eb95a 4251 struct host_if_msg msg;
d42ab083 4252 int id;
a4ab1ade 4253 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4254
d42ab083 4255 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4256 hif_drv = get_handler_from_id(id);
c5c77ba1 4257
a4ab1ade
TC
4258 if (!hif_drv || hif_drv == terminated_handle) {
4259 PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
c5c77ba1
JK
4260 return;
4261 }
4262
143eb95a 4263 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4264
a9f812a6 4265 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
a4ab1ade 4266 msg.drv = hif_drv;
c5c77ba1 4267
3bffac68 4268 msg.body.net_info.len = u32Length;
b021b80b
LK
4269 msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4270 memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4271
31390eec
LK
4272 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4273 if (result)
4274 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
c5c77ba1
JK
4275}
4276
4e4467fd 4277void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4278{
31390eec 4279 s32 result = 0;
143eb95a 4280 struct host_if_msg msg;
d42ab083 4281 int id;
a4ab1ade 4282 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4283
440e8993 4284 down(&hif_sema_deinit);
c5c77ba1 4285
d42ab083 4286 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4287 hif_drv = get_handler_from_id(id);
03b2d5e7 4288 PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
c5c77ba1 4289
a4ab1ade 4290 if (!hif_drv || hif_drv == terminated_handle) {
c5c77ba1 4291 PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
440e8993 4292 up(&hif_sema_deinit);
c5c77ba1
JK
4293 return;
4294 }
4295
f8b17132 4296 if (!hif_drv->usr_conn_req.pfUserConnectResult) {
c5c77ba1 4297 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
440e8993 4298 up(&hif_sema_deinit);
c5c77ba1
JK
4299 return;
4300 }
4301
143eb95a 4302 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4303
a9f812a6 4304 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
a4ab1ade 4305 msg.drv = hif_drv;
c5c77ba1 4306
f94f4889 4307 msg.body.async_info.len = u32Length;
33722ac7
LK
4308 msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4309 memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4310
31390eec
LK
4311 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4312 if (result)
4313 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
c5c77ba1 4314
440e8993 4315 up(&hif_sema_deinit);
c5c77ba1
JK
4316}
4317
4e4467fd 4318void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4319{
31390eec 4320 s32 result = 0;
143eb95a 4321 struct host_if_msg msg;
d42ab083 4322 int id;
a4ab1ade 4323 struct host_if_drv *hif_drv = NULL;
78c87591 4324
d42ab083 4325 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4326 hif_drv = get_handler_from_id(id);
c5c77ba1 4327
a4ab1ade 4328 PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
c5c77ba1 4329
a4ab1ade 4330 if (!hif_drv || hif_drv == terminated_handle)
c5c77ba1 4331 return;
c5c77ba1 4332
70793b2a 4333 if (hif_drv->usr_scan_req.pfUserScanResult) {
143eb95a 4334 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4335
a9f812a6 4336 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
a4ab1ade 4337 msg.drv = hif_drv;
c5c77ba1 4338
31390eec
LK
4339 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4340 if (result)
4341 PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
c5c77ba1
JK
4342 }
4343
c5c77ba1 4344 return;
c5c77ba1
JK
4345}
4346
a4ab1ade
TC
4347s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
4348 u32 u32duration, u16 chan,
4349 wilc_remain_on_chan_expired RemainOnChanExpired,
4350 wilc_remain_on_chan_ready RemainOnChanReady,
4351 void *pvUserArg)
c5c77ba1 4352{
31390eec 4353 s32 result = 0;
143eb95a 4354 struct host_if_msg msg;
c5c77ba1 4355
a4ab1ade 4356 if (!hif_drv) {
24db713f
LK
4357 PRINT_ER("driver is null\n");
4358 return -EFAULT;
4359 }
c5c77ba1 4360
143eb95a 4361 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4362
a9f812a6 4363 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
070d365c
TC
4364 msg.body.remain_on_ch.u16Channel = chan;
4365 msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
4366 msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
4367 msg.body.remain_on_ch.pVoid = pvUserArg;
4368 msg.body.remain_on_ch.u32duration = u32duration;
4369 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
a4ab1ade 4370 msg.drv = hif_drv;
143eb95a 4371
31390eec
LK
4372 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4373 if (result)
24db713f 4374 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4375
31390eec 4376 return result;
c5c77ba1
JK
4377}
4378
a4ab1ade 4379s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
c5c77ba1 4380{
31390eec 4381 s32 result = 0;
143eb95a 4382 struct host_if_msg msg;
c5c77ba1 4383
a4ab1ade 4384 if (!hif_drv) {
24db713f
LK
4385 PRINT_ER("driver is null\n");
4386 return -EFAULT;
4387 }
c5c77ba1 4388
a4ab1ade 4389 del_timer(&hif_drv->hRemainOnChannel);
c5c77ba1 4390
143eb95a 4391 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 4392 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
a4ab1ade 4393 msg.drv = hif_drv;
070d365c 4394 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
c5c77ba1 4395
31390eec
LK
4396 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4397 if (result)
24db713f 4398 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4399
31390eec 4400 return result;
c5c77ba1
JK
4401}
4402
a4ab1ade 4403s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
c5c77ba1 4404{
31390eec 4405 s32 result = 0;
143eb95a 4406 struct host_if_msg msg;
c5c77ba1 4407
a4ab1ade 4408 if (!hif_drv) {
24db713f
LK
4409 PRINT_ER("driver is null\n");
4410 return -EFAULT;
4411 }
c5c77ba1 4412
143eb95a 4413 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4414
a9f812a6 4415 msg.id = HOST_IF_MSG_REGISTER_FRAME;
c5c77ba1
JK
4416 switch (u16FrameType) {
4417 case ACTION:
4418 PRINT_D(HOSTINF_DBG, "ACTION\n");
5c4008db 4419 msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
c5c77ba1
JK
4420 break;
4421
4422 case PROBE_REQ:
4423 PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
5c4008db 4424 msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
c5c77ba1
JK
4425 break;
4426
4427 default:
4428 PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
4429 break;
4430 }
5c4008db
TC
4431 msg.body.reg_frame.u16FrameType = u16FrameType;
4432 msg.body.reg_frame.bReg = bReg;
a4ab1ade 4433 msg.drv = hif_drv;
c5c77ba1 4434
31390eec
LK
4435 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4436 if (result)
24db713f 4437 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4438
31390eec 4439 return result;
c5c77ba1 4440}
c5c77ba1 4441
a4ab1ade
TC
4442s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
4443 u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
4444 u32 u32TailLen, u8 *pu8Tail)
c5c77ba1 4445{
31390eec 4446 s32 result = 0;
143eb95a 4447 struct host_if_msg msg;
a98491e5 4448 struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
c5c77ba1 4449
a4ab1ade 4450 if (!hif_drv) {
24db713f
LK
4451 PRINT_ER("driver is null\n");
4452 return -EFAULT;
4453 }
c5c77ba1 4454
143eb95a 4455 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4456
4457 PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
4458
a9f812a6 4459 msg.id = HOST_IF_MSG_ADD_BEACON;
a4ab1ade 4460 msg.drv = hif_drv;
12262dda 4461 pstrSetBeaconParam->interval = u32Interval;
e76ab770 4462 pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
51c66185 4463 pstrSetBeaconParam->head_len = u32HeadLen;
543f5b13 4464 pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL);
91109e11 4465 if (!pstrSetBeaconParam->head) {
31390eec 4466 result = -ENOMEM;
24db713f
LK
4467 goto ERRORHANDLER;
4468 }
030c57e2 4469 pstrSetBeaconParam->tail_len = u32TailLen;
c5c77ba1 4470
c5c77ba1 4471 if (u32TailLen > 0) {
543f5b13
SB
4472 pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen,
4473 GFP_KERNEL);
91109e11 4474 if (!pstrSetBeaconParam->tail) {
31390eec 4475 result = -ENOMEM;
24db713f
LK
4476 goto ERRORHANDLER;
4477 }
c5c77ba1 4478 } else {
7dbcb6d3 4479 pstrSetBeaconParam->tail = NULL;
c5c77ba1
JK
4480 }
4481
31390eec
LK
4482 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4483 if (result)
24db713f 4484 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4485
24db713f 4486ERRORHANDLER:
31390eec 4487 if (result) {
95f840fb 4488 kfree(pstrSetBeaconParam->head);
c5c77ba1 4489
95f840fb 4490 kfree(pstrSetBeaconParam->tail);
c5c77ba1
JK
4491 }
4492
31390eec 4493 return result;
c5c77ba1
JK
4494}
4495
a4ab1ade 4496s32 host_int_del_beacon(struct host_if_drv *hif_drv)
c5c77ba1 4497{
31390eec 4498 s32 result = 0;
143eb95a 4499 struct host_if_msg msg;
c5c77ba1 4500
a4ab1ade 4501 if (!hif_drv) {
24db713f
LK
4502 PRINT_ER("driver is null\n");
4503 return -EFAULT;
4504 }
c5c77ba1 4505
a9f812a6 4506 msg.id = HOST_IF_MSG_DEL_BEACON;
a4ab1ade 4507 msg.drv = hif_drv;
c5c77ba1
JK
4508 PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
4509
31390eec
LK
4510 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4511 if (result)
7dc1d0cc 4512 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4513
31390eec 4514 return result;
c5c77ba1
JK
4515}
4516
a4ab1ade 4517s32 host_int_add_station(struct host_if_drv *hif_drv,
6a89ba9c 4518 struct add_sta_param *pstrStaParams)
c5c77ba1 4519{
31390eec 4520 s32 result = 0;
143eb95a 4521 struct host_if_msg msg;
ca8f47f8 4522 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1 4523
a4ab1ade 4524 if (!hif_drv) {
24db713f
LK
4525 PRINT_ER("driver is null\n");
4526 return -EFAULT;
4527 }
c5c77ba1 4528
143eb95a 4529 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4530
4531 PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
4532
a9f812a6 4533 msg.id = HOST_IF_MSG_ADD_STATION;
a4ab1ade 4534 msg.drv = hif_drv;
c5c77ba1 4535
6a89ba9c 4536 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4537 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4538 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
c09389ac 4539
7ae43363
LK
4540 if (!rates)
4541 return -ENOMEM;
c5c77ba1 4542
d00d2ba3 4543 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4544 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4545 }
4546
31390eec
LK
4547 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4548 if (result)
24db713f 4549 PRINT_ER("wilc_mq_send fail\n");
31390eec 4550 return result;
c5c77ba1
JK
4551}
4552
a4ab1ade 4553s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr)
c5c77ba1 4554{
31390eec 4555 s32 result = 0;
143eb95a 4556 struct host_if_msg msg;
889c25be 4557 struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
c5c77ba1 4558
a4ab1ade 4559 if (!hif_drv) {
24db713f
LK
4560 PRINT_ER("driver is null\n");
4561 return -EFAULT;
4562 }
c5c77ba1 4563
143eb95a 4564 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4565
4566 PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
4567
a9f812a6 4568 msg.id = HOST_IF_MSG_DEL_STATION;
a4ab1ade 4569 msg.drv = hif_drv;
c5c77ba1 4570
91109e11 4571 if (!pu8MacAddr)
e4839d39 4572 memset(pstrDelStationMsg->mac_addr, 255, ETH_ALEN);
c5c77ba1 4573 else
e4839d39 4574 memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN);
c5c77ba1 4575
31390eec
LK
4576 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4577 if (result)
24db713f 4578 PRINT_ER("wilc_mq_send fail\n");
31390eec 4579 return result;
c5c77ba1 4580}
ae4dfa57 4581
a4ab1ade 4582s32 host_int_del_allstation(struct host_if_drv *hif_drv,
441dc609 4583 u8 pu8MacAddr[][ETH_ALEN])
c5c77ba1 4584{
31390eec 4585 s32 result = 0;
143eb95a 4586 struct host_if_msg msg;
b0c1e80e 4587 struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
63d03e47 4588 u8 au8Zero_Buff[ETH_ALEN] = {0};
4e4467fd 4589 u32 i;
63d03e47 4590 u8 u8AssocNumb = 0;
c5c77ba1 4591
a4ab1ade 4592 if (!hif_drv) {
24db713f
LK
4593 PRINT_ER("driver is null\n");
4594 return -EFAULT;
4595 }
c5c77ba1 4596
143eb95a 4597 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4598
4599 PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
4600
a9f812a6 4601 msg.id = HOST_IF_MSG_DEL_ALL_STA;
a4ab1ade 4602 msg.drv = hif_drv;
c5c77ba1 4603
c5c77ba1
JK
4604 for (i = 0; i < MAX_NUM_STA; i++) {
4605 if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
e51b9216
LK
4606 memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN);
4607 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4608 pstrDelAllStationMsg->del_all_sta[i][0],
4609 pstrDelAllStationMsg->del_all_sta[i][1],
4610 pstrDelAllStationMsg->del_all_sta[i][2],
4611 pstrDelAllStationMsg->del_all_sta[i][3],
4612 pstrDelAllStationMsg->del_all_sta[i][4],
4613 pstrDelAllStationMsg->del_all_sta[i][5]);
c5c77ba1
JK
4614 u8AssocNumb++;
4615 }
4616 }
4617 if (!u8AssocNumb) {
4618 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
31390eec 4619 return result;
c5c77ba1
JK
4620 }
4621
8ba1803f 4622 pstrDelAllStationMsg->assoc_sta = u8AssocNumb;
31390eec 4623 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 4624
31390eec 4625 if (result)
24db713f 4626 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4627
2d25af87 4628 down(&hif_sema_wait_response);
c5c77ba1 4629
31390eec 4630 return result;
c5c77ba1
JK
4631}
4632
a4ab1ade 4633s32 host_int_edit_station(struct host_if_drv *hif_drv,
6a89ba9c 4634 struct add_sta_param *pstrStaParams)
c5c77ba1 4635{
31390eec 4636 s32 result = 0;
143eb95a 4637 struct host_if_msg msg;
ca8f47f8 4638 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1 4639
a4ab1ade 4640 if (!hif_drv) {
24db713f
LK
4641 PRINT_ER("driver is null\n");
4642 return -EFAULT;
4643 }
c5c77ba1
JK
4644
4645 PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
4646
143eb95a 4647 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4648
a9f812a6 4649 msg.id = HOST_IF_MSG_EDIT_STATION;
a4ab1ade 4650 msg.drv = hif_drv;
c5c77ba1 4651
6a89ba9c 4652 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4653 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4654 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
c09389ac 4655
7ae43363
LK
4656 if (!rates)
4657 return -ENOMEM;
4658
d00d2ba3 4659 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4660 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4661 }
4662
31390eec
LK
4663 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4664 if (result)
24db713f
LK
4665 PRINT_ER("wilc_mq_send fail\n");
4666
31390eec 4667 return result;
c5c77ba1 4668}
108b3439 4669
a4ab1ade
TC
4670s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
4671 bool bIsEnabled,
4672 u32 u32Timeout)
c5c77ba1 4673{
31390eec 4674 s32 result = 0;
143eb95a 4675 struct host_if_msg msg;
49e1f81b 4676 struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
c5c77ba1 4677
03b2d5e7 4678 PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
c5c77ba1 4679
a4ab1ade 4680 if (!hif_drv) {
24db713f
LK
4681 PRINT_ER("driver is null\n");
4682 return -EFAULT;
4683 }
c5c77ba1
JK
4684
4685 PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
4686
143eb95a 4687 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4688
a9f812a6 4689 msg.id = HOST_IF_MSG_POWER_MGMT;
a4ab1ade 4690 msg.drv = hif_drv;
c5c77ba1 4691
33c70c1b 4692 pstrPowerMgmtParam->enabled = bIsEnabled;
937918ff 4693 pstrPowerMgmtParam->timeout = u32Timeout;
c5c77ba1 4694
31390eec
LK
4695 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4696 if (result)
24db713f 4697 PRINT_ER("wilc_mq_send fail\n");
31390eec 4698 return result;
c5c77ba1
JK
4699}
4700
a4ab1ade
TC
4701s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
4702 bool bIsEnabled,
4703 u32 u32count)
c5c77ba1 4704{
31390eec 4705 s32 result = 0;
143eb95a 4706 struct host_if_msg msg;
a079cf4d 4707 struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
c5c77ba1 4708
a4ab1ade 4709 if (!hif_drv) {
24db713f
LK
4710 PRINT_ER("driver is null\n");
4711 return -EFAULT;
4712 }
c5c77ba1
JK
4713
4714 PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
4715
143eb95a 4716 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4717
a9f812a6 4718 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
a4ab1ade 4719 msg.drv = hif_drv;
c5c77ba1 4720
bae636eb 4721 pstrMulticastFilterParam->enabled = bIsEnabled;
adab2f71 4722 pstrMulticastFilterParam->cnt = u32count;
c5c77ba1 4723
31390eec
LK
4724 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4725 if (result)
24db713f 4726 PRINT_ER("wilc_mq_send fail\n");
31390eec 4727 return result;
c5c77ba1
JK
4728}
4729
c5c77ba1
JK
4730static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
4731{
e0a12217 4732 struct join_bss_param *pNewJoinBssParam = NULL;
63d03e47 4733 u8 *pu8IEs;
d85f5326
CL
4734 u16 u16IEsLen;
4735 u16 index = 0;
63d03e47
GKH
4736 u8 suppRatesNo = 0;
4737 u8 extSuppRatesNo;
d85f5326 4738 u16 jumpOffset;
63d03e47
GKH
4739 u8 pcipherCount;
4740 u8 authCount;
4741 u8 pcipherTotalCount = 0;
4742 u8 authTotalCount = 0;
4743 u8 i, j;
c5c77ba1
JK
4744
4745 pu8IEs = ptstrNetworkInfo->pu8IEs;
4746 u16IEsLen = ptstrNetworkInfo->u16IEsLen;
4747
b156f1ed 4748 pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
91109e11 4749 if (pNewJoinBssParam) {
c5c77ba1
JK
4750 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
4751 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
4752 pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
d00d2ba3 4753 memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
d00d2ba3 4754 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
619d27b8 4755 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen;
2cc46837
CL
4756 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4757 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
c5c77ba1 4758
c5c77ba1 4759 while (index < u16IEsLen) {
c5c77ba1 4760 if (pu8IEs[index] == SUPP_RATES_IE) {
c5c77ba1
JK
4761 suppRatesNo = pu8IEs[index + 1];
4762 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
ae4dfa57 4763 index += 2;
c5c77ba1 4764
d1666e2a 4765 for (i = 0; i < suppRatesNo; i++)
c5c77ba1 4766 pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
d1666e2a 4767
c5c77ba1
JK
4768 index += suppRatesNo;
4769 continue;
ae4dfa57 4770 } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
c5c77ba1
JK
4771 extSuppRatesNo = pu8IEs[index + 1];
4772 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4773 pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4774 else
4775 pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4776 index += 2;
d1666e2a 4777 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
c5c77ba1 4778 pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
d1666e2a 4779
c5c77ba1
JK
4780 index += extSuppRatesNo;
4781 continue;
ae4dfa57 4782 } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
0be1eb74 4783 pNewJoinBssParam->ht_capable = true;
ae4dfa57 4784 index += pu8IEs[index + 1] + 2;
c5c77ba1 4785 continue;
ae4dfa57 4786 } else if ((pu8IEs[index] == WMM_IE) &&
c5c77ba1 4787 (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
ae4dfa57
LK
4788 (pu8IEs[index + 4] == 0xF2) &&
4789 (pu8IEs[index + 5] == 0x02) &&
4790 ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
c5c77ba1 4791 (pu8IEs[index + 7] == 0x01)) {
0be1eb74 4792 pNewJoinBssParam->wmm_cap = true;
c5c77ba1 4793
ffda203c 4794 if (pu8IEs[index + 8] & BIT(7))
0be1eb74 4795 pNewJoinBssParam->uapsd_cap = true;
c5c77ba1
JK
4796 index += pu8IEs[index + 1] + 2;
4797 continue;
ae4dfa57 4798 } else if ((pu8IEs[index] == P2P_IE) &&
c5c77ba1 4799 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
ae4dfa57
LK
4800 (pu8IEs[index + 4] == 0x9a) &&
4801 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
d85f5326 4802 u16 u16P2P_count;
78c87591 4803
c5c77ba1 4804 pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
7a8d51d7 4805 pNewJoinBssParam->noa_enabled = 1;
cc179008 4806 pNewJoinBssParam->idx = pu8IEs[index + 9];
c5c77ba1 4807
ffda203c 4808 if (pu8IEs[index + 10] & BIT(7)) {
d72b33ca 4809 pNewJoinBssParam->opp_enabled = 1;
99b66945 4810 pNewJoinBssParam->ct_window = pu8IEs[index + 10];
d72b33ca
LK
4811 } else {
4812 pNewJoinBssParam->opp_enabled = 0;
4813 }
ae4dfa57 4814
03b2d5e7 4815 PRINT_D(GENERIC_DBG, "P2P Dump\n");
c5c77ba1 4816 for (i = 0; i < pu8IEs[index + 7]; i++)
03b2d5e7 4817 PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
c5c77ba1 4818
c21047ed 4819 pNewJoinBssParam->cnt = pu8IEs[index + 11];
c5c77ba1
JK
4820 u16P2P_count = index + 12;
4821
109e6cab 4822 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4823 u16P2P_count += 4;
4824
1d8b76b3 4825 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4826 u16P2P_count += 4;
4827
4be55e22 4828 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4829
4830 index += pu8IEs[index + 1] + 2;
4831 continue;
4832
ae4dfa57 4833 } else if ((pu8IEs[index] == RSN_IE) ||
c5c77ba1
JK
4834 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4835 (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4836 (pu8IEs[index + 5] == 0x01))) {
d85f5326 4837 u16 rsnIndex = index;
ae4dfa57 4838
c5c77ba1
JK
4839 if (pu8IEs[rsnIndex] == RSN_IE) {
4840 pNewJoinBssParam->mode_802_11i = 2;
ae4dfa57 4841 } else {
c5c77ba1
JK
4842 if (pNewJoinBssParam->mode_802_11i == 0)
4843 pNewJoinBssParam->mode_802_11i = 1;
c5c77ba1
JK
4844 rsnIndex += 4;
4845 }
ae4dfa57
LK
4846
4847 rsnIndex += 7;
c5c77ba1
JK
4848 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4849 rsnIndex++;
ae4dfa57 4850 jumpOffset = pu8IEs[rsnIndex] * 4;
c5c77ba1 4851 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4852 rsnIndex += 2;
c5c77ba1 4853
d1666e2a 4854 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
c5c77ba1 4855 pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
d1666e2a 4856
c5c77ba1
JK
4857 pcipherTotalCount += pcipherCount;
4858 rsnIndex += jumpOffset;
4859
4860 jumpOffset = pu8IEs[rsnIndex] * 4;
4861
c5c77ba1 4862 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4863 rsnIndex += 2;
c5c77ba1 4864
d1666e2a 4865 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
c5c77ba1 4866 pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
d1666e2a 4867
c5c77ba1
JK
4868 authTotalCount += authCount;
4869 rsnIndex += jumpOffset;
ae4dfa57 4870
c5c77ba1
JK
4871 if (pu8IEs[index] == RSN_IE) {
4872 pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4873 pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4874 rsnIndex += 2;
4875 }
f717c0eb 4876 pNewJoinBssParam->rsn_found = true;
ae4dfa57 4877 index += pu8IEs[index + 1] + 2;
c5c77ba1
JK
4878 continue;
4879 } else
ae4dfa57 4880 index += pu8IEs[index + 1] + 2;
c5c77ba1 4881 }
c5c77ba1
JK
4882 }
4883
4884 return (void *)pNewJoinBssParam;
c5c77ba1
JK
4885}
4886
4887void host_int_freeJoinParams(void *pJoinParams)
4888{
91109e11 4889 if ((struct bss_param *)pJoinParams)
e0a12217 4890 kfree((struct bss_param *)pJoinParams);
c5c77ba1
JK
4891 else
4892 PRINT_ER("Unable to FREE null pointer\n");
4893}
c5c77ba1 4894
a4ab1ade 4895s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
c5c77ba1 4896{
31390eec 4897 s32 result = 0;
143eb95a 4898 struct host_if_msg msg;
c833b474 4899 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 4900
a4ab1ade 4901 if (!hif_drv) {
24db713f
LK
4902 PRINT_ER("driver is null\n");
4903 return -EFAULT;
4904 }
c5c77ba1 4905
143eb95a 4906 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4907
a9f812a6 4908 msg.id = HOST_IF_MSG_DEL_BA_SESSION;
c5c77ba1
JK
4909
4910 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4911 pBASessionInfo->u8Ted = TID;
a4ab1ade 4912 msg.drv = hif_drv;
c5c77ba1 4913
31390eec
LK
4914 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4915 if (result)
24db713f 4916 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4917
2d25af87 4918 down(&hif_sema_wait_response);
c5c77ba1 4919
31390eec 4920 return result;
c5c77ba1
JK
4921}
4922
a4ab1ade
TC
4923s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
4924 char *pBSSID,
4925 char TID)
c5c77ba1 4926{
31390eec 4927 s32 result = 0;
143eb95a 4928 struct host_if_msg msg;
c833b474 4929 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 4930
a4ab1ade 4931 if (!hif_drv) {
24db713f
LK
4932 PRINT_ER("driver is null\n");
4933 return -EFAULT;
4934 }
c5c77ba1 4935
143eb95a 4936 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4937
a9f812a6 4938 msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
c5c77ba1
JK
4939
4940 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4941 pBASessionInfo->u8Ted = TID;
a4ab1ade 4942 msg.drv = hif_drv;
c5c77ba1 4943
31390eec
LK
4944 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4945 if (result)
24db713f 4946 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4947
2d25af87 4948 down(&hif_sema_wait_response);
c5c77ba1 4949
31390eec 4950 return result;
c5c77ba1
JK
4951}
4952
a4ab1ade 4953s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 4954{
31390eec 4955 s32 result = 0;
143eb95a 4956 struct host_if_msg msg;
c5c77ba1 4957
c5c77ba1
JK
4958 return 0;
4959
a4ab1ade 4960 if (!hif_drv) {
24db713f
LK
4961 PRINT_ER("driver is null\n");
4962 return -EFAULT;
4963 }
c5c77ba1 4964
143eb95a 4965 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4966
a9f812a6 4967 msg.id = HOST_IF_MSG_SET_IPADDRESS;
c5c77ba1 4968
78675be5 4969 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 4970 msg.drv = hif_drv;
fb2d65ed 4971 msg.body.ip_info.idx = idx;
c5c77ba1 4972
31390eec
LK
4973 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4974 if (result)
24db713f 4975 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4976
31390eec 4977 return result;
c5c77ba1
JK
4978}
4979
a4ab1ade 4980s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 4981{
31390eec 4982 s32 result = 0;
143eb95a 4983 struct host_if_msg msg;
c5c77ba1 4984
a4ab1ade 4985 if (!hif_drv) {
24db713f
LK
4986 PRINT_ER("driver is null\n");
4987 return -EFAULT;
4988 }
c5c77ba1 4989
143eb95a 4990 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4991
a9f812a6 4992 msg.id = HOST_IF_MSG_GET_IPADDRESS;
c5c77ba1 4993
78675be5 4994 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 4995 msg.drv = hif_drv;
fb2d65ed 4996 msg.body.ip_info.idx = idx;
c5c77ba1 4997
31390eec
LK
4998 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4999 if (result)
24db713f 5000 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 5001
31390eec 5002 return result;
c5c77ba1 5003}