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