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