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