]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/staging/wilc1000/host_interface.c
staging: wilc1000: Remove inclusion of version.h
[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,
a76dc953 3145 u8 index,
730a28da 3146 u8 mode,
ff3bce2f 3147 enum AUTHTYPE auth_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;
58eabd68
CL
3168 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
3169 if (!msg.body.key_info.attr.wep.key)
3170 return -ENOMEM;
3171
a5389b07 3172 msg.body.key_info.attr.wep.key_len = len;
a76dc953 3173 msg.body.key_info.attr.wep.index = index;
730a28da 3174 msg.body.key_info.attr.wep.mode = mode;
ff3bce2f 3175 msg.body.key_info.attr.wep.auth_type = auth_type;
ae4dfa57 3176
31390eec 3177 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3178
31390eec 3179 if (result)
c5c77ba1 3180 PRINT_ER("Error in sending message queue :WEP Key\n");
a4ab1ade 3181 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3182
31390eec 3183 return result;
c5c77ba1 3184}
108b3439 3185
a4ab1ade
TC
3186s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
3187 u8 u8PtkKeylen, const u8 *mac_addr,
3188 const u8 *pu8RxMic, const u8 *pu8TxMic,
3189 u8 mode, u8 u8Ciphermode, u8 u8Idx)
c5c77ba1 3190{
31390eec 3191 s32 result = 0;
143eb95a 3192 struct host_if_msg msg;
63d03e47 3193 u8 u8KeyLen = u8PtkKeylen;
4e4467fd 3194 u32 i;
78c87591 3195
a4ab1ade 3196 if (!hif_drv) {
24db713f 3197 PRINT_ER("driver is null\n");
77178807 3198 return -EFAULT;
24db713f 3199 }
91109e11
LK
3200
3201 if (pu8RxMic)
c5c77ba1 3202 u8KeyLen += RX_MIC_KEY_LEN;
91109e11
LK
3203
3204 if (pu8TxMic)
c5c77ba1 3205 u8KeyLen += TX_MIC_KEY_LEN;
c5c77ba1 3206
143eb95a 3207 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3208
a9f812a6 3209 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3210 msg.body.key_info.type = WPAPtk;
c5c77ba1 3211 if (mode == AP_MODE) {
0d17e382 3212 msg.body.key_info.action = ADDKEY_AP;
e2dfbac5 3213 msg.body.key_info.attr.wpa.index = u8Idx;
c5c77ba1 3214 }
c5c77ba1 3215 if (mode == STATION_MODE)
0d17e382 3216 msg.body.key_info.action = ADDKEY;
c5c77ba1 3217
124968fc
LK
3218 msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
3219 memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
c5c77ba1 3220
91109e11 3221 if (pu8RxMic) {
124968fc 3222 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
c5c77ba1
JK
3223 if (INFO) {
3224 for (i = 0; i < RX_MIC_KEY_LEN; i++)
3225 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
3226 }
3227 }
91109e11 3228 if (pu8TxMic) {
124968fc 3229 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
c5c77ba1
JK
3230 if (INFO) {
3231 for (i = 0; i < TX_MIC_KEY_LEN; i++)
3232 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
3233 }
3234 }
3235
6acf2919 3236 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
248080aa 3237 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
7b2ebb28 3238 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
a4ab1ade 3239 msg.drv = hif_drv;
c5c77ba1 3240
31390eec 3241 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3242
31390eec 3243 if (result)
c5c77ba1
JK
3244 PRINT_ER("Error in sending message queue: PTK Key\n");
3245
a4ab1ade 3246 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3247
31390eec 3248 return result;
c5c77ba1
JK
3249}
3250
a4ab1ade
TC
3251s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
3252 u8 u8GtkKeylen, u8 u8KeyIdx,
3253 u32 u32KeyRSClen, const u8 *KeyRSC,
3254 const u8 *pu8RxMic, const u8 *pu8TxMic,
3255 u8 mode, u8 u8Ciphermode)
c5c77ba1 3256{
31390eec 3257 s32 result = 0;
143eb95a 3258 struct host_if_msg msg;
63d03e47 3259 u8 u8KeyLen = u8GtkKeylen;
c5c77ba1 3260
a4ab1ade 3261 if (!hif_drv) {
24db713f 3262 PRINT_ER("driver is null\n");
77178807 3263 return -EFAULT;
24db713f 3264 }
143eb95a 3265 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3266
91109e11 3267 if (pu8RxMic)
c5c77ba1 3268 u8KeyLen += RX_MIC_KEY_LEN;
91109e11
LK
3269
3270 if (pu8TxMic)
c5c77ba1 3271 u8KeyLen += TX_MIC_KEY_LEN;
91109e11
LK
3272
3273 if (KeyRSC) {
0e74c009
LK
3274 msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
3275 memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
c5c77ba1
JK
3276 }
3277
a9f812a6 3278 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3279 msg.body.key_info.type = WPARxGtk;
a4ab1ade 3280 msg.drv = hif_drv;
c5c77ba1 3281
c5c77ba1 3282 if (mode == AP_MODE) {
0d17e382 3283 msg.body.key_info.action = ADDKEY_AP;
7b2ebb28 3284 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
c5c77ba1 3285 }
c5c77ba1 3286 if (mode == STATION_MODE)
0d17e382 3287 msg.body.key_info.action = ADDKEY;
c5c77ba1 3288
124968fc
LK
3289 msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
3290 memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
c5c77ba1 3291
d1666e2a
LK
3292 if (pu8RxMic)
3293 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic,
3294 RX_MIC_KEY_LEN);
91109e11 3295
d1666e2a
LK
3296 if (pu8TxMic)
3297 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic,
3298 TX_MIC_KEY_LEN);
c5c77ba1 3299
e2dfbac5 3300 msg.body.key_info.attr.wpa.index = u8KeyIdx;
6acf2919 3301 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
dacc594d 3302 msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
c5c77ba1 3303
31390eec
LK
3304 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3305 if (result)
c5c77ba1 3306 PRINT_ER("Error in sending message queue: RX GTK\n");
ae4dfa57 3307
a4ab1ade 3308 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3309
31390eec 3310 return result;
c5c77ba1 3311}
c5c77ba1 3312
a4ab1ade 3313s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
c5c77ba1 3314{
31390eec 3315 s32 result = 0;
143eb95a 3316 struct host_if_msg msg;
4e4467fd 3317 u32 i;
c5c77ba1 3318
a4ab1ade 3319 if (!hif_drv) {
24db713f 3320 PRINT_ER("driver is null\n");
77178807 3321 return -EFAULT;
24db713f 3322 }
c5c77ba1 3323
143eb95a 3324 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3325
a9f812a6 3326 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3327 msg.body.key_info.type = PMKSA;
0d17e382 3328 msg.body.key_info.action = ADDKEY;
a4ab1ade 3329 msg.drv = hif_drv;
c5c77ba1
JK
3330
3331 for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
8c8360b3
LK
3332 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3333 &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN);
3334 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3335 &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN);
c5c77ba1
JK
3336 }
3337
31390eec
LK
3338 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3339 if (result)
c5c77ba1
JK
3340 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3341
31390eec 3342 return result;
c5c77ba1
JK
3343}
3344
a4ab1ade
TC
3345s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
3346 u8 *pu8PmkidInfoArray,
3347 u32 u32PmkidInfoLen)
c5c77ba1 3348{
45102f83 3349 struct wid wid;
c5c77ba1 3350
45102f83
LK
3351 wid.id = (u16)WID_PMKID_INFO;
3352 wid.type = WID_STR;
3353 wid.size = u32PmkidInfoLen;
3354 wid.val = pu8PmkidInfoArray;
c5c77ba1 3355
b68d820b 3356 return 0;
c5c77ba1
JK
3357}
3358
a4ab1ade
TC
3359s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3360 u8 *pu8PassPhrase,
3361 u8 u8Psklength)
c5c77ba1 3362{
45102f83 3363 struct wid wid;
c5c77ba1 3364
c5c77ba1 3365 if ((u8Psklength > 7) && (u8Psklength < 65)) {
45102f83
LK
3366 wid.id = (u16)WID_11I_PSK;
3367 wid.type = WID_STR;
3368 wid.val = pu8PassPhrase;
3369 wid.size = u8Psklength;
c5c77ba1
JK
3370 }
3371
b68d820b 3372 return 0;
c5c77ba1 3373}
ae4dfa57 3374
a4ab1ade 3375s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3376{
31390eec 3377 s32 result = 0;
143eb95a 3378 struct host_if_msg msg;
c5c77ba1 3379
143eb95a 3380 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3381
a9f812a6 3382 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
6ceba0af 3383 msg.body.get_mac_info.mac_addr = pu8MacAddress;
a4ab1ade 3384 msg.drv = hif_drv;
ae4dfa57 3385
31390eec
LK
3386 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3387 if (result) {
c5c77ba1 3388 PRINT_ER("Failed to send get mac address\n");
e6e12661 3389 return -EFAULT;
c5c77ba1
JK
3390 }
3391
2d25af87 3392 down(&hif_sema_wait_response);
31390eec 3393 return result;
c5c77ba1
JK
3394}
3395
a4ab1ade 3396s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3397{
31390eec 3398 s32 result = 0;
143eb95a 3399 struct host_if_msg msg;
c5c77ba1
JK
3400
3401 PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
3402
143eb95a 3403 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3404 msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
ae5e4522 3405 memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN);
a4ab1ade 3406 msg.drv = hif_drv;
c5c77ba1 3407
31390eec
LK
3408 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3409 if (result)
c5c77ba1 3410 PRINT_ER("Failed to send message queue: Set mac address\n");
c5c77ba1 3411
31390eec 3412 return result;
c5c77ba1
JK
3413}
3414
a4ab1ade
TC
3415s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3416 u8 *pu8PassPhrase, u8 u8Psklength)
c5c77ba1 3417{
45102f83 3418 struct wid wid;
c5c77ba1 3419
45102f83
LK
3420 wid.id = (u16)WID_11I_PSK;
3421 wid.type = WID_STR;
3422 wid.size = u8Psklength;
3423 wid.val = pu8PassPhrase;
c5c77ba1 3424
b68d820b 3425 return 0;
c5c77ba1
JK
3426}
3427
a4ab1ade 3428s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
c5c77ba1 3429{
45102f83 3430 struct wid wid;
c5c77ba1 3431
45102f83
LK
3432 wid.id = (u16)WID_START_SCAN_REQ;
3433 wid.type = WID_CHAR;
3434 wid.val = (s8 *)&scanSource;
3435 wid.size = sizeof(char);
c5c77ba1 3436
b68d820b 3437 return 0;
c5c77ba1
JK
3438}
3439
a4ab1ade 3440s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
c5c77ba1 3441{
45102f83 3442 struct wid wid;
c5c77ba1 3443
45102f83
LK
3444 wid.id = (u16)WID_START_SCAN_REQ;
3445 wid.type = WID_CHAR;
3446 wid.val = (s8 *)pu8ScanSource;
3447 wid.size = sizeof(char);
c5c77ba1 3448
b68d820b 3449 return 0;
c5c77ba1
JK
3450}
3451
a4ab1ade
TC
3452s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
3453 const u8 *pu8ssid, size_t ssidLen,
3454 const u8 *pu8IEs, size_t IEsLen,
3455 wilc_connect_result pfConnectResult, void *pvUserArg,
3456 u8 u8security, enum AUTHTYPE tenuAuth_type,
3457 u8 u8channel, void *pJoinParams)
c5c77ba1 3458{
31390eec 3459 s32 result = 0;
143eb95a 3460 struct host_if_msg msg;
c5c77ba1 3461
91109e11 3462 if (!hif_drv || !pfConnectResult) {
24db713f 3463 PRINT_ER("Driver is null\n");
77178807 3464 return -EFAULT;
24db713f 3465 }
c5c77ba1 3466
91109e11 3467 if (!pJoinParams) {
c5c77ba1 3468 PRINT_ER("Unable to Join - JoinParams is NULL\n");
24db713f 3469 return -EFAULT;
c5c77ba1 3470 }
24db713f 3471
143eb95a 3472 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3473
a9f812a6 3474 msg.id = HOST_IF_MSG_CONNECT;
c5c77ba1 3475
a64fd677 3476 msg.body.con_info.security = u8security;
61b4fd02 3477 msg.body.con_info.auth_type = tenuAuth_type;
0d1527e6 3478 msg.body.con_info.ch = u8channel;
6abcc11d 3479 msg.body.con_info.result = pfConnectResult;
8f38db89 3480 msg.body.con_info.arg = pvUserArg;
f2bed2ca 3481 msg.body.con_info.params = pJoinParams;
a4ab1ade 3482 msg.drv = hif_drv ;
c5c77ba1 3483
91109e11 3484 if (pu8bssid) {
9254db07
LK
3485 msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
3486 memcpy(msg.body.con_info.bssid, pu8bssid, 6);
c5c77ba1
JK
3487 }
3488
91109e11 3489 if (pu8ssid) {
8b3c9fa6 3490 msg.body.con_info.ssid_len = ssidLen;
f7bbd9cf
LK
3491 msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL);
3492 memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen);
c5c77ba1
JK
3493 }
3494
91109e11 3495 if (pu8IEs) {
b59d5c5b 3496 msg.body.con_info.ies_len = IEsLen;
2ea158c4
LK
3497 msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3498 memcpy(msg.body.con_info.ies, pu8IEs, IEsLen);
c5c77ba1 3499 }
a4ab1ade
TC
3500 if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING)
3501 hif_drv->enuHostIFstate = HOST_IF_CONNECTING;
78174ada 3502 else
a4ab1ade 3503 PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate);
c5c77ba1 3504
31390eec
LK
3505 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3506 if (result) {
c5c77ba1 3507 PRINT_ER("Failed to send message queue: Set join request\n");
24db713f 3508 return -EFAULT;
c5c77ba1
JK
3509 }
3510
a4ab1ade
TC
3511 hif_drv->hConnectTimer.data = (unsigned long)hif_drv;
3512 mod_timer(&hif_drv->hConnectTimer,
9eb06643 3513 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
c5c77ba1 3514
31390eec 3515 return result;
c5c77ba1
JK
3516}
3517
a4ab1ade 3518s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
c5c77ba1 3519{
31390eec 3520 s32 result = 0;
143eb95a 3521 struct host_if_msg msg;
c5c77ba1 3522
77178807
LK
3523 if (!join_req)
3524 return -EFAULT;
c5c77ba1 3525
a4ab1ade 3526 if (!hif_drv) {
24db713f 3527 PRINT_ER("Driver is null\n");
77178807 3528 return -EFAULT;
24db713f 3529 }
c5c77ba1 3530
a9f812a6 3531 msg.id = HOST_IF_MSG_FLUSH_CONNECT;
a4ab1ade 3532 msg.drv = hif_drv;
c5c77ba1 3533
31390eec
LK
3534 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3535 if (result) {
c5c77ba1 3536 PRINT_ER("Failed to send message queue: Flush join request\n");
24db713f 3537 return -EFAULT;
c5c77ba1
JK
3538 }
3539
31390eec 3540 return result;
c5c77ba1
JK
3541}
3542
a4ab1ade 3543s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
c5c77ba1 3544{
31390eec 3545 s32 result = 0;
143eb95a 3546 struct host_if_msg msg;
c5c77ba1 3547
a4ab1ade 3548 if (!hif_drv) {
24db713f
LK
3549 PRINT_ER("Driver is null\n");
3550 return -EFAULT;
c5c77ba1
JK
3551 }
3552
143eb95a 3553 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3554
a9f812a6 3555 msg.id = HOST_IF_MSG_DISCONNECT;
a4ab1ade 3556 msg.drv = hif_drv;
c5c77ba1 3557
31390eec
LK
3558 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3559 if (result)
c5c77ba1 3560 PRINT_ER("Failed to send message queue: disconnect\n");
ae4dfa57 3561
a4ab1ade 3562 down(&hif_drv->hSemTestDisconnectBlock);
c5c77ba1 3563
31390eec 3564 return result;
c5c77ba1
JK
3565}
3566
a4ab1ade 3567s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
c5c77ba1 3568{
45102f83 3569 struct wid wid;
c5c77ba1 3570
45102f83
LK
3571 wid.id = (u16)WID_DISCONNECT;
3572 wid.type = WID_CHAR;
3573 wid.val = (s8 *)&assoc_id;
3574 wid.size = sizeof(char);
c5c77ba1 3575
b68d820b 3576 return 0;
c5c77ba1
JK
3577}
3578
8c8360b3
LK
3579s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
3580 u8 *pu8AssocReqInfo,
3581 u32 u32AssocReqInfoLen)
c5c77ba1 3582{
45102f83 3583 struct wid wid;
c5c77ba1 3584
45102f83
LK
3585 wid.id = (u16)WID_ASSOC_REQ_INFO;
3586 wid.type = WID_STR;
3587 wid.val = pu8AssocReqInfo;
3588 wid.size = u32AssocReqInfoLen;
c5c77ba1 3589
b68d820b 3590 return 0;
c5c77ba1
JK
3591}
3592
8c8360b3
LK
3593s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
3594 u8 *pu8AssocRespInfo,
3595 u32 u32MaxAssocRespInfoLen,
3596 u32 *pu32RcvdAssocRespInfoLen)
c5c77ba1 3597{
31390eec 3598 s32 result = 0;
45102f83 3599 struct wid wid;
c5c77ba1 3600
a4ab1ade 3601 if (!hif_drv) {
24db713f
LK
3602 PRINT_ER("Driver is null\n");
3603 return -EFAULT;
c5c77ba1
JK
3604 }
3605
45102f83
LK
3606 wid.id = (u16)WID_ASSOC_RES_INFO;
3607 wid.type = WID_STR;
3608 wid.val = pu8AssocRespInfo;
3609 wid.size = u32MaxAssocRespInfoLen;
c5c77ba1 3610
45102f83 3611 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 3612 get_id_from_handler(hif_drv));
31390eec 3613 if (result) {
c5c77ba1 3614 *pu32RcvdAssocRespInfoLen = 0;
24db713f
LK
3615 PRINT_ER("Failed to send association response config packet\n");
3616 return -EINVAL;
c5c77ba1 3617 } else {
45102f83 3618 *pu32RcvdAssocRespInfoLen = wid.size;
c5c77ba1
JK
3619 }
3620
31390eec 3621 return result;
c5c77ba1
JK
3622}
3623
8c8360b3
LK
3624s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
3625 u8 *pu8RxPowerLevel,
3626 u32 u32RxPowerLevelLen)
c5c77ba1 3627{
45102f83 3628 struct wid wid;
c5c77ba1 3629
45102f83
LK
3630 wid.id = (u16)WID_RX_POWER_LEVEL;
3631 wid.type = WID_STR;
3632 wid.val = pu8RxPowerLevel;
3633 wid.size = u32RxPowerLevelLen;
c5c77ba1 3634
b68d820b 3635 return 0;
c5c77ba1
JK
3636}
3637
a4ab1ade 3638int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
c5c77ba1 3639{
792fb25b 3640 int result;
143eb95a 3641 struct host_if_msg msg;
c5c77ba1 3642
a4ab1ade 3643 if (!hif_drv) {
24db713f
LK
3644 PRINT_ER("driver is null\n");
3645 return -EFAULT;
3646 }
c5c77ba1 3647
143eb95a 3648 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3649 msg.id = HOST_IF_MSG_SET_CHANNEL;
730ee059 3650 msg.body.channel_info.set_ch = channel;
a4ab1ade 3651 msg.drv = hif_drv;
c5c77ba1 3652
cb067dcf 3653 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
1ef58e42 3654 if (result) {
24db713f 3655 PRINT_ER("wilc mq send fail\n");
792fb25b 3656 return -EINVAL;
c5c77ba1
JK
3657 }
3658
792fb25b 3659 return 0;
c5c77ba1
JK
3660}
3661
244efb1f 3662int host_int_wait_msg_queue_idle(void)
c5c77ba1 3663{
6d6c9bbb 3664 int result = 0;
143eb95a 3665 struct host_if_msg msg;
c09389ac 3666
143eb95a 3667 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3668 msg.id = HOST_IF_MSG_Q_IDLE;
cb067dcf 3669 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
6d6c9bbb 3670 if (result) {
24db713f 3671 PRINT_ER("wilc mq send fail\n");
6d6c9bbb 3672 result = -EINVAL;
c5c77ba1
JK
3673 }
3674
2d25af87 3675 down(&hif_sema_wait_response);
c5c77ba1 3676
6d6c9bbb 3677 return result;
c5c77ba1
JK
3678}
3679
a4ab1ade 3680int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
c5c77ba1 3681{
a094101c 3682 int result = 0;
143eb95a 3683 struct host_if_msg msg;
c09389ac 3684
143eb95a 3685 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3686 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
a7f3b12f 3687 msg.body.drv.handler = get_id_from_handler(hif_drv);
a4ab1ade 3688 msg.drv = hif_drv;
c5c77ba1 3689
cb067dcf 3690 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a094101c 3691 if (result) {
24db713f 3692 PRINT_ER("wilc mq send fail\n");
a094101c 3693 result = -EINVAL;
c5c77ba1
JK
3694 }
3695
a094101c 3696 return result;
c5c77ba1
JK
3697}
3698
a4ab1ade 3699int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
c5c77ba1 3700{
a0c1ee0c 3701 int result = 0;
143eb95a 3702 struct host_if_msg msg;
c09389ac 3703
143eb95a 3704 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3705 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
c96debf1 3706 msg.body.mode.mode = mode;
a4ab1ade 3707 msg.drv = hif_drv;
c5c77ba1 3708
cb067dcf 3709 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a0c1ee0c 3710 if (result) {
24db713f 3711 PRINT_ER("wilc mq send fail\n");
a0c1ee0c 3712 result = -EINVAL;
c5c77ba1
JK
3713 }
3714
a0c1ee0c 3715 return result;
c5c77ba1
JK
3716}
3717
a4ab1ade 3718s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
c5c77ba1 3719{
31390eec 3720 s32 result = 0;
143eb95a 3721 struct host_if_msg msg;
c5c77ba1 3722
a4ab1ade 3723 if (!hif_drv) {
24db713f
LK
3724 PRINT_ER("driver is null\n");
3725 return -EFAULT;
c5c77ba1
JK
3726 }
3727
143eb95a 3728 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3729
a9f812a6 3730 msg.id = HOST_IF_MSG_GET_CHNL;
a4ab1ade 3731 msg.drv = hif_drv;
c5c77ba1 3732
31390eec
LK
3733 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3734 if (result)
24db713f 3735 PRINT_ER("wilc mq send fail\n");
a4ab1ade 3736 down(&hif_drv->hSemGetCHNL);
c5c77ba1 3737
95ebb0ff 3738 *pu8ChNo = ch_no;
c5c77ba1 3739
31390eec 3740 return result;
c5c77ba1
JK
3741}
3742
a4ab1ade
TC
3743s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
3744 const u8 *mac, u32 *pu32InactiveTime)
c5c77ba1 3745{
31390eec 3746 s32 result = 0;
143eb95a 3747 struct host_if_msg msg;
c5c77ba1 3748
a4ab1ade 3749 if (!hif_drv) {
24db713f
LK
3750 PRINT_ER("driver is null\n");
3751 return -EFAULT;
c5c77ba1
JK
3752 }
3753
143eb95a 3754 memset(&msg, 0, sizeof(struct host_if_msg));
8c8360b3 3755 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
c5c77ba1 3756
a9f812a6 3757 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
a4ab1ade 3758 msg.drv = hif_drv;
c5c77ba1 3759
31390eec
LK
3760 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3761 if (result)
c5c77ba1
JK
3762 PRINT_ER("Failed to send get host channel param's message queue ");
3763
a4ab1ade 3764 down(&hif_drv->hSemInactiveTime);
c5c77ba1 3765
ad26906f 3766 *pu32InactiveTime = inactive_time;
c5c77ba1 3767
31390eec 3768 return result;
c5c77ba1 3769}
108b3439 3770
a4ab1ade 3771s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
c5c77ba1 3772{
31390eec 3773 s32 result = 0;
45102f83 3774 struct wid wid;
c5c77ba1 3775
a4ab1ade 3776 if (!hif_drv) {
24db713f
LK
3777 PRINT_ER("driver is null\n");
3778 return -EFAULT;
c5c77ba1
JK
3779 }
3780
45102f83
LK
3781 wid.id = (u16)WID_MEMORY_ADDRESS;
3782 wid.type = WID_INT;
3783 wid.val = (s8 *)pu32TestMemAddr;
3784 wid.size = sizeof(u32);
c5c77ba1 3785
45102f83 3786 result = send_config_pkt(GET_CFG, &wid, 1,
8c8360b3 3787 get_id_from_handler(hif_drv));
ae4dfa57 3788
31390eec 3789 if (result) {
24db713f
LK
3790 PRINT_ER("Failed to get wid value\n");
3791 return -EINVAL;
c5c77ba1
JK
3792 } else {
3793 PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
c5c77ba1
JK
3794 }
3795
31390eec 3796 return result;
c5c77ba1
JK
3797}
3798
a4ab1ade 3799s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
c5c77ba1 3800{
31390eec 3801 s32 result = 0;
143eb95a 3802 struct host_if_msg msg;
c5c77ba1 3803
c09389ac 3804 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3805 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 3806 msg.drv = hif_drv;
c5c77ba1 3807
31390eec
LK
3808 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3809 if (result) {
c5c77ba1 3810 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3811 return -EFAULT;
c5c77ba1
JK
3812 }
3813
a4ab1ade 3814 down(&hif_drv->hSemGetRSSI);
c5c77ba1 3815
91109e11 3816 if (!ps8Rssi) {
c5c77ba1 3817 PRINT_ER("RSS pointer value is null");
e6e12661 3818 return -EFAULT;
c5c77ba1
JK
3819 }
3820
144b7b23 3821 *ps8Rssi = rssi;
c5c77ba1 3822
31390eec 3823 return result;
c5c77ba1
JK
3824}
3825
a4ab1ade 3826s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
c5c77ba1 3827{
143eb95a 3828 struct host_if_msg msg;
31390eec 3829 s32 result = 0;
c5c77ba1 3830
c09389ac 3831 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3832 msg.id = HOST_IF_MSG_GET_LINKSPEED;
a4ab1ade 3833 msg.drv = hif_drv;
c5c77ba1 3834
31390eec
LK
3835 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3836 if (result) {
c5c77ba1 3837 PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
e6e12661 3838 return -EFAULT;
c5c77ba1
JK
3839 }
3840
a4ab1ade 3841 down(&hif_drv->hSemGetLINKSPEED);
c5c77ba1 3842
91109e11 3843 if (!ps8lnkspd) {
c5c77ba1 3844 PRINT_ER("LINKSPEED pointer value is null");
e6e12661 3845 return -EFAULT;
c5c77ba1
JK
3846 }
3847
75327a02 3848 *ps8lnkspd = link_speed;
c5c77ba1 3849
31390eec 3850 return result;
c5c77ba1
JK
3851}
3852
a4ab1ade 3853s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
c5c77ba1 3854{
31390eec 3855 s32 result = 0;
143eb95a 3856 struct host_if_msg msg;
c5c77ba1 3857
c09389ac 3858 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3859 msg.id = HOST_IF_MSG_GET_STATISTICS;
e60831e9 3860 msg.body.data = (char *)pstrStatistics;
a4ab1ade 3861 msg.drv = hif_drv;
ae4dfa57 3862
31390eec
LK
3863 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3864 if (result) {
c5c77ba1 3865 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3866 return -EFAULT;
c5c77ba1
JK
3867 }
3868
2d25af87 3869 down(&hif_sema_wait_response);
31390eec 3870 return result;
c5c77ba1
JK
3871}
3872
a4ab1ade
TC
3873s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
3874 u8 u8ScanType, u8 *pu8ChnlFreqList,
3875 u8 u8ChnlListLen, const u8 *pu8IEs,
3876 size_t IEsLen, wilc_scan_result ScanResult,
3877 void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
c5c77ba1 3878{
31390eec 3879 s32 result = 0;
143eb95a 3880 struct host_if_msg msg;
c5c77ba1 3881
91109e11 3882 if (!hif_drv || !ScanResult) {
a4ab1ade 3883 PRINT_ER("hif_drv or ScanResult = NULL\n");
24db713f
LK
3884 return -EFAULT;
3885 }
c5c77ba1 3886
143eb95a 3887 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3888
a9f812a6 3889 msg.id = HOST_IF_MSG_SCAN;
c5c77ba1 3890
91109e11 3891 if (pstrHiddenNetwork) {
629b9ca0
LK
3892 msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
3893 msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
c5c77ba1
JK
3894
3895 } else
3896 PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
3897
a4ab1ade 3898 msg.drv = hif_drv;
42568898 3899 msg.body.scan_info.src = u8ScanSource;
1e276c88 3900 msg.body.scan_info.type = u8ScanType;
c17c6da6 3901 msg.body.scan_info.result = ScanResult;
5f2b50c8 3902 msg.body.scan_info.arg = pvUserArg;
4528bdb5 3903
f97bd9ca 3904 msg.body.scan_info.ch_list_len = u8ChnlListLen;
82eeb0ad
LK
3905 msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL);
3906 memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen);
c5c77ba1 3907
7b1f76cd 3908 msg.body.scan_info.ies_len = IEsLen;
d6f19aa5
LK
3909 msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3910 memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen);
c5c77ba1 3911
31390eec
LK
3912 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3913 if (result) {
24db713f
LK
3914 PRINT_ER("Error in sending message queue\n");
3915 return -EINVAL;
c5c77ba1
JK
3916 }
3917
c5c77ba1 3918 PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
a4ab1ade
TC
3919 hif_drv->hScanTimer.data = (unsigned long)hif_drv;
3920 mod_timer(&hif_drv->hScanTimer,
9eb06643 3921 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
c5c77ba1 3922
31390eec 3923 return result;
c5c77ba1 3924}
ae4dfa57 3925
a4ab1ade
TC
3926s32 hif_set_cfg(struct host_if_drv *hif_drv,
3927 struct cfg_param_val *pstrCfgParamVal)
c5c77ba1 3928{
31390eec 3929 s32 result = 0;
143eb95a 3930 struct host_if_msg msg;
c5c77ba1 3931
a4ab1ade
TC
3932 if (!hif_drv) {
3933 PRINT_ER("hif_drv NULL\n");
24db713f
LK
3934 return -EFAULT;
3935 }
ae4dfa57 3936
143eb95a 3937 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3938 msg.id = HOST_IF_MSG_CFG_PARAMS;
221371e5 3939 msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
a4ab1ade 3940 msg.drv = hif_drv;
c5c77ba1 3941
31390eec 3942 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3943
31390eec 3944 return result;
c5c77ba1
JK
3945}
3946
a4ab1ade 3947s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
c5c77ba1 3948{
31390eec 3949 s32 result = 0;
c5c77ba1 3950
a4ab1ade 3951 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 3952
a4ab1ade
TC
3953 if (!hif_drv) {
3954 PRINT_ER("hif_drv NULL\n");
24db713f 3955 return -EFAULT;
c5c77ba1
JK
3956 }
3957 PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
3958 switch (u16WID) {
c5c77ba1 3959 case WID_BSS_TYPE:
a4ab1ade 3960 *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type;
c5c77ba1
JK
3961 break;
3962
3963 case WID_AUTH_TYPE:
a4ab1ade 3964 *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type;
c5c77ba1
JK
3965 break;
3966
3967 case WID_AUTH_TIMEOUT:
a4ab1ade 3968 *pu16WID_Value = hif_drv->strCfgValues.auth_timeout;
c5c77ba1
JK
3969 break;
3970
3971 case WID_POWER_MANAGEMENT:
a4ab1ade 3972 *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode;
c5c77ba1
JK
3973 break;
3974
3975 case WID_SHORT_RETRY_LIMIT:
a4ab1ade 3976 *pu16WID_Value = hif_drv->strCfgValues.short_retry_limit;
c5c77ba1
JK
3977 break;
3978
3979 case WID_LONG_RETRY_LIMIT:
a4ab1ade 3980 *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit;
c5c77ba1
JK
3981 break;
3982
3983 case WID_FRAG_THRESHOLD:
a4ab1ade 3984 *pu16WID_Value = hif_drv->strCfgValues.frag_threshold;
c5c77ba1
JK
3985 break;
3986
3987 case WID_RTS_THRESHOLD:
a4ab1ade 3988 *pu16WID_Value = hif_drv->strCfgValues.rts_threshold;
c5c77ba1
JK
3989 break;
3990
3991 case WID_PREAMBLE:
a4ab1ade 3992 *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type;
c5c77ba1
JK
3993 break;
3994
3995 case WID_SHORT_SLOT_ALLOWED:
a4ab1ade 3996 *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed;
c5c77ba1
JK
3997 break;
3998
3999 case WID_11N_TXOP_PROT_DISABLE:
a4ab1ade 4000 *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled;
c5c77ba1
JK
4001 break;
4002
4003 case WID_BEACON_INTERVAL:
a4ab1ade 4004 *pu16WID_Value = hif_drv->strCfgValues.beacon_interval;
c5c77ba1
JK
4005 break;
4006
4007 case WID_DTIM_PERIOD:
a4ab1ade 4008 *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period;
c5c77ba1
JK
4009 break;
4010
4011 case WID_SITE_SURVEY:
a4ab1ade 4012 *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled;
c5c77ba1
JK
4013 break;
4014
4015 case WID_SITE_SURVEY_SCAN_TIME:
a4ab1ade 4016 *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time;
c5c77ba1
JK
4017 break;
4018
4019 case WID_ACTIVE_SCAN_TIME:
a4ab1ade 4020 *pu16WID_Value = hif_drv->strCfgValues.active_scan_time;
c5c77ba1
JK
4021 break;
4022
4023 case WID_PASSIVE_SCAN_TIME:
a4ab1ade 4024 *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time;
c5c77ba1
JK
4025 break;
4026
4027 case WID_CURRENT_TX_RATE:
a4ab1ade 4028 *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate;
c5c77ba1
JK
4029 break;
4030
4031 default:
4032 break;
4033 }
4034
a4ab1ade 4035 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4036
31390eec 4037 return result;
c5c77ba1
JK
4038}
4039
93dee8ee 4040static void GetPeriodicRSSI(unsigned long arg)
c5c77ba1 4041{
a4ab1ade 4042 struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
78c87591 4043
a4ab1ade 4044 if (!hif_drv) {
c5c77ba1
JK
4045 PRINT_ER("Driver handler is NULL\n");
4046 return;
4047 }
4048
a4ab1ade 4049 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) {
31390eec 4050 s32 result = 0;
143eb95a 4051 struct host_if_msg msg;
c5c77ba1 4052
143eb95a 4053 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4054
a9f812a6 4055 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 4056 msg.drv = hif_drv;
c5c77ba1 4057
31390eec
LK
4058 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4059 if (result) {
c5c77ba1
JK
4060 PRINT_ER("Failed to send get host channel param's message queue ");
4061 return;
4062 }
4063 }
262f55e1
LK
4064 periodic_rssi.data = (unsigned long)hif_drv;
4065 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4066}
4067
d5382219 4068s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
c5c77ba1 4069{
5b09bd32 4070 s32 result = 0;
a4ab1ade 4071 struct host_if_drv *hif_drv;
d42ab083 4072 int err;
d5382219
GL
4073 perInterface_wlan_t *nic;
4074 struct wilc *wilc;
4075
4076 nic = netdev_priv(dev);
4077 wilc = nic->wilc;
c5c77ba1 4078
c5c77ba1
JK
4079 PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
4080
ca8540e4 4081 scan_while_connected = false;
c5c77ba1 4082
2d25af87 4083 sema_init(&hif_sema_wait_response, 0);
c5c77ba1 4084
a4ab1ade
TC
4085 hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
4086 if (!hif_drv) {
5b09bd32 4087 result = -ENOMEM;
17db84eb 4088 goto _fail_;
c5c77ba1 4089 }
a4ab1ade
TC
4090 *hif_drv_handler = hif_drv;
4091 err = add_handler_in_list(hif_drv);
d42ab083 4092 if (err) {
5b09bd32 4093 result = -EFAULT;
d42ab083
JK
4094 goto _fail_timer_2;
4095 }
c5c77ba1 4096
72ed4dc7 4097 g_obtainingIP = false;
c5c77ba1 4098
a4ab1ade 4099 PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
c5c77ba1 4100 if (clients_count == 0) {
834e0cb0 4101 sema_init(&hif_sema_thread, 0);
27ff2168 4102 sema_init(&hif_sema_driver, 0);
440e8993 4103 sema_init(&hif_sema_deinit, 1);
83383ea3
AB
4104 }
4105
a4ab1ade
TC
4106 sema_init(&hif_drv->hSemTestKeyBlock, 0);
4107 sema_init(&hif_drv->hSemTestDisconnectBlock, 0);
4108 sema_init(&hif_drv->hSemGetRSSI, 0);
4109 sema_init(&hif_drv->hSemGetLINKSPEED, 0);
4110 sema_init(&hif_drv->hSemGetCHNL, 0);
4111 sema_init(&hif_drv->hSemInactiveTime, 0);
c5c77ba1 4112
c5c77ba1
JK
4113 PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
4114
4115 if (clients_count == 0) {
cb067dcf 4116 result = wilc_mq_create(&hif_msg_q);
c5c77ba1 4117
5b09bd32 4118 if (result < 0) {
c5c77ba1
JK
4119 PRINT_ER("Failed to creat MQ\n");
4120 goto _fail_;
4121 }
c2115d8e 4122
d5382219
GL
4123 hif_thread_handler = kthread_run(hostIFthread, wilc,
4124 "WILC_kthread");
c2115d8e
LK
4125
4126 if (IS_ERR(hif_thread_handler)) {
c5c77ba1 4127 PRINT_ER("Failed to creat Thread\n");
5b09bd32 4128 result = -EFAULT;
c5c77ba1
JK
4129 goto _fail_mq_;
4130 }
262f55e1 4131 setup_timer(&periodic_rssi, GetPeriodicRSSI,
a4ab1ade 4132 (unsigned long)hif_drv);
262f55e1 4133 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4134 }
4135
a4ab1ade 4136 setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0);
c5c77ba1 4137
a4ab1ade 4138 setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0);
c5c77ba1 4139
a4ab1ade 4140 setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0);
c5c77ba1 4141
bafaa696 4142 sema_init(&hif_drv->gtOsCfgValuesSem, 1);
a4ab1ade 4143 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4144
a4ab1ade 4145 hif_drv->enuHostIFstate = HOST_IF_IDLE;
a4ab1ade
TC
4146 hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
4147 hif_drv->strCfgValues.scan_source = DEFAULT_SCAN;
4148 hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
4149 hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
4150 hif_drv->strCfgValues.curr_tx_rate = AUTORATE;
c5c77ba1 4151
a4ab1ade 4152 hif_drv->u64P2p_MgmtTimeout = 0;
c5c77ba1 4153
c5c77ba1
JK
4154 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",
4155
a4ab1ade
TC
4156 hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source,
4157 hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time,
4158 hif_drv->strCfgValues.curr_tx_rate);
c5c77ba1 4159
a4ab1ade 4160 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4161
ae4dfa57 4162 clients_count++;
c5c77ba1 4163
5b09bd32 4164 return result;
c5c77ba1 4165
c5c77ba1 4166_fail_timer_2:
a4ab1ade
TC
4167 up(&hif_drv->gtOsCfgValuesSem);
4168 del_timer_sync(&hif_drv->hConnectTimer);
4169 del_timer_sync(&hif_drv->hScanTimer);
c2115d8e 4170 kthread_stop(hif_thread_handler);
c5c77ba1 4171_fail_mq_:
cb067dcf 4172 wilc_mq_destroy(&hif_msg_q);
c5c77ba1 4173_fail_:
5b09bd32 4174 return result;
c5c77ba1 4175}
c5c77ba1 4176
a4ab1ade 4177s32 host_int_deinit(struct host_if_drv *hif_drv)
c5c77ba1 4178{
31390eec 4179 s32 result = 0;
143eb95a 4180 struct host_if_msg msg;
d42ab083 4181 int ret;
c5c77ba1 4182
a4ab1ade
TC
4183 if (!hif_drv) {
4184 PRINT_ER("hif_drv = NULL\n");
c5c77ba1
JK
4185 return 0;
4186 }
4187
440e8993 4188 down(&hif_sema_deinit);
c5c77ba1 4189
a4ab1ade 4190 terminated_handle = hif_drv;
c5c77ba1
JK
4191 PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
4192
d1666e2a 4193 if (del_timer_sync(&hif_drv->hScanTimer))
03b2d5e7 4194 PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
c5c77ba1 4195
d1666e2a 4196 if (del_timer_sync(&hif_drv->hConnectTimer))
03b2d5e7 4197 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1 4198
262f55e1 4199 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4200 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1 4201
a4ab1ade 4202 del_timer_sync(&hif_drv->hRemainOnChannel);
c5c77ba1 4203
218dc407 4204 host_int_set_wfi_drv_handler(NULL);
27ff2168 4205 down(&hif_sema_driver);
c5c77ba1 4206
70793b2a
LK
4207 if (hif_drv->usr_scan_req.pfUserScanResult) {
4208 hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
4209 hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
c5c77ba1 4210
70793b2a 4211 hif_drv->usr_scan_req.pfUserScanResult = NULL;
c5c77ba1 4212 }
c5c77ba1 4213
a4ab1ade 4214 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 4215
ca8540e4 4216 scan_while_connected = false;
c5c77ba1 4217
143eb95a 4218 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4219
4220 if (clients_count == 1) {
262f55e1 4221 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4222 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
262f55e1 4223
a9f812a6 4224 msg.id = HOST_IF_MSG_EXIT;
a4ab1ade 4225 msg.drv = hif_drv;
c5c77ba1 4226
31390eec
LK
4227 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4228 if (result != 0)
4229 PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
c5c77ba1 4230
834e0cb0 4231 down(&hif_sema_thread);
c5c77ba1 4232
cb067dcf 4233 wilc_mq_destroy(&hif_msg_q);
c5c77ba1
JK
4234 }
4235
bafaa696 4236 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4237
a4ab1ade 4238 ret = remove_handler_in_list(hif_drv);
d42ab083 4239 if (ret)
31390eec 4240 result = -ENOENT;
d42ab083 4241
a4ab1ade 4242 kfree(hif_drv);
c5c77ba1 4243
ae4dfa57 4244 clients_count--;
b1413b60 4245 terminated_handle = NULL;
440e8993 4246 up(&hif_sema_deinit);
31390eec 4247 return result;
c5c77ba1
JK
4248}
4249
4e4467fd 4250void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4251{
31390eec 4252 s32 result = 0;
143eb95a 4253 struct host_if_msg msg;
d42ab083 4254 int id;
a4ab1ade 4255 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4256
d42ab083 4257 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4258 hif_drv = get_handler_from_id(id);
c5c77ba1 4259
a4ab1ade
TC
4260 if (!hif_drv || hif_drv == terminated_handle) {
4261 PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
c5c77ba1
JK
4262 return;
4263 }
4264
143eb95a 4265 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4266
a9f812a6 4267 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
a4ab1ade 4268 msg.drv = hif_drv;
c5c77ba1 4269
3bffac68 4270 msg.body.net_info.len = u32Length;
b021b80b
LK
4271 msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4272 memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4273
31390eec
LK
4274 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4275 if (result)
4276 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
c5c77ba1
JK
4277}
4278
4e4467fd 4279void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4280{
31390eec 4281 s32 result = 0;
143eb95a 4282 struct host_if_msg msg;
d42ab083 4283 int id;
a4ab1ade 4284 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4285
440e8993 4286 down(&hif_sema_deinit);
c5c77ba1 4287
d42ab083 4288 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4289 hif_drv = get_handler_from_id(id);
03b2d5e7 4290 PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
c5c77ba1 4291
a4ab1ade 4292 if (!hif_drv || hif_drv == terminated_handle) {
c5c77ba1 4293 PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
440e8993 4294 up(&hif_sema_deinit);
c5c77ba1
JK
4295 return;
4296 }
4297
f8b17132 4298 if (!hif_drv->usr_conn_req.pfUserConnectResult) {
c5c77ba1 4299 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
440e8993 4300 up(&hif_sema_deinit);
c5c77ba1
JK
4301 return;
4302 }
4303
143eb95a 4304 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4305
a9f812a6 4306 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
a4ab1ade 4307 msg.drv = hif_drv;
c5c77ba1 4308
f94f4889 4309 msg.body.async_info.len = u32Length;
33722ac7
LK
4310 msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4311 memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4312
31390eec
LK
4313 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4314 if (result)
4315 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
c5c77ba1 4316
440e8993 4317 up(&hif_sema_deinit);
c5c77ba1
JK
4318}
4319
4e4467fd 4320void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4321{
31390eec 4322 s32 result = 0;
143eb95a 4323 struct host_if_msg msg;
d42ab083 4324 int id;
a4ab1ade 4325 struct host_if_drv *hif_drv = NULL;
78c87591 4326
d42ab083 4327 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4328 hif_drv = get_handler_from_id(id);
c5c77ba1 4329
a4ab1ade 4330 PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
c5c77ba1 4331
a4ab1ade 4332 if (!hif_drv || hif_drv == terminated_handle)
c5c77ba1 4333 return;
c5c77ba1 4334
70793b2a 4335 if (hif_drv->usr_scan_req.pfUserScanResult) {
143eb95a 4336 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4337
a9f812a6 4338 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
a4ab1ade 4339 msg.drv = hif_drv;
c5c77ba1 4340
31390eec
LK
4341 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4342 if (result)
4343 PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
c5c77ba1
JK
4344 }
4345
c5c77ba1 4346 return;
c5c77ba1
JK
4347}
4348
a4ab1ade
TC
4349s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
4350 u32 u32duration, u16 chan,
4351 wilc_remain_on_chan_expired RemainOnChanExpired,
4352 wilc_remain_on_chan_ready RemainOnChanReady,
4353 void *pvUserArg)
c5c77ba1 4354{
31390eec 4355 s32 result = 0;
143eb95a 4356 struct host_if_msg msg;
c5c77ba1 4357
a4ab1ade 4358 if (!hif_drv) {
24db713f
LK
4359 PRINT_ER("driver is null\n");
4360 return -EFAULT;
4361 }
c5c77ba1 4362
143eb95a 4363 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4364
a9f812a6 4365 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
070d365c
TC
4366 msg.body.remain_on_ch.u16Channel = chan;
4367 msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
4368 msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
4369 msg.body.remain_on_ch.pVoid = pvUserArg;
4370 msg.body.remain_on_ch.u32duration = u32duration;
4371 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
a4ab1ade 4372 msg.drv = hif_drv;
143eb95a 4373
31390eec
LK
4374 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4375 if (result)
24db713f 4376 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4377
31390eec 4378 return result;
c5c77ba1
JK
4379}
4380
a4ab1ade 4381s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
c5c77ba1 4382{
31390eec 4383 s32 result = 0;
143eb95a 4384 struct host_if_msg msg;
c5c77ba1 4385
a4ab1ade 4386 if (!hif_drv) {
24db713f
LK
4387 PRINT_ER("driver is null\n");
4388 return -EFAULT;
4389 }
c5c77ba1 4390
a4ab1ade 4391 del_timer(&hif_drv->hRemainOnChannel);
c5c77ba1 4392
143eb95a 4393 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 4394 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
a4ab1ade 4395 msg.drv = hif_drv;
070d365c 4396 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
c5c77ba1 4397
31390eec
LK
4398 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4399 if (result)
24db713f 4400 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4401
31390eec 4402 return result;
c5c77ba1
JK
4403}
4404
a4ab1ade 4405s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
c5c77ba1 4406{
31390eec 4407 s32 result = 0;
143eb95a 4408 struct host_if_msg msg;
c5c77ba1 4409
a4ab1ade 4410 if (!hif_drv) {
24db713f
LK
4411 PRINT_ER("driver is null\n");
4412 return -EFAULT;
4413 }
c5c77ba1 4414
143eb95a 4415 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4416
a9f812a6 4417 msg.id = HOST_IF_MSG_REGISTER_FRAME;
c5c77ba1
JK
4418 switch (u16FrameType) {
4419 case ACTION:
4420 PRINT_D(HOSTINF_DBG, "ACTION\n");
5c4008db 4421 msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
c5c77ba1
JK
4422 break;
4423
4424 case PROBE_REQ:
4425 PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
5c4008db 4426 msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
c5c77ba1
JK
4427 break;
4428
4429 default:
4430 PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
4431 break;
4432 }
5c4008db
TC
4433 msg.body.reg_frame.u16FrameType = u16FrameType;
4434 msg.body.reg_frame.bReg = bReg;
a4ab1ade 4435 msg.drv = hif_drv;
c5c77ba1 4436
31390eec
LK
4437 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4438 if (result)
24db713f 4439 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4440
31390eec 4441 return result;
c5c77ba1 4442}
c5c77ba1 4443
a4ab1ade
TC
4444s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
4445 u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
4446 u32 u32TailLen, u8 *pu8Tail)
c5c77ba1 4447{
31390eec 4448 s32 result = 0;
143eb95a 4449 struct host_if_msg msg;
a98491e5 4450 struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
c5c77ba1 4451
a4ab1ade 4452 if (!hif_drv) {
24db713f
LK
4453 PRINT_ER("driver is null\n");
4454 return -EFAULT;
4455 }
c5c77ba1 4456
143eb95a 4457 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4458
4459 PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
4460
a9f812a6 4461 msg.id = HOST_IF_MSG_ADD_BEACON;
a4ab1ade 4462 msg.drv = hif_drv;
12262dda 4463 pstrSetBeaconParam->interval = u32Interval;
e76ab770 4464 pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
51c66185 4465 pstrSetBeaconParam->head_len = u32HeadLen;
543f5b13 4466 pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL);
91109e11 4467 if (!pstrSetBeaconParam->head) {
31390eec 4468 result = -ENOMEM;
24db713f
LK
4469 goto ERRORHANDLER;
4470 }
030c57e2 4471 pstrSetBeaconParam->tail_len = u32TailLen;
c5c77ba1 4472
c5c77ba1 4473 if (u32TailLen > 0) {
543f5b13
SB
4474 pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen,
4475 GFP_KERNEL);
91109e11 4476 if (!pstrSetBeaconParam->tail) {
31390eec 4477 result = -ENOMEM;
24db713f
LK
4478 goto ERRORHANDLER;
4479 }
c5c77ba1 4480 } else {
7dbcb6d3 4481 pstrSetBeaconParam->tail = NULL;
c5c77ba1
JK
4482 }
4483
31390eec
LK
4484 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4485 if (result)
24db713f 4486 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4487
24db713f 4488ERRORHANDLER:
31390eec 4489 if (result) {
95f840fb 4490 kfree(pstrSetBeaconParam->head);
c5c77ba1 4491
95f840fb 4492 kfree(pstrSetBeaconParam->tail);
c5c77ba1
JK
4493 }
4494
31390eec 4495 return result;
c5c77ba1
JK
4496}
4497
a4ab1ade 4498s32 host_int_del_beacon(struct host_if_drv *hif_drv)
c5c77ba1 4499{
31390eec 4500 s32 result = 0;
143eb95a 4501 struct host_if_msg msg;
c5c77ba1 4502
a4ab1ade 4503 if (!hif_drv) {
24db713f
LK
4504 PRINT_ER("driver is null\n");
4505 return -EFAULT;
4506 }
c5c77ba1 4507
a9f812a6 4508 msg.id = HOST_IF_MSG_DEL_BEACON;
a4ab1ade 4509 msg.drv = hif_drv;
c5c77ba1
JK
4510 PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
4511
31390eec
LK
4512 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4513 if (result)
7dc1d0cc 4514 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4515
31390eec 4516 return result;
c5c77ba1
JK
4517}
4518
a4ab1ade 4519s32 host_int_add_station(struct host_if_drv *hif_drv,
6a89ba9c 4520 struct add_sta_param *pstrStaParams)
c5c77ba1 4521{
31390eec 4522 s32 result = 0;
143eb95a 4523 struct host_if_msg msg;
ca8f47f8 4524 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1 4525
a4ab1ade 4526 if (!hif_drv) {
24db713f
LK
4527 PRINT_ER("driver is null\n");
4528 return -EFAULT;
4529 }
c5c77ba1 4530
143eb95a 4531 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4532
4533 PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
4534
a9f812a6 4535 msg.id = HOST_IF_MSG_ADD_STATION;
a4ab1ade 4536 msg.drv = hif_drv;
c5c77ba1 4537
6a89ba9c 4538 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4539 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4540 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
c09389ac 4541
7ae43363
LK
4542 if (!rates)
4543 return -ENOMEM;
c5c77ba1 4544
d00d2ba3 4545 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4546 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4547 }
4548
31390eec
LK
4549 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4550 if (result)
24db713f 4551 PRINT_ER("wilc_mq_send fail\n");
31390eec 4552 return result;
c5c77ba1
JK
4553}
4554
a4ab1ade 4555s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr)
c5c77ba1 4556{
31390eec 4557 s32 result = 0;
143eb95a 4558 struct host_if_msg msg;
889c25be 4559 struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
c5c77ba1 4560
a4ab1ade 4561 if (!hif_drv) {
24db713f
LK
4562 PRINT_ER("driver is null\n");
4563 return -EFAULT;
4564 }
c5c77ba1 4565
143eb95a 4566 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4567
4568 PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
4569
a9f812a6 4570 msg.id = HOST_IF_MSG_DEL_STATION;
a4ab1ade 4571 msg.drv = hif_drv;
c5c77ba1 4572
91109e11 4573 if (!pu8MacAddr)
0bc85241 4574 eth_broadcast_addr(pstrDelStationMsg->mac_addr);
c5c77ba1 4575 else
e4839d39 4576 memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN);
c5c77ba1 4577
31390eec
LK
4578 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4579 if (result)
24db713f 4580 PRINT_ER("wilc_mq_send fail\n");
31390eec 4581 return result;
c5c77ba1 4582}
ae4dfa57 4583
a4ab1ade 4584s32 host_int_del_allstation(struct host_if_drv *hif_drv,
441dc609 4585 u8 pu8MacAddr[][ETH_ALEN])
c5c77ba1 4586{
31390eec 4587 s32 result = 0;
143eb95a 4588 struct host_if_msg msg;
b0c1e80e 4589 struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
63d03e47 4590 u8 au8Zero_Buff[ETH_ALEN] = {0};
4e4467fd 4591 u32 i;
63d03e47 4592 u8 u8AssocNumb = 0;
c5c77ba1 4593
a4ab1ade 4594 if (!hif_drv) {
24db713f
LK
4595 PRINT_ER("driver is null\n");
4596 return -EFAULT;
4597 }
c5c77ba1 4598
143eb95a 4599 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4600
4601 PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
4602
a9f812a6 4603 msg.id = HOST_IF_MSG_DEL_ALL_STA;
a4ab1ade 4604 msg.drv = hif_drv;
c5c77ba1 4605
c5c77ba1
JK
4606 for (i = 0; i < MAX_NUM_STA; i++) {
4607 if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
e51b9216
LK
4608 memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN);
4609 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4610 pstrDelAllStationMsg->del_all_sta[i][0],
4611 pstrDelAllStationMsg->del_all_sta[i][1],
4612 pstrDelAllStationMsg->del_all_sta[i][2],
4613 pstrDelAllStationMsg->del_all_sta[i][3],
4614 pstrDelAllStationMsg->del_all_sta[i][4],
4615 pstrDelAllStationMsg->del_all_sta[i][5]);
c5c77ba1
JK
4616 u8AssocNumb++;
4617 }
4618 }
4619 if (!u8AssocNumb) {
4620 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
31390eec 4621 return result;
c5c77ba1
JK
4622 }
4623
8ba1803f 4624 pstrDelAllStationMsg->assoc_sta = u8AssocNumb;
31390eec 4625 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 4626
31390eec 4627 if (result)
24db713f 4628 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4629
2d25af87 4630 down(&hif_sema_wait_response);
c5c77ba1 4631
31390eec 4632 return result;
c5c77ba1
JK
4633}
4634
a4ab1ade 4635s32 host_int_edit_station(struct host_if_drv *hif_drv,
6a89ba9c 4636 struct add_sta_param *pstrStaParams)
c5c77ba1 4637{
31390eec 4638 s32 result = 0;
143eb95a 4639 struct host_if_msg msg;
ca8f47f8 4640 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1 4641
a4ab1ade 4642 if (!hif_drv) {
24db713f
LK
4643 PRINT_ER("driver is null\n");
4644 return -EFAULT;
4645 }
c5c77ba1
JK
4646
4647 PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
4648
143eb95a 4649 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4650
a9f812a6 4651 msg.id = HOST_IF_MSG_EDIT_STATION;
a4ab1ade 4652 msg.drv = hif_drv;
c5c77ba1 4653
6a89ba9c 4654 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4655 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4656 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
c09389ac 4657
7ae43363
LK
4658 if (!rates)
4659 return -ENOMEM;
4660
d00d2ba3 4661 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4662 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4663 }
4664
31390eec
LK
4665 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4666 if (result)
24db713f
LK
4667 PRINT_ER("wilc_mq_send fail\n");
4668
31390eec 4669 return result;
c5c77ba1 4670}
108b3439 4671
a4ab1ade
TC
4672s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
4673 bool bIsEnabled,
4674 u32 u32Timeout)
c5c77ba1 4675{
31390eec 4676 s32 result = 0;
143eb95a 4677 struct host_if_msg msg;
49e1f81b 4678 struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
c5c77ba1 4679
03b2d5e7 4680 PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
c5c77ba1 4681
a4ab1ade 4682 if (!hif_drv) {
24db713f
LK
4683 PRINT_ER("driver is null\n");
4684 return -EFAULT;
4685 }
c5c77ba1
JK
4686
4687 PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
4688
143eb95a 4689 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4690
a9f812a6 4691 msg.id = HOST_IF_MSG_POWER_MGMT;
a4ab1ade 4692 msg.drv = hif_drv;
c5c77ba1 4693
33c70c1b 4694 pstrPowerMgmtParam->enabled = bIsEnabled;
937918ff 4695 pstrPowerMgmtParam->timeout = u32Timeout;
c5c77ba1 4696
31390eec
LK
4697 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4698 if (result)
24db713f 4699 PRINT_ER("wilc_mq_send fail\n");
31390eec 4700 return result;
c5c77ba1
JK
4701}
4702
a4ab1ade
TC
4703s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
4704 bool bIsEnabled,
4705 u32 u32count)
c5c77ba1 4706{
31390eec 4707 s32 result = 0;
143eb95a 4708 struct host_if_msg msg;
a079cf4d 4709 struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
c5c77ba1 4710
a4ab1ade 4711 if (!hif_drv) {
24db713f
LK
4712 PRINT_ER("driver is null\n");
4713 return -EFAULT;
4714 }
c5c77ba1
JK
4715
4716 PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
4717
143eb95a 4718 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4719
a9f812a6 4720 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
a4ab1ade 4721 msg.drv = hif_drv;
c5c77ba1 4722
bae636eb 4723 pstrMulticastFilterParam->enabled = bIsEnabled;
adab2f71 4724 pstrMulticastFilterParam->cnt = u32count;
c5c77ba1 4725
31390eec
LK
4726 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4727 if (result)
24db713f 4728 PRINT_ER("wilc_mq_send fail\n");
31390eec 4729 return result;
c5c77ba1
JK
4730}
4731
c5c77ba1
JK
4732static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
4733{
e0a12217 4734 struct join_bss_param *pNewJoinBssParam = NULL;
63d03e47 4735 u8 *pu8IEs;
d85f5326
CL
4736 u16 u16IEsLen;
4737 u16 index = 0;
63d03e47
GKH
4738 u8 suppRatesNo = 0;
4739 u8 extSuppRatesNo;
d85f5326 4740 u16 jumpOffset;
63d03e47
GKH
4741 u8 pcipherCount;
4742 u8 authCount;
4743 u8 pcipherTotalCount = 0;
4744 u8 authTotalCount = 0;
4745 u8 i, j;
c5c77ba1
JK
4746
4747 pu8IEs = ptstrNetworkInfo->pu8IEs;
4748 u16IEsLen = ptstrNetworkInfo->u16IEsLen;
4749
b156f1ed 4750 pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
91109e11 4751 if (pNewJoinBssParam) {
c5c77ba1
JK
4752 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
4753 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
4754 pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
d00d2ba3 4755 memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
d00d2ba3 4756 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
619d27b8 4757 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen;
2cc46837
CL
4758 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4759 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
c5c77ba1 4760
c5c77ba1 4761 while (index < u16IEsLen) {
c5c77ba1 4762 if (pu8IEs[index] == SUPP_RATES_IE) {
c5c77ba1
JK
4763 suppRatesNo = pu8IEs[index + 1];
4764 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
ae4dfa57 4765 index += 2;
c5c77ba1 4766
d1666e2a 4767 for (i = 0; i < suppRatesNo; i++)
c5c77ba1 4768 pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
d1666e2a 4769
c5c77ba1
JK
4770 index += suppRatesNo;
4771 continue;
ae4dfa57 4772 } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
c5c77ba1
JK
4773 extSuppRatesNo = pu8IEs[index + 1];
4774 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4775 pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4776 else
4777 pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4778 index += 2;
d1666e2a 4779 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
c5c77ba1 4780 pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
d1666e2a 4781
c5c77ba1
JK
4782 index += extSuppRatesNo;
4783 continue;
ae4dfa57 4784 } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
0be1eb74 4785 pNewJoinBssParam->ht_capable = true;
ae4dfa57 4786 index += pu8IEs[index + 1] + 2;
c5c77ba1 4787 continue;
ae4dfa57 4788 } else if ((pu8IEs[index] == WMM_IE) &&
c5c77ba1 4789 (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
ae4dfa57
LK
4790 (pu8IEs[index + 4] == 0xF2) &&
4791 (pu8IEs[index + 5] == 0x02) &&
4792 ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
c5c77ba1 4793 (pu8IEs[index + 7] == 0x01)) {
0be1eb74 4794 pNewJoinBssParam->wmm_cap = true;
c5c77ba1 4795
ffda203c 4796 if (pu8IEs[index + 8] & BIT(7))
0be1eb74 4797 pNewJoinBssParam->uapsd_cap = true;
c5c77ba1
JK
4798 index += pu8IEs[index + 1] + 2;
4799 continue;
ae4dfa57 4800 } else if ((pu8IEs[index] == P2P_IE) &&
c5c77ba1 4801 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
ae4dfa57
LK
4802 (pu8IEs[index + 4] == 0x9a) &&
4803 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
d85f5326 4804 u16 u16P2P_count;
78c87591 4805
c5c77ba1 4806 pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
7a8d51d7 4807 pNewJoinBssParam->noa_enabled = 1;
cc179008 4808 pNewJoinBssParam->idx = pu8IEs[index + 9];
c5c77ba1 4809
ffda203c 4810 if (pu8IEs[index + 10] & BIT(7)) {
d72b33ca 4811 pNewJoinBssParam->opp_enabled = 1;
99b66945 4812 pNewJoinBssParam->ct_window = pu8IEs[index + 10];
d72b33ca
LK
4813 } else {
4814 pNewJoinBssParam->opp_enabled = 0;
4815 }
ae4dfa57 4816
03b2d5e7 4817 PRINT_D(GENERIC_DBG, "P2P Dump\n");
c5c77ba1 4818 for (i = 0; i < pu8IEs[index + 7]; i++)
03b2d5e7 4819 PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
c5c77ba1 4820
c21047ed 4821 pNewJoinBssParam->cnt = pu8IEs[index + 11];
c5c77ba1
JK
4822 u16P2P_count = index + 12;
4823
109e6cab 4824 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4825 u16P2P_count += 4;
4826
1d8b76b3 4827 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4828 u16P2P_count += 4;
4829
4be55e22 4830 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4831
4832 index += pu8IEs[index + 1] + 2;
4833 continue;
4834
ae4dfa57 4835 } else if ((pu8IEs[index] == RSN_IE) ||
c5c77ba1
JK
4836 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4837 (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4838 (pu8IEs[index + 5] == 0x01))) {
d85f5326 4839 u16 rsnIndex = index;
ae4dfa57 4840
c5c77ba1
JK
4841 if (pu8IEs[rsnIndex] == RSN_IE) {
4842 pNewJoinBssParam->mode_802_11i = 2;
ae4dfa57 4843 } else {
c5c77ba1
JK
4844 if (pNewJoinBssParam->mode_802_11i == 0)
4845 pNewJoinBssParam->mode_802_11i = 1;
c5c77ba1
JK
4846 rsnIndex += 4;
4847 }
ae4dfa57
LK
4848
4849 rsnIndex += 7;
c5c77ba1
JK
4850 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4851 rsnIndex++;
ae4dfa57 4852 jumpOffset = pu8IEs[rsnIndex] * 4;
c5c77ba1 4853 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4854 rsnIndex += 2;
c5c77ba1 4855
d1666e2a 4856 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
c5c77ba1 4857 pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
d1666e2a 4858
c5c77ba1
JK
4859 pcipherTotalCount += pcipherCount;
4860 rsnIndex += jumpOffset;
4861
4862 jumpOffset = pu8IEs[rsnIndex] * 4;
4863
c5c77ba1 4864 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4865 rsnIndex += 2;
c5c77ba1 4866
d1666e2a 4867 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
c5c77ba1 4868 pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
d1666e2a 4869
c5c77ba1
JK
4870 authTotalCount += authCount;
4871 rsnIndex += jumpOffset;
ae4dfa57 4872
c5c77ba1
JK
4873 if (pu8IEs[index] == RSN_IE) {
4874 pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4875 pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4876 rsnIndex += 2;
4877 }
f717c0eb 4878 pNewJoinBssParam->rsn_found = true;
ae4dfa57 4879 index += pu8IEs[index + 1] + 2;
c5c77ba1
JK
4880 continue;
4881 } else
ae4dfa57 4882 index += pu8IEs[index + 1] + 2;
c5c77ba1 4883 }
c5c77ba1
JK
4884 }
4885
4886 return (void *)pNewJoinBssParam;
c5c77ba1
JK
4887}
4888
4889void host_int_freeJoinParams(void *pJoinParams)
4890{
91109e11 4891 if ((struct bss_param *)pJoinParams)
e0a12217 4892 kfree((struct bss_param *)pJoinParams);
c5c77ba1
JK
4893 else
4894 PRINT_ER("Unable to FREE null pointer\n");
4895}
c5c77ba1 4896
a4ab1ade 4897s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
c5c77ba1 4898{
31390eec 4899 s32 result = 0;
143eb95a 4900 struct host_if_msg msg;
c833b474 4901 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 4902
a4ab1ade 4903 if (!hif_drv) {
24db713f
LK
4904 PRINT_ER("driver is null\n");
4905 return -EFAULT;
4906 }
c5c77ba1 4907
143eb95a 4908 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4909
a9f812a6 4910 msg.id = HOST_IF_MSG_DEL_BA_SESSION;
c5c77ba1
JK
4911
4912 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4913 pBASessionInfo->u8Ted = TID;
a4ab1ade 4914 msg.drv = hif_drv;
c5c77ba1 4915
31390eec
LK
4916 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4917 if (result)
24db713f 4918 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4919
2d25af87 4920 down(&hif_sema_wait_response);
c5c77ba1 4921
31390eec 4922 return result;
c5c77ba1
JK
4923}
4924
a4ab1ade
TC
4925s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
4926 char *pBSSID,
4927 char TID)
c5c77ba1 4928{
31390eec 4929 s32 result = 0;
143eb95a 4930 struct host_if_msg msg;
c833b474 4931 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 4932
a4ab1ade 4933 if (!hif_drv) {
24db713f
LK
4934 PRINT_ER("driver is null\n");
4935 return -EFAULT;
4936 }
c5c77ba1 4937
143eb95a 4938 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4939
a9f812a6 4940 msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
c5c77ba1
JK
4941
4942 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4943 pBASessionInfo->u8Ted = TID;
a4ab1ade 4944 msg.drv = hif_drv;
c5c77ba1 4945
31390eec
LK
4946 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4947 if (result)
24db713f 4948 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4949
2d25af87 4950 down(&hif_sema_wait_response);
c5c77ba1 4951
31390eec 4952 return result;
c5c77ba1
JK
4953}
4954
a4ab1ade 4955s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 4956{
31390eec 4957 s32 result = 0;
143eb95a 4958 struct host_if_msg msg;
c5c77ba1 4959
c5c77ba1
JK
4960 return 0;
4961
a4ab1ade 4962 if (!hif_drv) {
24db713f
LK
4963 PRINT_ER("driver is null\n");
4964 return -EFAULT;
4965 }
c5c77ba1 4966
143eb95a 4967 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4968
a9f812a6 4969 msg.id = HOST_IF_MSG_SET_IPADDRESS;
c5c77ba1 4970
78675be5 4971 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 4972 msg.drv = hif_drv;
fb2d65ed 4973 msg.body.ip_info.idx = idx;
c5c77ba1 4974
31390eec
LK
4975 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4976 if (result)
24db713f 4977 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4978
31390eec 4979 return result;
c5c77ba1
JK
4980}
4981
a4ab1ade 4982s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 4983{
31390eec 4984 s32 result = 0;
143eb95a 4985 struct host_if_msg msg;
c5c77ba1 4986
a4ab1ade 4987 if (!hif_drv) {
24db713f
LK
4988 PRINT_ER("driver is null\n");
4989 return -EFAULT;
4990 }
c5c77ba1 4991
143eb95a 4992 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4993
a9f812a6 4994 msg.id = HOST_IF_MSG_GET_IPADDRESS;
c5c77ba1 4995
78675be5 4996 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 4997 msg.drv = hif_drv;
fb2d65ed 4998 msg.body.ip_info.idx = idx;
c5c77ba1 4999
31390eec
LK
5000 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
5001 if (result)
24db713f 5002 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 5003
31390eec 5004 return result;
c5c77ba1 5005}