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