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