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