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