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