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