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