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