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