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