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