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