]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/staging/wilc1000/host_interface.c
staging: wilc1000: fixes alignment should match open parenthesis
[mirror_ubuntu-hirsute-kernel.git] / drivers / staging / wilc1000 / host_interface.c
CommitLineData
e215a871
CL
1#include <linux/slab.h>
2#include <linux/time.h>
3#include <linux/kthread.h>
4#include <linux/delay.h>
c5c77ba1 5#include "host_interface.h"
c5c77ba1 6#include "coreconfigurator.h"
5366012d 7#include "wilc_wlan_if.h"
f23eb98b 8#include "wilc_msgqueue.h"
281dd5ac 9#include <linux/etherdevice.h>
c5c77ba1 10
63d03e47 11extern u8 connecting;
c5c77ba1 12
da711eb6 13extern struct timer_list hDuringIpTimer;
c5c77ba1 14
63d03e47 15extern u8 g_wilc_initialized;
c5c77ba1 16
9eac3a15
CL
17#define HOST_IF_MSG_SCAN 0
18#define HOST_IF_MSG_CONNECT 1
19#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
20#define HOST_IF_MSG_KEY 3
21#define HOST_IF_MSG_RCVD_NTWRK_INFO 4
22#define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
23#define HOST_IF_MSG_CFG_PARAMS 6
24#define HOST_IF_MSG_SET_CHANNEL 7
25#define HOST_IF_MSG_DISCONNECT 8
26#define HOST_IF_MSG_GET_RSSI 9
27#define HOST_IF_MSG_GET_CHNL 10
28#define HOST_IF_MSG_ADD_BEACON 11
29#define HOST_IF_MSG_DEL_BEACON 12
30#define HOST_IF_MSG_ADD_STATION 13
31#define HOST_IF_MSG_DEL_STATION 14
32#define HOST_IF_MSG_EDIT_STATION 15
33#define HOST_IF_MSG_SCAN_TIMER_FIRED 16
34#define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
35#define HOST_IF_MSG_POWER_MGMT 18
36#define HOST_IF_MSG_GET_INACTIVETIME 19
37#define HOST_IF_MSG_REMAIN_ON_CHAN 20
38#define HOST_IF_MSG_REGISTER_FRAME 21
39#define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
40#define HOST_IF_MSG_GET_LINKSPEED 23
41#define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
42#define HOST_IF_MSG_SET_MAC_ADDRESS 25
43#define HOST_IF_MSG_GET_MAC_ADDRESS 26
44#define HOST_IF_MSG_SET_OPERATION_MODE 27
45#define HOST_IF_MSG_SET_IPADDRESS 28
46#define HOST_IF_MSG_GET_IPADDRESS 29
47#define HOST_IF_MSG_FLUSH_CONNECT 30
48#define HOST_IF_MSG_GET_STATISTICS 31
49#define HOST_IF_MSG_SET_MULTICAST_FILTER 32
50#define HOST_IF_MSG_ADD_BA_SESSION 33
51#define HOST_IF_MSG_DEL_BA_SESSION 34
52#define HOST_IF_MSG_Q_IDLE 35
53#define HOST_IF_MSG_DEL_ALL_STA 36
54#define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS 34
55#define HOST_IF_MSG_EXIT 100
d85f5326 56
e54d5b75
CL
57#define HOST_IF_SCAN_TIMEOUT 4000
58#define HOST_IF_CONNECT_TIMEOUT 9500
c5c77ba1 59
e54d5b75
CL
60#define BA_SESSION_DEFAULT_BUFFER_SIZE 16
61#define BA_SESSION_DEFAULT_TIMEOUT 1000
62#define BLOCK_ACK_REQ_SIZE 0x14
9f3295a2 63#define FALSE_FRMWR_CHANNEL 100
c5c77ba1 64
361ff841 65struct cfg_param_attr {
221371e5 66 struct cfg_param_val cfg_attr_info;
361ff841 67};
c5c77ba1 68
4372d3d3 69struct host_if_wpa_attr {
124968fc 70 u8 *key;
248080aa 71 const u8 *mac_addr;
0e74c009 72 u8 *seq;
dacc594d 73 u8 seq_len;
e2dfbac5 74 u8 index;
6acf2919 75 u8 key_len;
7b2ebb28 76 u8 mode;
4372d3d3 77};
c5c77ba1 78
c276c44a 79struct host_if_wep_attr {
e5538d34 80 u8 *key;
d520e355 81 u8 key_len;
259b3aa6 82 u8 index;
b5eaff12 83 u8 mode;
7fa252e7 84 enum AUTHTYPE auth_type;
c276c44a 85};
c5c77ba1 86
40cc2c90 87union host_if_key_attr {
2ed7a2fb 88 struct host_if_wep_attr wep;
e3501a4d 89 struct host_if_wpa_attr wpa;
610e3868 90 struct host_if_pmkid_attr pmkid;
40cc2c90 91};
c5c77ba1 92
c98387a5 93struct key_attr {
8e9f427a 94 enum KEY_TYPE type;
0d17e382 95 u8 action;
73b2e381 96 union host_if_key_attr attr;
c98387a5 97};
c5c77ba1 98
c476feb8 99struct scan_attr {
42568898 100 u8 src;
1e276c88 101 u8 type;
82eeb0ad 102 u8 *ch_freq_list;
f97bd9ca 103 u8 ch_list_len;
d6f19aa5 104 u8 *ies;
7b1f76cd 105 size_t ies_len;
c17c6da6 106 wilc_scan_result result;
5f2b50c8 107 void *arg;
629b9ca0 108 struct hidden_network hidden_network;
c476feb8 109};
c5c77ba1 110
120ae593 111struct connect_attr {
9254db07 112 u8 *bssid;
f7bbd9cf 113 u8 *ssid;
8b3c9fa6 114 size_t ssid_len;
2ea158c4 115 u8 *ies;
b59d5c5b 116 size_t ies_len;
a64fd677 117 u8 security;
6abcc11d 118 wilc_connect_result result;
8f38db89 119 void *arg;
61b4fd02 120 enum AUTHTYPE auth_type;
0d1527e6 121 u8 ch;
f2bed2ca 122 void *params;
120ae593 123};
c5c77ba1 124
f23a9eab 125struct rcvd_async_info {
33722ac7 126 u8 *buffer;
f94f4889 127 u32 len;
f23a9eab 128};
c5c77ba1 129
94bdfe42 130struct channel_attr {
730ee059 131 u8 set_ch;
326b323d 132};
c5c77ba1 133
7f33fecd 134struct beacon_attr {
12262dda 135 u32 interval;
e76ab770 136 u32 dtim_period;
51c66185 137 u32 head_len;
8ce528b9 138 u8 *head;
030c57e2 139 u32 tail_len;
7dbcb6d3 140 u8 *tail;
902362b1 141};
c5c77ba1 142
641210ac 143struct set_multicast {
bae636eb 144 bool enabled;
adab2f71 145 u32 cnt;
641210ac 146};
c5c77ba1 147
b4e644e4 148struct del_all_sta {
e51b9216 149 u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
8ba1803f 150 u8 assoc_sta;
b4e644e4 151};
c5c77ba1 152
fb93a1e1 153struct del_sta {
e4839d39 154 u8 mac_addr[ETH_ALEN];
fb93a1e1 155};
c5c77ba1 156
5a008f1c 157struct power_mgmt_param {
33c70c1b 158 bool enabled;
937918ff 159 u32 timeout;
5a008f1c 160};
c5c77ba1 161
15191eaf 162struct set_ip_addr {
78675be5 163 u8 *ip_addr;
63d03e47 164 u8 idx;
15191eaf 165};
c5c77ba1 166
3d1eac04 167struct sta_inactive_t {
63d03e47 168 u8 mac[6];
3d1eac04 169};
ae4dfa57 170
dfc7663b 171union message_body {
4528bdb5 172 struct scan_attr scan_info;
3f501971 173 struct connect_attr con_info;
02d19460 174 struct rcvd_net_info net_info;
66add622 175 struct rcvd_async_info async_info;
18990bfe 176 struct key_attr key_info;
a2340c36 177 struct cfg_param_attr cfg_info;
ffd6dbc8 178 struct channel_attr channel_info;
a98491e5 179 struct beacon_attr beacon_info;
ca8f47f8 180 struct add_sta_param add_sta_info;
889c25be 181 struct del_sta del_sta_info;
4a930962 182 struct add_sta_param edit_sta_info;
49e1f81b 183 struct power_mgmt_param pwr_mgmt_info;
66bac7f2 184 struct sta_inactive_t mac_info;
fb2d65ed 185 struct set_ip_addr ip_info;
5e4377e6 186 struct drv_handler drv;
a079cf4d 187 struct set_multicast multicast_info;
00c4630e 188 struct op_mode mode;
15326e28 189 struct set_mac_addr set_mac_info;
a5848695 190 struct get_mac_addr get_mac_info;
c833b474 191 struct ba_session_info session_info;
070d365c 192 struct remain_ch remain_on_ch;
5c4008db 193 struct reg_frame reg_frame;
e60831e9 194 char *data;
b0c1e80e 195 struct del_all_sta del_all_sta_info;
dfc7663b 196};
c5c77ba1 197
3a8c41b5 198struct host_if_msg {
ae4dfa57
LK
199 u16 id;
200 union message_body body;
2482a79f 201 struct host_if_drv *drv;
3a8c41b5 202};
c5c77ba1 203
e0a12217 204struct join_bss_param {
c5c77ba1 205 BSSTYPE_T bss_type;
63d03e47 206 u8 dtim_period;
d85f5326
CL
207 u16 beacon_period;
208 u16 cap_info;
63d03e47 209 u8 au8bssid[6];
576917ad 210 char ssid[MAX_SSID_LEN];
619d27b8 211 u8 ssid_len;
63d03e47
GKH
212 u8 supp_rates[MAX_RATES_SUPPORTED + 1];
213 u8 ht_capable;
214 u8 wmm_cap;
215 u8 uapsd_cap;
72ed4dc7 216 bool rsn_found;
63d03e47
GKH
217 u8 rsn_grp_policy;
218 u8 mode_802_11i;
219 u8 rsn_pcip_policy[3];
220 u8 rsn_auth_policy[3];
221 u8 rsn_cap[2];
4e4467fd 222 u32 tsf;
7a8d51d7 223 u8 noa_enabled;
d72b33ca 224 u8 opp_enabled;
99b66945 225 u8 ct_window;
c21047ed 226 u8 cnt;
cc179008 227 u8 idx;
109e6cab 228 u8 duration[4];
1d8b76b3 229 u8 interval[4];
63d03e47 230 u8 au8StartTime[4];
e0a12217 231};
c5c77ba1 232
441dc609
LK
233static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1];
234struct host_if_drv *terminated_handle;
f2fc9f6e 235bool g_obtainingIP;
63d03e47 236u8 P2P_LISTEN_STATE;
c2115d8e 237static struct task_struct *hif_thread_handler;
cb067dcf 238static WILC_MsgQueueHandle hif_msg_q;
834e0cb0 239static struct semaphore hif_sema_thread;
413f930e 240static struct semaphore hif_sema_driver;
2d25af87 241static struct semaphore hif_sema_wait_response;
17225002 242static struct semaphore hif_sema_deinit;
24aadb8b 243static struct timer_list periodic_rssi;
c5c77ba1 244
63d03e47 245u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
c5c77ba1 246
a633c0b5 247static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
c5c77ba1 248
f64321c6 249static bool scan_while_connected;
c5c77ba1 250
144b7b23 251static s8 rssi;
75327a02 252static s8 link_speed;
95ebb0ff 253static u8 ch_no;
078b1e98 254static u8 set_ip[2][4];
1e75d01c 255static u8 get_ip[2][4];
ad26906f 256static u32 inactive_time;
a74c7bf8 257static u8 del_beacon;
7178aed8 258static u32 clients_count;
c5c77ba1 259
ef599194 260static u8 *join_req;
48ce2465 261u8 *info_element;
23047d5b 262static u8 mode_11i;
fba4989e 263u8 auth_type;
0626baaa 264u32 join_req_size;
5e0e7c2e 265static u32 info_element_size;
23fba59d 266static struct host_if_drv *join_req_drv;
c5c77ba1
JK
267#define REAL_JOIN_REQ 0
268#define FLUSHED_JOIN_REQ 1
ae4dfa57 269#define FLUSHED_BYTE_POS 79
c5c77ba1 270
c5c77ba1 271static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo);
c5c77ba1 272
4e4467fd 273extern void chip_sleep_manually(u32 u32SleepTime);
c5c77ba1
JK
274extern int linux_wlan_get_num_conn_ifcs(void);
275
441dc609 276static int add_handler_in_list(struct host_if_drv *handler)
d42ab083
JK
277{
278 int i;
279
280 for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
281 if (!wfidrv_list[i]) {
282 wfidrv_list[i] = handler;
283 return 0;
284 }
285 }
286
287 return -ENOBUFS;
288}
289
441dc609 290static int remove_handler_in_list(struct host_if_drv *handler)
d42ab083
JK
291{
292 int i;
293
294 for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
295 if (wfidrv_list[i] == handler) {
296 wfidrv_list[i] = NULL;
297 return 0;
298 }
299 }
300
301 return -EINVAL;
302}
303
441dc609 304static int get_id_from_handler(struct host_if_drv *handler)
d42ab083
JK
305{
306 int i;
307
308 if (!handler)
309 return 0;
310
311 for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
312 if (wfidrv_list[i] == handler)
313 return i;
314 }
315
316 return 0;
317}
318
441dc609 319static struct host_if_drv *get_handler_from_id(int id)
d42ab083 320{
6ae9ac0b 321 if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list))
d42ab083
JK
322 return NULL;
323 return wfidrv_list[id];
324}
325
a4ab1ade 326static s32 Handle_SetChannel(struct host_if_drv *hif_drv,
94bdfe42 327 struct channel_attr *pstrHostIFSetChan)
c5c77ba1 328{
31390eec 329 s32 result = 0;
e9e0c260 330 struct wid strWID;
c5c77ba1 331
daaf16ba 332 strWID.id = (u16)WID_CURRENT_CHANNEL;
416d8321 333 strWID.type = WID_CHAR;
730ee059 334 strWID.val = (char *)&(pstrHostIFSetChan->set_ch);
2fd3e443 335 strWID.size = sizeof(char);
c5c77ba1
JK
336
337 PRINT_D(HOSTINF_DBG, "Setting channel\n");
ae4dfa57 338
31390eec 339 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 340 get_id_from_handler(hif_drv));
31390eec
LK
341
342 if (result) {
c5c77ba1 343 PRINT_ER("Failed to set channel\n");
24db713f 344 return -EINVAL;
c5c77ba1
JK
345 }
346
31390eec 347 return result;
c5c77ba1 348}
ae4dfa57 349
a4ab1ade 350static s32 Handle_SetWfiDrvHandler(struct host_if_drv *hif_drv,
127f9d94 351 struct drv_handler *pstrHostIfSetDrvHandler)
c5c77ba1 352{
31390eec 353 s32 result = 0;
e9e0c260 354 struct wid strWID;
c5c77ba1 355
daaf16ba 356 strWID.id = (u16)WID_SET_DRV_HANDLER;
416d8321 357 strWID.type = WID_INT;
900bb4a6 358 strWID.val = (s8 *)&(pstrHostIfSetDrvHandler->u32Address);
2fd3e443 359 strWID.size = sizeof(u32);
c5c77ba1 360
31390eec 361 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 362 pstrHostIfSetDrvHandler->u32Address);
c5c77ba1 363
a4ab1ade 364 if (!hif_drv)
27ff2168 365 up(&hif_sema_driver);
c5c77ba1 366
31390eec 367 if (result) {
c5c77ba1 368 PRINT_ER("Failed to set driver handler\n");
24db713f 369 return -EINVAL;
c5c77ba1
JK
370 }
371
31390eec 372 return result;
c5c77ba1
JK
373}
374
a4ab1ade 375static s32 Handle_SetOperationMode(struct host_if_drv *hif_drv,
801bee52 376 struct op_mode *pstrHostIfSetOperationMode)
c5c77ba1 377{
31390eec 378 s32 result = 0;
e9e0c260 379 struct wid strWID;
c5c77ba1 380
daaf16ba 381 strWID.id = (u16)WID_SET_OPERATION_MODE;
416d8321 382 strWID.type = WID_INT;
900bb4a6 383 strWID.val = (s8 *)&(pstrHostIfSetOperationMode->u32Mode);
2fd3e443 384 strWID.size = sizeof(u32);
c5c77ba1 385
31390eec 386 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 387 get_id_from_handler(hif_drv));
c5c77ba1 388
c590b9a4 389 if ((pstrHostIfSetOperationMode->u32Mode) == IDLE_MODE)
27ff2168 390 up(&hif_sema_driver);
c5c77ba1 391
31390eec 392 if (result) {
c5c77ba1 393 PRINT_ER("Failed to set driver handler\n");
24db713f 394 return -EINVAL;
c5c77ba1
JK
395 }
396
31390eec 397 return result;
c5c77ba1
JK
398}
399
a4ab1ade 400s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx)
c5c77ba1 401{
31390eec 402 s32 result = 0;
e9e0c260 403 struct wid strWID;
c5c77ba1 404 char firmwareIPAddress[4] = {0};
c5c77ba1
JK
405
406 if (pu8IPAddr[0] < 192)
407 pu8IPAddr[0] = 0;
408
b3a02832 409 PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %pI4\n", idx, pu8IPAddr);
c5c77ba1 410
078b1e98 411 memcpy(set_ip[idx], pu8IPAddr, IP_ALEN);
c5c77ba1 412
daaf16ba 413 strWID.id = (u16)WID_IP_ADDRESS;
416d8321 414 strWID.type = WID_STR;
900bb4a6 415 strWID.val = (u8 *)pu8IPAddr;
2fd3e443 416 strWID.size = IP_ALEN;
c5c77ba1 417
31390eec 418 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 419 get_id_from_handler(hif_drv));
c5c77ba1 420
a4ab1ade 421 host_int_get_ipaddress(hif_drv, firmwareIPAddress, idx);
c5c77ba1 422
31390eec 423 if (result) {
24db713f
LK
424 PRINT_ER("Failed to set IP address\n");
425 return -EINVAL;
c5c77ba1
JK
426 }
427
24db713f 428 PRINT_INFO(HOSTINF_DBG, "IP address set\n");
c5c77ba1 429
31390eec 430 return result;
c5c77ba1
JK
431}
432
a4ab1ade 433s32 Handle_get_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx)
c5c77ba1 434{
31390eec 435 s32 result = 0;
e9e0c260 436 struct wid strWID;
c5c77ba1 437
daaf16ba 438 strWID.id = (u16)WID_IP_ADDRESS;
416d8321 439 strWID.type = WID_STR;
900bb4a6 440 strWID.val = kmalloc(IP_ALEN, GFP_KERNEL);
2fd3e443 441 strWID.size = IP_ALEN;
c5c77ba1 442
31390eec 443 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 444 get_id_from_handler(hif_drv));
c5c77ba1 445
900bb4a6 446 PRINT_INFO(HOSTINF_DBG, "%pI4\n", strWID.val);
c5c77ba1 447
1e75d01c 448 memcpy(get_ip[idx], strWID.val, IP_ALEN);
c5c77ba1 449
900bb4a6 450 kfree(strWID.val);
c5c77ba1 451
1e75d01c 452 if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
078b1e98 453 host_int_setup_ipaddress(hif_drv, set_ip[idx], idx);
c5c77ba1 454
31390eec 455 if (result != 0) {
c5c77ba1 456 PRINT_ER("Failed to get IP address\n");
24db713f 457 return -EINVAL;
c5c77ba1
JK
458 }
459
24db713f 460 PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d\n", idx);
1e75d01c 461 PRINT_INFO(HOSTINF_DBG, "%pI4\n", get_ip[idx]);
24db713f 462 PRINT_INFO(HOSTINF_DBG, "\n");
c5c77ba1 463
31390eec 464 return result;
c5c77ba1
JK
465}
466
a4ab1ade 467static s32 Handle_SetMacAddress(struct host_if_drv *hif_drv,
b7611a87 468 struct set_mac_addr *pstrHostIfSetMacAddress)
c5c77ba1 469{
31390eec 470 s32 result = 0;
e9e0c260 471 struct wid strWID;
f3052587 472 u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL);
78c87591 473
c5c77ba1
JK
474 if (mac_buf == NULL) {
475 PRINT_ER("No buffer to send mac address\n");
e6e12661 476 return -EFAULT;
c5c77ba1 477 }
d00d2ba3 478 memcpy(mac_buf, pstrHostIfSetMacAddress->u8MacAddress, ETH_ALEN);
c5c77ba1 479
daaf16ba 480 strWID.id = (u16)WID_MAC_ADDR;
416d8321 481 strWID.type = WID_STR;
900bb4a6 482 strWID.val = mac_buf;
2fd3e443 483 strWID.size = ETH_ALEN;
900bb4a6 484 PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", strWID.val);
ae4dfa57 485
31390eec 486 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 487 get_id_from_handler(hif_drv));
31390eec 488 if (result) {
c5c77ba1 489 PRINT_ER("Failed to set mac address\n");
31390eec 490 result = -EFAULT;
c5c77ba1
JK
491 }
492
49188af2 493 kfree(mac_buf);
31390eec 494 return result;
c5c77ba1
JK
495}
496
a4ab1ade 497static s32 Handle_GetMacAddress(struct host_if_drv *hif_drv,
fcd27c5f 498 struct get_mac_addr *pstrHostIfGetMacAddress)
c5c77ba1 499{
31390eec 500 s32 result = 0;
e9e0c260 501 struct wid strWID;
c5c77ba1 502
daaf16ba 503 strWID.id = (u16)WID_MAC_ADDR;
416d8321 504 strWID.type = WID_STR;
900bb4a6 505 strWID.val = pstrHostIfGetMacAddress->u8MacAddress;
2fd3e443 506 strWID.size = ETH_ALEN;
c5c77ba1 507
31390eec 508 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 509 get_id_from_handler(hif_drv));
31390eec
LK
510
511 if (result) {
c5c77ba1 512 PRINT_ER("Failed to get mac address\n");
31390eec 513 result = -EFAULT;
c5c77ba1 514 }
2d25af87 515 up(&hif_sema_wait_response);
c5c77ba1 516
31390eec 517 return result;
c5c77ba1
JK
518}
519
a4ab1ade 520static s32 Handle_CfgParam(struct host_if_drv *hif_drv,
361ff841 521 struct cfg_param_attr *strHostIFCfgParamAttr)
c5c77ba1 522{
31390eec 523 s32 result = 0;
e9e0c260 524 struct wid strWIDList[32];
63d03e47 525 u8 u8WidCnt = 0;
c5c77ba1 526
a4ab1ade 527 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1
JK
528
529
530 PRINT_D(HOSTINF_DBG, "Setting CFG params\n");
531
87c05b28 532 if (strHostIFCfgParamAttr->cfg_attr_info.flag & BSS_TYPE) {
221371e5 533 if (strHostIFCfgParamAttr->cfg_attr_info.bss_type < 6) {
daaf16ba 534 strWIDList[u8WidCnt].id = WID_BSS_TYPE;
221371e5 535 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.bss_type;
416d8321 536 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 537 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 538 hif_drv->strCfgValues.bss_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.bss_type;
c5c77ba1 539 } else {
24db713f 540 PRINT_ER("check value 6 over\n");
31390eec 541 result = -EINVAL;
24db713f 542 goto ERRORHANDLER;
c5c77ba1
JK
543 }
544 u8WidCnt++;
545 }
87c05b28 546 if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTH_TYPE) {
221371e5 547 if ((strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 1 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 2 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 5) {
daaf16ba 548 strWIDList[u8WidCnt].id = WID_AUTH_TYPE;
221371e5 549 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_type;
416d8321 550 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 551 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 552 hif_drv->strCfgValues.auth_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.auth_type;
c5c77ba1 553 } else {
24db713f 554 PRINT_ER("Impossible value \n");
31390eec 555 result = -EINVAL;
24db713f 556 goto ERRORHANDLER;
c5c77ba1
JK
557 }
558 u8WidCnt++;
559 }
87c05b28 560 if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTHEN_TIMEOUT) {
221371e5 561 if (strHostIFCfgParamAttr->cfg_attr_info.auth_timeout > 0 && strHostIFCfgParamAttr->cfg_attr_info.auth_timeout < 65536) {
daaf16ba 562 strWIDList[u8WidCnt].id = WID_AUTH_TIMEOUT;
221371e5 563 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_timeout;
416d8321 564 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 565 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 566 hif_drv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->cfg_attr_info.auth_timeout;
c5c77ba1 567 } else {
24db713f 568 PRINT_ER("Range(1 ~ 65535) over\n");
31390eec 569 result = -EINVAL;
24db713f 570 goto ERRORHANDLER;
c5c77ba1
JK
571 }
572 u8WidCnt++;
573 }
87c05b28 574 if (strHostIFCfgParamAttr->cfg_attr_info.flag & POWER_MANAGEMENT) {
221371e5 575 if (strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode < 5) {
daaf16ba 576 strWIDList[u8WidCnt].id = WID_POWER_MANAGEMENT;
221371e5 577 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode;
416d8321 578 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 579 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 580 hif_drv->strCfgValues.power_mgmt_mode = (u8)strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode;
c5c77ba1 581 } else {
24db713f 582 PRINT_ER("Invalide power mode\n");
31390eec 583 result = -EINVAL;
24db713f 584 goto ERRORHANDLER;
c5c77ba1
JK
585 }
586 u8WidCnt++;
587 }
87c05b28 588 if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_SHORT) {
221371e5 589 if ((strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit < 256)) {
daaf16ba 590 strWIDList[u8WidCnt].id = WID_SHORT_RETRY_LIMIT;
221371e5 591 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit;
416d8321 592 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 593 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 594 hif_drv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit;
c5c77ba1 595 } else {
24db713f 596 PRINT_ER("Range(1~256) over\n");
31390eec 597 result = -EINVAL;
24db713f 598 goto ERRORHANDLER;
c5c77ba1
JK
599 }
600 u8WidCnt++;
601 }
87c05b28 602 if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_LONG) {
221371e5 603 if ((strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit < 256)) {
daaf16ba 604 strWIDList[u8WidCnt].id = WID_LONG_RETRY_LIMIT;
221371e5 605 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit;
c5c77ba1 606
416d8321 607 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 608 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 609 hif_drv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit;
c5c77ba1 610 } else {
24db713f 611 PRINT_ER("Range(1~256) over\n");
31390eec 612 result = -EINVAL;
24db713f 613 goto ERRORHANDLER;
c5c77ba1
JK
614 }
615 u8WidCnt++;
616 }
87c05b28 617 if (strHostIFCfgParamAttr->cfg_attr_info.flag & FRAG_THRESHOLD) {
c5c77ba1 618
221371e5 619 if (strHostIFCfgParamAttr->cfg_attr_info.frag_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.frag_threshold < 7937) {
daaf16ba 620 strWIDList[u8WidCnt].id = WID_FRAG_THRESHOLD;
221371e5 621 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.frag_threshold;
416d8321 622 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 623 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 624 hif_drv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->cfg_attr_info.frag_threshold;
c5c77ba1 625 } else {
24db713f 626 PRINT_ER("Threshold Range fail\n");
31390eec 627 result = -EINVAL;
24db713f 628 goto ERRORHANDLER;
c5c77ba1
JK
629 }
630 u8WidCnt++;
631 }
87c05b28 632 if (strHostIFCfgParamAttr->cfg_attr_info.flag & RTS_THRESHOLD) {
221371e5 633 if (strHostIFCfgParamAttr->cfg_attr_info.rts_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.rts_threshold < 65536) {
daaf16ba 634 strWIDList[u8WidCnt].id = WID_RTS_THRESHOLD;
221371e5 635 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.rts_threshold;
416d8321 636 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 637 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 638 hif_drv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->cfg_attr_info.rts_threshold;
c5c77ba1 639 } else {
24db713f 640 PRINT_ER("Threshold Range fail\n");
31390eec 641 result = -EINVAL;
24db713f 642 goto ERRORHANDLER;
c5c77ba1
JK
643 }
644 u8WidCnt++;
645 }
87c05b28 646 if (strHostIFCfgParamAttr->cfg_attr_info.flag & PREAMBLE) {
221371e5 647 if (strHostIFCfgParamAttr->cfg_attr_info.preamble_type < 3) {
daaf16ba 648 strWIDList[u8WidCnt].id = WID_PREAMBLE;
221371e5 649 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.preamble_type;
416d8321 650 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 651 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 652 hif_drv->strCfgValues.preamble_type = strHostIFCfgParamAttr->cfg_attr_info.preamble_type;
c5c77ba1 653 } else {
24db713f 654 PRINT_ER("Preamle Range(0~2) over\n");
31390eec 655 result = -EINVAL;
24db713f 656 goto ERRORHANDLER;
c5c77ba1
JK
657 }
658 u8WidCnt++;
659 }
87c05b28 660 if (strHostIFCfgParamAttr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) {
221371e5 661 if (strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed < 2) {
daaf16ba 662 strWIDList[u8WidCnt].id = WID_SHORT_SLOT_ALLOWED;
221371e5 663 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed;
416d8321 664 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 665 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 666 hif_drv->strCfgValues.short_slot_allowed = (u8)strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed;
c5c77ba1 667 } else {
24db713f 668 PRINT_ER("Short slot(2) over\n");
31390eec 669 result = -EINVAL;
24db713f 670 goto ERRORHANDLER;
c5c77ba1
JK
671 }
672 u8WidCnt++;
673 }
87c05b28 674 if (strHostIFCfgParamAttr->cfg_attr_info.flag & TXOP_PROT_DISABLE) {
221371e5 675 if (strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled < 2) {
daaf16ba 676 strWIDList[u8WidCnt].id = WID_11N_TXOP_PROT_DISABLE;
221371e5 677 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled;
416d8321 678 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 679 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 680 hif_drv->strCfgValues.txop_prot_disabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled;
c5c77ba1 681 } else {
24db713f 682 PRINT_ER("TXOP prot disable\n");
31390eec 683 result = -EINVAL;
24db713f 684 goto ERRORHANDLER;
c5c77ba1
JK
685 }
686 u8WidCnt++;
687 }
87c05b28 688 if (strHostIFCfgParamAttr->cfg_attr_info.flag & BEACON_INTERVAL) {
221371e5 689 if (strHostIFCfgParamAttr->cfg_attr_info.beacon_interval > 0 && strHostIFCfgParamAttr->cfg_attr_info.beacon_interval < 65536) {
daaf16ba 690 strWIDList[u8WidCnt].id = WID_BEACON_INTERVAL;
221371e5 691 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.beacon_interval;
416d8321 692 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 693 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 694 hif_drv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->cfg_attr_info.beacon_interval;
c5c77ba1 695 } else {
24db713f 696 PRINT_ER("Beacon interval(1~65535) fail\n");
31390eec 697 result = -EINVAL;
24db713f 698 goto ERRORHANDLER;
c5c77ba1
JK
699 }
700 u8WidCnt++;
701 }
87c05b28 702 if (strHostIFCfgParamAttr->cfg_attr_info.flag & DTIM_PERIOD) {
221371e5 703 if (strHostIFCfgParamAttr->cfg_attr_info.dtim_period > 0 && strHostIFCfgParamAttr->cfg_attr_info.dtim_period < 256) {
daaf16ba 704 strWIDList[u8WidCnt].id = WID_DTIM_PERIOD;
221371e5 705 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.dtim_period;
416d8321 706 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 707 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 708 hif_drv->strCfgValues.dtim_period = strHostIFCfgParamAttr->cfg_attr_info.dtim_period;
c5c77ba1 709 } else {
24db713f 710 PRINT_ER("DTIM range(1~255) fail\n");
31390eec 711 result = -EINVAL;
24db713f 712 goto ERRORHANDLER;
c5c77ba1
JK
713 }
714 u8WidCnt++;
715 }
87c05b28 716 if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY) {
221371e5 717 if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled < 3) {
daaf16ba 718 strWIDList[u8WidCnt].id = WID_SITE_SURVEY;
221371e5 719 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled;
416d8321 720 strWIDList[u8WidCnt].type = WID_CHAR;
2fd3e443 721 strWIDList[u8WidCnt].size = sizeof(char);
221371e5 722 hif_drv->strCfgValues.site_survey_enabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled;
c5c77ba1 723 } else {
24db713f 724 PRINT_ER("Site survey disable\n");
31390eec 725 result = -EINVAL;
24db713f 726 goto ERRORHANDLER;
c5c77ba1
JK
727 }
728 u8WidCnt++;
729 }
87c05b28 730 if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) {
221371e5 731 if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time < 65536) {
daaf16ba 732 strWIDList[u8WidCnt].id = WID_SITE_SURVEY_SCAN_TIME;
221371e5 733 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time;
416d8321 734 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 735 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 736 hif_drv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time;
c5c77ba1 737 } else {
24db713f 738 PRINT_ER("Site survey scan time(1~65535) over\n");
31390eec 739 result = -EINVAL;
24db713f 740 goto ERRORHANDLER;
c5c77ba1
JK
741 }
742 u8WidCnt++;
743 }
87c05b28 744 if (strHostIFCfgParamAttr->cfg_attr_info.flag & ACTIVE_SCANTIME) {
221371e5 745 if (strHostIFCfgParamAttr->cfg_attr_info.active_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.active_scan_time < 65536) {
daaf16ba 746 strWIDList[u8WidCnt].id = WID_ACTIVE_SCAN_TIME;
221371e5 747 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.active_scan_time;
416d8321 748 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 749 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 750 hif_drv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->cfg_attr_info.active_scan_time;
c5c77ba1 751 } else {
24db713f 752 PRINT_ER("Active scan time(1~65535) over\n");
31390eec 753 result = -EINVAL;
24db713f 754 goto ERRORHANDLER;
c5c77ba1
JK
755 }
756 u8WidCnt++;
757 }
87c05b28 758 if (strHostIFCfgParamAttr->cfg_attr_info.flag & PASSIVE_SCANTIME) {
221371e5 759 if (strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time < 65536) {
daaf16ba 760 strWIDList[u8WidCnt].id = WID_PASSIVE_SCAN_TIME;
221371e5 761 strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time;
416d8321 762 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 763 strWIDList[u8WidCnt].size = sizeof(u16);
221371e5 764 hif_drv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time;
c5c77ba1 765 } else {
24db713f 766 PRINT_ER("Passive scan time(1~65535) over\n");
31390eec 767 result = -EINVAL;
24db713f 768 goto ERRORHANDLER;
c5c77ba1
JK
769 }
770 u8WidCnt++;
771 }
87c05b28 772 if (strHostIFCfgParamAttr->cfg_attr_info.flag & CURRENT_TX_RATE) {
221371e5 773 enum CURRENT_TXRATE curr_tx_rate = strHostIFCfgParamAttr->cfg_attr_info.curr_tx_rate;
c5c77ba1
JK
774 if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1
775 || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5
776 || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6
777 || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12
778 || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24
779 || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) {
daaf16ba 780 strWIDList[u8WidCnt].id = WID_CURRENT_TX_RATE;
900bb4a6 781 strWIDList[u8WidCnt].val = (s8 *)&curr_tx_rate;
416d8321 782 strWIDList[u8WidCnt].type = WID_SHORT;
2fd3e443 783 strWIDList[u8WidCnt].size = sizeof(u16);
a4ab1ade 784 hif_drv->strCfgValues.curr_tx_rate = (u8)curr_tx_rate;
c5c77ba1 785 } else {
24db713f 786 PRINT_ER("out of TX rate\n");
31390eec 787 result = -EINVAL;
24db713f 788 goto ERRORHANDLER;
c5c77ba1
JK
789 }
790 u8WidCnt++;
791 }
31390eec
LK
792
793 result = send_config_pkt(SET_CFG, strWIDList, u8WidCnt,
8c8360b3 794 get_id_from_handler(hif_drv));
c5c77ba1 795
31390eec 796 if (result)
c5c77ba1
JK
797 PRINT_ER("Error in setting CFG params\n");
798
24db713f 799ERRORHANDLER:
a4ab1ade 800 up(&hif_drv->gtOsCfgValuesSem);
31390eec 801 return result;
c5c77ba1
JK
802}
803
fb4ec9ca 804static s32 Handle_wait_msg_q_empty(void)
c5c77ba1 805{
c5c77ba1 806 g_wilc_initialized = 0;
2d25af87 807 up(&hif_sema_wait_response);
b68d820b 808 return 0;
c5c77ba1
JK
809}
810
a4ab1ade 811static s32 Handle_Scan(struct host_if_drv *hif_drv,
c476feb8 812 struct scan_attr *pstrHostIFscanAttr)
c5c77ba1 813{
31390eec 814 s32 result = 0;
e9e0c260 815 struct wid strWIDList[5];
4e4467fd
CL
816 u32 u32WidsCount = 0;
817 u32 i;
63d03e47
GKH
818 u8 *pu8Buffer;
819 u8 valuesize = 0;
820 u8 *pu8HdnNtwrksWidVal = NULL;
c5c77ba1
JK
821
822 PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
a4ab1ade 823 PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->enuHostIFstate);
c5c77ba1 824
c17c6da6 825 hif_drv->strWILC_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->result;
5f2b50c8 826 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->arg;
c5c77ba1 827
a4ab1ade 828 if ((hif_drv->enuHostIFstate >= HOST_IF_SCANNING) && (hif_drv->enuHostIFstate < HOST_IF_CONNECTED)) {
a4ab1ade 829 PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", hif_drv->enuHostIFstate);
24db713f 830 PRINT_ER("Already scan\n");
31390eec 831 result = -EBUSY;
24db713f 832 goto ERRORHANDLER;
c5c77ba1
JK
833 }
834
c5c77ba1
JK
835 if (g_obtainingIP || connecting) {
836 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
24db713f 837 PRINT_ER("Don't do obss scan\n");
31390eec 838 result = -EBUSY;
24db713f 839 goto ERRORHANDLER;
c5c77ba1 840 }
c5c77ba1
JK
841
842 PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
843
844
a4ab1ade 845 hif_drv->strWILC_UsrScanReq.u32RcvdChCount = 0;
c5c77ba1 846
daaf16ba 847 strWIDList[u32WidsCount].id = (u16)WID_SSID_PROBE_REQ;
416d8321 848 strWIDList[u32WidsCount].type = WID_STR;
c5c77ba1 849
629b9ca0
LK
850 for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++)
851 valuesize += ((pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen) + 1);
f3052587 852 pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
900bb4a6
LK
853 strWIDList[u32WidsCount].val = pu8HdnNtwrksWidVal;
854 if (strWIDList[u32WidsCount].val != NULL) {
855 pu8Buffer = strWIDList[u32WidsCount].val;
c5c77ba1 856
629b9ca0 857 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.u8ssidnum;
c5c77ba1 858
629b9ca0 859 PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->hidden_network.u8ssidnum);
c5c77ba1 860
629b9ca0
LK
861 for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++) {
862 *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen;
863 memcpy(pu8Buffer, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen);
864 pu8Buffer += pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen;
c5c77ba1
JK
865 }
866
867
868
2fd3e443 869 strWIDList[u32WidsCount].size = (s32)(valuesize + 1);
c5c77ba1
JK
870 u32WidsCount++;
871 }
872
c5c77ba1 873 {
daaf16ba 874 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_PROBE;
416d8321 875 strWIDList[u32WidsCount].type = WID_BIN_DATA;
d6f19aa5 876 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ies;
7b1f76cd 877 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ies_len;
c5c77ba1
JK
878 u32WidsCount++;
879 }
880
daaf16ba 881 strWIDList[u32WidsCount].id = WID_SCAN_TYPE;
416d8321 882 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 883 strWIDList[u32WidsCount].size = sizeof(char);
1e276c88 884 strWIDList[u32WidsCount].val = (s8 *)(&(pstrHostIFscanAttr->type));
c5c77ba1
JK
885 u32WidsCount++;
886
daaf16ba 887 strWIDList[u32WidsCount].id = WID_SCAN_CHANNEL_LIST;
416d8321 888 strWIDList[u32WidsCount].type = WID_BIN_DATA;
c5c77ba1 889
f97bd9ca 890 if (pstrHostIFscanAttr->ch_freq_list != NULL && pstrHostIFscanAttr->ch_list_len > 0) {
c5c77ba1
JK
891 int i;
892
f97bd9ca 893 for (i = 0; i < pstrHostIFscanAttr->ch_list_len; i++) {
82eeb0ad
LK
894 if (pstrHostIFscanAttr->ch_freq_list[i] > 0)
895 pstrHostIFscanAttr->ch_freq_list[i] = pstrHostIFscanAttr->ch_freq_list[i] - 1;
c5c77ba1
JK
896 }
897 }
898
82eeb0ad 899 strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ch_freq_list;
f97bd9ca 900 strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ch_list_len;
c5c77ba1
JK
901 u32WidsCount++;
902
daaf16ba 903 strWIDList[u32WidsCount].id = WID_START_SCAN_REQ;
416d8321 904 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 905 strWIDList[u32WidsCount].size = sizeof(char);
42568898 906 strWIDList[u32WidsCount].val = (s8 *)(&(pstrHostIFscanAttr->src));
c5c77ba1
JK
907 u32WidsCount++;
908
a4ab1ade 909 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
ca8540e4 910 scan_while_connected = true;
a4ab1ade 911 else if (hif_drv->enuHostIFstate == HOST_IF_IDLE)
ca8540e4 912 scan_while_connected = false;
c5c77ba1 913
31390eec 914 result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
8c8360b3 915 get_id_from_handler(hif_drv));
c5c77ba1 916
31390eec 917 if (result)
c5c77ba1 918 PRINT_ER("Failed to send scan paramters config packet\n");
24db713f 919 else
c5c77ba1 920 PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n");
c5c77ba1 921
24db713f 922ERRORHANDLER:
31390eec 923 if (result) {
a4ab1ade 924 del_timer(&hif_drv->hScanTimer);
a4ab1ade 925 Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
c5c77ba1
JK
926 }
927
95f840fb
SB
928 kfree(pstrHostIFscanAttr->ch_freq_list);
929 pstrHostIFscanAttr->ch_freq_list = NULL;
c5c77ba1 930
95f840fb
SB
931 kfree(pstrHostIFscanAttr->ies);
932 pstrHostIFscanAttr->ies = NULL;
933 kfree(pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo);
934 pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo = NULL;
c5c77ba1 935
95f840fb 936 kfree(pu8HdnNtwrksWidVal);
c5c77ba1 937
31390eec 938 return result;
c5c77ba1
JK
939}
940
a4ab1ade
TC
941static s32 Handle_ScanDone(struct host_if_drv *hif_drv,
942 enum scan_event enuEvent)
c5c77ba1 943{
31390eec 944 s32 result = 0;
63d03e47 945 u8 u8abort_running_scan;
e9e0c260 946 struct wid strWID;
c5c77ba1
JK
947
948
949 PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n");
950
c5c77ba1
JK
951 if (enuEvent == SCAN_EVENT_ABORTED) {
952 PRINT_D(GENERIC_DBG, "Abort running scan\n");
953 u8abort_running_scan = 1;
daaf16ba 954 strWID.id = (u16)WID_ABORT_RUNNING_SCAN;
416d8321 955 strWID.type = WID_CHAR;
900bb4a6 956 strWID.val = (s8 *)&u8abort_running_scan;
2fd3e443 957 strWID.size = sizeof(char);
c5c77ba1 958
31390eec 959 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 960 get_id_from_handler(hif_drv));
31390eec
LK
961
962 if (result) {
c5c77ba1 963 PRINT_ER("Failed to set abort running scan\n");
31390eec 964 result = -EFAULT;
c5c77ba1
JK
965 }
966 }
967
a4ab1ade 968 if (!hif_drv) {
c5c77ba1 969 PRINT_ER("Driver handler is NULL\n");
31390eec 970 return result;
c5c77ba1
JK
971 }
972
a4ab1ade
TC
973 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
974 hif_drv->strWILC_UsrScanReq.pfUserScanResult(enuEvent, NULL,
975 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
a4ab1ade 976 hif_drv->strWILC_UsrScanReq.pfUserScanResult = NULL;
c5c77ba1
JK
977 }
978
31390eec 979 return result;
c5c77ba1
JK
980}
981
63d03e47 982u8 u8ConnectedSSID[6] = {0};
a4ab1ade 983static s32 Handle_Connect(struct host_if_drv *hif_drv,
120ae593 984 struct connect_attr *pstrHostIFconnectAttr)
c5c77ba1 985{
31390eec 986 s32 result = 0;
e9e0c260 987 struct wid strWIDList[8];
4e4467fd 988 u32 u32WidsCount = 0, dummyval = 0;
63d03e47 989 u8 *pu8CurrByte = NULL;
e0a12217 990 struct join_bss_param *ptstrJoinBssParam;
c5c77ba1
JK
991
992 PRINT_D(GENERIC_DBG, "Handling connect request\n");
993
9254db07 994 if (memcmp(pstrHostIFconnectAttr->bssid, u8ConnectedSSID, ETH_ALEN) == 0) {
31390eec 995 result = 0;
c5c77ba1 996 PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n");
31390eec 997 return result;
c5c77ba1
JK
998 }
999
1000 PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n");
1001
f2bed2ca 1002 ptstrJoinBssParam = (struct join_bss_param *)pstrHostIFconnectAttr->params;
c5c77ba1
JK
1003 if (ptstrJoinBssParam == NULL) {
1004 PRINT_ER("Required BSSID not found\n");
31390eec 1005 result = -ENOENT;
24db713f 1006 goto ERRORHANDLER;
c5c77ba1 1007 }
c5c77ba1 1008
9254db07 1009 if (pstrHostIFconnectAttr->bssid != NULL) {
a4ab1ade 1010 hif_drv->strWILC_UsrConnReq.pu8bssid = kmalloc(6, GFP_KERNEL);
9254db07 1011 memcpy(hif_drv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->bssid, 6);
c5c77ba1
JK
1012 }
1013
8b3c9fa6 1014 hif_drv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssid_len;
f7bbd9cf 1015 if (pstrHostIFconnectAttr->ssid != NULL) {
8b3c9fa6 1016 hif_drv->strWILC_UsrConnReq.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
8c8360b3
LK
1017 memcpy(hif_drv->strWILC_UsrConnReq.pu8ssid,
1018 pstrHostIFconnectAttr->ssid,
1019 pstrHostIFconnectAttr->ssid_len);
8b3c9fa6 1020 hif_drv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
c5c77ba1
JK
1021 }
1022
b59d5c5b 1023 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->ies_len;
2ea158c4 1024 if (pstrHostIFconnectAttr->ies != NULL) {
b59d5c5b 1025 hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
8c8360b3
LK
1026 memcpy(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
1027 pstrHostIFconnectAttr->ies,
1028 pstrHostIFconnectAttr->ies_len);
c5c77ba1
JK
1029 }
1030
a64fd677 1031 hif_drv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->security;
61b4fd02 1032 hif_drv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->auth_type;
6abcc11d 1033 hif_drv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->result;
8f38db89 1034 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->arg;
c5c77ba1 1035
daaf16ba 1036 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
416d8321 1037 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 1038 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 1039 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
c5c77ba1
JK
1040 u32WidsCount++;
1041
daaf16ba 1042 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
416d8321 1043 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 1044 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 1045 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
c5c77ba1
JK
1046 u32WidsCount++;
1047
daaf16ba 1048 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
416d8321 1049 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 1050 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 1051 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
c5c77ba1
JK
1052 u32WidsCount++;
1053
c5c77ba1 1054 {
daaf16ba 1055 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
416d8321 1056 strWIDList[u32WidsCount].type = WID_BIN_DATA;
a4ab1ade
TC
1057 strWIDList[u32WidsCount].val = hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs;
1058 strWIDList[u32WidsCount].size = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
c5c77ba1
JK
1059 u32WidsCount++;
1060
f7bbd9cf 1061 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
dfef7b84
LK
1062 info_element_size = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
1063 info_element = kmalloc(info_element_size, GFP_KERNEL);
48ce2465 1064 memcpy(info_element, hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
dfef7b84 1065 info_element_size);
c5c77ba1
JK
1066 }
1067 }
daaf16ba 1068 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
416d8321 1069 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1070 strWIDList[u32WidsCount].size = sizeof(char);
a4ab1ade 1071 strWIDList[u32WidsCount].val = (s8 *)(&(hif_drv->strWILC_UsrConnReq.u8security));
c5c77ba1
JK
1072 u32WidsCount++;
1073
f7bbd9cf 1074 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1bd9d44c 1075 mode_11i = hif_drv->strWILC_UsrConnReq.u8security;
c5c77ba1 1076
a4ab1ade 1077 PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", hif_drv->strWILC_UsrConnReq.u8security);
c5c77ba1
JK
1078
1079
daaf16ba 1080 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
416d8321 1081 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1082 strWIDList[u32WidsCount].size = sizeof(char);
a4ab1ade 1083 strWIDList[u32WidsCount].val = (s8 *)(&hif_drv->strWILC_UsrConnReq.tenuAuth_type);
c5c77ba1
JK
1084 u32WidsCount++;
1085
f7bbd9cf 1086 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
fba4989e 1087 auth_type = (u8)hif_drv->strWILC_UsrConnReq.tenuAuth_type;
c5c77ba1 1088
a4ab1ade 1089 PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", hif_drv->strWILC_UsrConnReq.tenuAuth_type);
c5c77ba1 1090 PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n",
0d1527e6 1091 hif_drv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->ch);
c5c77ba1 1092
daaf16ba 1093 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
416d8321 1094 strWIDList[u32WidsCount].type = WID_STR;
ae4dfa57 1095 strWIDList[u32WidsCount].size = 112;
900bb4a6 1096 strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
c5c77ba1 1097
f7bbd9cf 1098 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
0626baaa
LK
1099 join_req_size = strWIDList[u32WidsCount].size;
1100 join_req = kmalloc(join_req_size, GFP_KERNEL);
c5c77ba1 1101 }
900bb4a6 1102 if (strWIDList[u32WidsCount].val == NULL) {
31390eec 1103 result = -EFAULT;
24db713f
LK
1104 goto ERRORHANDLER;
1105 }
c5c77ba1 1106
900bb4a6 1107 pu8CurrByte = strWIDList[u32WidsCount].val;
c5c77ba1
JK
1108
1109
f7bbd9cf 1110 if (pstrHostIFconnectAttr->ssid != NULL) {
8b3c9fa6
LK
1111 memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
1112 pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
c5c77ba1
JK
1113 }
1114 pu8CurrByte += MAX_SSID_LEN;
c5c77ba1 1115 *(pu8CurrByte++) = INFRASTRUCTURE;
ae4dfa57 1116
0d1527e6
LK
1117 if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1118 *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
c5c77ba1
JK
1119 } else {
1120 PRINT_ER("Channel out of range\n");
1121 *(pu8CurrByte++) = 0xFF;
1122 }
c5c77ba1
JK
1123 *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF;
1124 *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1125 PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
1126
9254db07
LK
1127 if (pstrHostIFconnectAttr->bssid != NULL)
1128 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
c5c77ba1
JK
1129 pu8CurrByte += 6;
1130
c5c77ba1
JK
1131 *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
1132 *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1133 PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
c5c77ba1
JK
1134 *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
1135 PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1)));
ae4dfa57 1136
d00d2ba3 1137 memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
c5c77ba1
JK
1138 pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1139
c5c77ba1
JK
1140 *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
1141 PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1)));
c5c77ba1
JK
1142 *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
1143
c5c77ba1 1144 *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
a4ab1ade 1145 hif_drv->strWILC_UsrConnReq.IsHTCapable = ptstrJoinBssParam->ht_capable;
c5c77ba1 1146
c5c77ba1
JK
1147 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
1148 PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1));
c5c77ba1
JK
1149 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
1150 PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1)));
c5c77ba1
JK
1151 *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
1152 PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1)));
ae4dfa57 1153
d00d2ba3 1154 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
c5c77ba1
JK
1155 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1156
d00d2ba3 1157 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
c5c77ba1
JK
1158 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1159
d00d2ba3 1160 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
c5c77ba1
JK
1161 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1162
c5c77ba1 1163 *(pu8CurrByte++) = REAL_JOIN_REQ;
7a8d51d7 1164 *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
c5c77ba1 1165
7a8d51d7 1166 if (ptstrJoinBssParam->noa_enabled) {
c5c77ba1
JK
1167 PRINT_D(HOSTINF_DBG, "NOA present\n");
1168
1169 *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1170 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1171 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1172 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1173
d72b33ca 1174 *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
cc179008 1175 *(pu8CurrByte++) = ptstrJoinBssParam->idx;
c5c77ba1 1176
d72b33ca 1177 if (ptstrJoinBssParam->opp_enabled)
99b66945 1178 *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
c5c77ba1 1179
c21047ed 1180 *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
c5c77ba1 1181
109e6cab
LK
1182 memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1183 pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
c5c77ba1 1184
1d8b76b3
LK
1185 memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1186 pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
c5c77ba1 1187
d00d2ba3 1188 memcpy(pu8CurrByte, ptstrJoinBssParam->au8StartTime, sizeof(ptstrJoinBssParam->au8StartTime));
c5c77ba1
JK
1189
1190 pu8CurrByte += sizeof(ptstrJoinBssParam->au8StartTime);
1191
1192 } else
1193 PRINT_D(HOSTINF_DBG, "NOA not present\n");
c5c77ba1 1194
900bb4a6 1195 pu8CurrByte = strWIDList[u32WidsCount].val;
c5c77ba1 1196 u32WidsCount++;
c5c77ba1 1197
f7bbd9cf 1198 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
0626baaa 1199 memcpy(join_req, pu8CurrByte, join_req_size);
870515c1 1200 join_req_drv = hif_drv;
c5c77ba1
JK
1201 }
1202
1203 PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n");
1204
9254db07
LK
1205 if (pstrHostIFconnectAttr->bssid != NULL) {
1206 memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->bssid, ETH_ALEN);
c5c77ba1 1207
9254db07 1208 PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->bssid);
310a28fd 1209 PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID);
c5c77ba1
JK
1210 }
1211
31390eec 1212 result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
8c8360b3 1213 get_id_from_handler(hif_drv));
31390eec 1214 if (result) {
24db713f 1215 PRINT_ER("failed to send config packet\n");
31390eec 1216 result = -EFAULT;
24db713f 1217 goto ERRORHANDLER;
c5c77ba1
JK
1218 } else {
1219 PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n");
a4ab1ade 1220 hif_drv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP;
c5c77ba1 1221 }
c5c77ba1 1222
24db713f 1223ERRORHANDLER:
31390eec 1224 if (result) {
c5c77ba1
JK
1225 tstrConnectInfo strConnectInfo;
1226
a4ab1ade 1227 del_timer(&hif_drv->hConnectTimer);
c5c77ba1
JK
1228
1229 PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n");
1230
2cc46837 1231 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
c5c77ba1 1232
6abcc11d 1233 if (pstrHostIFconnectAttr->result != NULL) {
9254db07
LK
1234 if (pstrHostIFconnectAttr->bssid != NULL)
1235 memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->bssid, 6);
c5c77ba1 1236
2ea158c4 1237 if (pstrHostIFconnectAttr->ies != NULL) {
b59d5c5b
LK
1238 strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->ies_len;
1239 strConnectInfo.pu8ReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
d00d2ba3 1240 memcpy(strConnectInfo.pu8ReqIEs,
8c8360b3
LK
1241 pstrHostIFconnectAttr->ies,
1242 pstrHostIFconnectAttr->ies_len);
c5c77ba1
JK
1243 }
1244
6abcc11d 1245 pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
c5c77ba1
JK
1246 &strConnectInfo,
1247 MAC_DISCONNECTED,
1248 NULL,
8f38db89 1249 pstrHostIFconnectAttr->arg);
a4ab1ade 1250 hif_drv->enuHostIFstate = HOST_IF_IDLE;
95f840fb
SB
1251 kfree(strConnectInfo.pu8ReqIEs);
1252 strConnectInfo.pu8ReqIEs = NULL;
c5c77ba1
JK
1253
1254 } else {
03b2d5e7 1255 PRINT_ER("Connect callback function pointer is NULL\n");
c5c77ba1
JK
1256 }
1257 }
1258
1259 PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n");
95f840fb
SB
1260 kfree(pstrHostIFconnectAttr->bssid);
1261 pstrHostIFconnectAttr->bssid = NULL;
c5c77ba1 1262
95f840fb
SB
1263 kfree(pstrHostIFconnectAttr->ssid);
1264 pstrHostIFconnectAttr->ssid = NULL;
c5c77ba1 1265
95f840fb
SB
1266 kfree(pstrHostIFconnectAttr->ies);
1267 pstrHostIFconnectAttr->ies = NULL;
c5c77ba1 1268
95f840fb 1269 kfree(pu8CurrByte);
31390eec 1270 return result;
c5c77ba1
JK
1271}
1272
a4ab1ade 1273static s32 Handle_FlushConnect(struct host_if_drv *hif_drv)
c5c77ba1 1274{
31390eec 1275 s32 result = 0;
e9e0c260 1276 struct wid strWIDList[5];
4e4467fd 1277 u32 u32WidsCount = 0;
63d03e47 1278 u8 *pu8CurrByte = NULL;
c5c77ba1 1279
daaf16ba 1280 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
416d8321 1281 strWIDList[u32WidsCount].type = WID_BIN_DATA;
48ce2465 1282 strWIDList[u32WidsCount].val = info_element;
dfef7b84 1283 strWIDList[u32WidsCount].size = info_element_size;
c5c77ba1
JK
1284 u32WidsCount++;
1285
daaf16ba 1286 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
416d8321 1287 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1288 strWIDList[u32WidsCount].size = sizeof(char);
1bd9d44c 1289 strWIDList[u32WidsCount].val = (s8 *)(&(mode_11i));
c5c77ba1
JK
1290 u32WidsCount++;
1291
1292
1293
daaf16ba 1294 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
416d8321 1295 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 1296 strWIDList[u32WidsCount].size = sizeof(char);
fba4989e 1297 strWIDList[u32WidsCount].val = (s8 *)(&auth_type);
c5c77ba1
JK
1298 u32WidsCount++;
1299
daaf16ba 1300 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
416d8321 1301 strWIDList[u32WidsCount].type = WID_STR;
0626baaa 1302 strWIDList[u32WidsCount].size = join_req_size;
044a6410 1303 strWIDList[u32WidsCount].val = (s8 *)join_req;
900bb4a6 1304 pu8CurrByte = strWIDList[u32WidsCount].val;
c5c77ba1
JK
1305
1306 pu8CurrByte += FLUSHED_BYTE_POS;
1307 *(pu8CurrByte) = FLUSHED_JOIN_REQ;
1308
1309 u32WidsCount++;
1310
31390eec 1311 result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
8c8360b3 1312 get_id_from_handler(join_req_drv));
31390eec 1313 if (result) {
24db713f 1314 PRINT_ER("failed to send config packet\n");
31390eec 1315 result = -EINVAL;
c5c77ba1
JK
1316 }
1317
31390eec 1318 return result;
c5c77ba1
JK
1319}
1320
a4ab1ade 1321static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv)
c5c77ba1 1322{
31390eec 1323 s32 result = 0;
c5c77ba1 1324 tstrConnectInfo strConnectInfo;
e9e0c260 1325 struct wid strWID;
d85f5326 1326 u16 u16DummyReasonCode = 0;
c5c77ba1 1327
a4ab1ade 1328 if (!hif_drv) {
c5c77ba1 1329 PRINT_ER("Driver handler is NULL\n");
31390eec 1330 return result;
c5c77ba1
JK
1331 }
1332
a4ab1ade 1333 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 1334
ca8540e4 1335 scan_while_connected = false;
c5c77ba1 1336
2cc46837 1337 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
c5c77ba1 1338
a4ab1ade
TC
1339 if (hif_drv->strWILC_UsrConnReq.pfUserConnectResult != NULL) {
1340 if (hif_drv->strWILC_UsrConnReq.pu8bssid != NULL) {
d00d2ba3 1341 memcpy(strConnectInfo.au8bssid,
8c8360b3 1342 hif_drv->strWILC_UsrConnReq.pu8bssid, 6);
c5c77ba1
JK
1343 }
1344
a4ab1ade
TC
1345 if (hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
1346 strConnectInfo.ReqIEsLen = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
1347 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
d00d2ba3 1348 memcpy(strConnectInfo.pu8ReqIEs,
8c8360b3
LK
1349 hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
1350 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen);
c5c77ba1
JK
1351 }
1352
a4ab1ade 1353 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
c5c77ba1
JK
1354 &strConnectInfo,
1355 MAC_DISCONNECTED,
1356 NULL,
a4ab1ade 1357 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1 1358
95f840fb
SB
1359 kfree(strConnectInfo.pu8ReqIEs);
1360 strConnectInfo.pu8ReqIEs = NULL;
c5c77ba1 1361 } else {
03b2d5e7 1362 PRINT_ER("Connect callback function pointer is NULL\n");
c5c77ba1
JK
1363 }
1364
daaf16ba 1365 strWID.id = (u16)WID_DISCONNECT;
416d8321 1366 strWID.type = WID_CHAR;
900bb4a6 1367 strWID.val = (s8 *)&u16DummyReasonCode;
2fd3e443 1368 strWID.size = sizeof(char);
c5c77ba1
JK
1369
1370 PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1371
31390eec 1372 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 1373 get_id_from_handler(hif_drv));
31390eec 1374 if (result)
c5c77ba1 1375 PRINT_ER("Failed to send dissconect config packet\n");
c5c77ba1 1376
a4ab1ade
TC
1377 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
1378 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
1379 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
1380 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
1381 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 1382
281dd5ac 1383 eth_zero_addr(u8ConnectedSSID);
ae4dfa57 1384
870515c1 1385 if (join_req != NULL && join_req_drv == hif_drv) {
044a6410
LK
1386 kfree(join_req);
1387 join_req = NULL;
c5c77ba1 1388 }
48ce2465 1389
870515c1 1390 if (info_element != NULL && join_req_drv == hif_drv) {
48ce2465
LK
1391 kfree(info_element);
1392 info_element = NULL;
c5c77ba1
JK
1393 }
1394
31390eec 1395 return result;
c5c77ba1
JK
1396}
1397
a4ab1ade 1398static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv,
3bbd59f5 1399 struct rcvd_net_info *pstrRcvdNetworkInfo)
c5c77ba1 1400{
4e4467fd 1401 u32 i;
72ed4dc7 1402 bool bNewNtwrkFound;
31390eec 1403 s32 result = 0;
c5c77ba1
JK
1404 tstrNetworkInfo *pstrNetworkInfo = NULL;
1405 void *pJoinParams = NULL;
1406
72ed4dc7 1407 bNewNtwrkFound = true;
c5c77ba1
JK
1408 PRINT_INFO(HOSTINF_DBG, "Handling received network info\n");
1409
a4ab1ade 1410 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
c5c77ba1 1411 PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n");
b021b80b 1412 parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
c5c77ba1 1413 if ((pstrNetworkInfo == NULL)
a4ab1ade 1414 || (hif_drv->strWILC_UsrScanReq.pfUserScanResult == NULL)) {
24db713f 1415 PRINT_ER("driver is null\n");
31390eec 1416 result = -EINVAL;
24db713f 1417 goto done;
c5c77ba1
JK
1418 }
1419
a4ab1ade 1420 for (i = 0; i < hif_drv->strWILC_UsrScanReq.u32RcvdChCount; i++) {
c5c77ba1 1421
a4ab1ade 1422 if ((hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid != NULL) &&
c5c77ba1 1423 (pstrNetworkInfo->au8bssid != NULL)) {
a4ab1ade 1424 if (memcmp(hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid,
8c8360b3 1425 pstrNetworkInfo->au8bssid, 6) == 0) {
a4ab1ade 1426 if (pstrNetworkInfo->s8rssi <= hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi) {
c5c77ba1
JK
1427 PRINT_D(HOSTINF_DBG, "Network previously discovered\n");
1428 goto done;
1429 } else {
a4ab1ade 1430 hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi;
72ed4dc7 1431 bNewNtwrkFound = false;
c5c77ba1
JK
1432 break;
1433 }
1434 }
1435 }
1436 }
1437
72ed4dc7 1438 if (bNewNtwrkFound == true) {
c5c77ba1
JK
1439 PRINT_D(HOSTINF_DBG, "New network found\n");
1440
a4ab1ade
TC
1441 if (hif_drv->strWILC_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
1442 hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[hif_drv->strWILC_UsrScanReq.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi;
c5c77ba1 1443
a4ab1ade 1444 if ((hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[hif_drv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid != NULL)
c5c77ba1 1445 && (pstrNetworkInfo->au8bssid != NULL)) {
a4ab1ade 1446 memcpy(hif_drv->strWILC_UsrScanReq.astrFoundNetworkInfo[hif_drv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid,
8c8360b3 1447 pstrNetworkInfo->au8bssid, 6);
c5c77ba1 1448
a4ab1ade 1449 hif_drv->strWILC_UsrScanReq.u32RcvdChCount++;
c5c77ba1 1450
72ed4dc7 1451 pstrNetworkInfo->bNewNetwork = true;
c5c77ba1 1452 pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
c5c77ba1 1453
a4ab1ade
TC
1454 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1455 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid,
c5c77ba1
JK
1456 pJoinParams);
1457
1458
1459 }
1460 } else {
03b2d5e7 1461 PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit\n");
c5c77ba1
JK
1462 }
1463 } else {
72ed4dc7 1464 pstrNetworkInfo->bNewNetwork = false;
a4ab1ade
TC
1465 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1466 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
c5c77ba1
JK
1467 }
1468 }
1469
c5c77ba1 1470done:
95f840fb
SB
1471 kfree(pstrRcvdNetworkInfo->buffer);
1472 pstrRcvdNetworkInfo->buffer = NULL;
c5c77ba1 1473
b1413b60 1474 if (pstrNetworkInfo != NULL) {
c5c77ba1 1475 DeallocateNetworkInfo(pstrNetworkInfo);
b1413b60 1476 pstrNetworkInfo = NULL;
c5c77ba1
JK
1477 }
1478
31390eec 1479 return result;
c5c77ba1
JK
1480}
1481
a4ab1ade 1482static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
f23a9eab 1483 struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
c5c77ba1 1484{
31390eec 1485 s32 result = 0;
63d03e47
GKH
1486 u8 u8MsgType = 0;
1487 u8 u8MsgID = 0;
d85f5326
CL
1488 u16 u16MsgLen = 0;
1489 u16 u16WidID = (u16)WID_NIL;
63d03e47
GKH
1490 u8 u8WidLen = 0;
1491 u8 u8MacStatus;
1492 u8 u8MacStatusReasonCode;
1493 u8 u8MacStatusAdditionalInfo;
c5c77ba1
JK
1494 tstrConnectInfo strConnectInfo;
1495 tstrDisconnectNotifInfo strDisconnectNotifInfo;
e6e12661 1496 s32 s32Err = 0;
78c87591 1497
a4ab1ade 1498 if (!hif_drv) {
c5c77ba1 1499 PRINT_ER("Driver handler is NULL\n");
234837de
LK
1500 return -ENODEV;
1501 }
a4ab1ade 1502 PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", hif_drv->enuHostIFstate,
33722ac7 1503 pstrRcvdGnrlAsyncInfo->buffer[7]);
c5c77ba1 1504
a4ab1ade
TC
1505 if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) ||
1506 (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) ||
1507 hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
33722ac7 1508 if ((pstrRcvdGnrlAsyncInfo->buffer == NULL) ||
a4ab1ade 1509 (hif_drv->strWILC_UsrConnReq.pfUserConnectResult == NULL)) {
24db713f
LK
1510 PRINT_ER("driver is null\n");
1511 return -EINVAL;
c5c77ba1
JK
1512 }
1513
33722ac7 1514 u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
c5c77ba1 1515
c5c77ba1
JK
1516 if ('I' != u8MsgType) {
1517 PRINT_ER("Received Message format incorrect.\n");
24db713f 1518 return -EFAULT;
c5c77ba1
JK
1519 }
1520
33722ac7
LK
1521 u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
1522 u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
1523 u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
1524 u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
1525 u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7];
1526 u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
1527 u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
c5c77ba1 1528 PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
a4ab1ade 1529 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
4e4467fd 1530 u32 u32RcvdAssocRespInfoLen;
c5c77ba1
JK
1531 tstrConnectRespInfo *pstrConnectRespInfo = NULL;
1532
1533 PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
1534
2cc46837 1535 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
c5c77ba1
JK
1536
1537 if (u8MacStatus == MAC_CONNECTED) {
a633c0b5 1538 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
c5c77ba1 1539
a4ab1ade 1540 host_int_get_assoc_res_info(hif_drv,
a633c0b5 1541 rcv_assoc_resp,
c5c77ba1
JK
1542 MAX_ASSOC_RESP_FRAME_SIZE,
1543 &u32RcvdAssocRespInfoLen);
1544
1545 PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen);
1546
1547 if (u32RcvdAssocRespInfoLen != 0) {
1548
1549 PRINT_D(HOSTINF_DBG, "Parsing association response\n");
a633c0b5 1550 s32Err = ParseAssocRespInfo(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
c5c77ba1
JK
1551 &pstrConnectRespInfo);
1552 if (s32Err) {
03b2d5e7 1553 PRINT_ER("ParseAssocRespInfo() returned error %d\n", s32Err);
c5c77ba1 1554 } else {
c5c77ba1
JK
1555 strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus;
1556
1557 if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
1558 PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n");
1559 if (pstrConnectRespInfo->pu8RespIEs != NULL) {
1560 strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen;
1561
1562
f3052587 1563 strConnectInfo.pu8RespIEs = kmalloc(pstrConnectRespInfo->u16RespIEsLen, GFP_KERNEL);
d00d2ba3 1564 memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs,
c5c77ba1
JK
1565 pstrConnectRespInfo->u16RespIEsLen);
1566 }
1567 }
1568
c5c77ba1
JK
1569 if (pstrConnectRespInfo != NULL) {
1570 DeallocateAssocRespInfo(pstrConnectRespInfo);
1571 pstrConnectRespInfo = NULL;
1572 }
1573 }
1574 }
1575 }
1576
c5c77ba1
JK
1577 if ((u8MacStatus == MAC_CONNECTED) &&
1578 (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) {
03b2d5e7 1579 PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
281dd5ac 1580 eth_zero_addr(u8ConnectedSSID);
c5c77ba1
JK
1581
1582 } else if (u8MacStatus == MAC_DISCONNECTED) {
1583 PRINT_ER("Received MAC status is MAC_DISCONNECTED\n");
281dd5ac 1584 eth_zero_addr(u8ConnectedSSID);
c5c77ba1
JK
1585 }
1586
a4ab1ade 1587 if (hif_drv->strWILC_UsrConnReq.pu8bssid != NULL) {
c5c77ba1 1588 PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n");
a4ab1ade 1589 memcpy(strConnectInfo.au8bssid, hif_drv->strWILC_UsrConnReq.pu8bssid, 6);
c5c77ba1
JK
1590
1591 if ((u8MacStatus == MAC_CONNECTED) &&
1592 (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
a4ab1ade
TC
1593 memcpy(hif_drv->au8AssociatedBSSID,
1594 hif_drv->strWILC_UsrConnReq.pu8bssid, ETH_ALEN);
c5c77ba1
JK
1595 }
1596 }
1597
1598
a4ab1ade
TC
1599 if (hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
1600 strConnectInfo.ReqIEsLen = hif_drv->strWILC_UsrConnReq.ConnReqIEsLen;
1601 strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
d00d2ba3 1602 memcpy(strConnectInfo.pu8ReqIEs,
a4ab1ade
TC
1603 hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs,
1604 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen);
c5c77ba1
JK
1605 }
1606
1607
a4ab1ade
TC
1608 del_timer(&hif_drv->hConnectTimer);
1609 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
c5c77ba1
JK
1610 &strConnectInfo,
1611 u8MacStatus,
1612 NULL,
a4ab1ade 1613 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1 1614
c5c77ba1
JK
1615 if ((u8MacStatus == MAC_CONNECTED) &&
1616 (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
a4ab1ade 1617 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1
JK
1618
1619 PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n");
a4ab1ade 1620 hif_drv->enuHostIFstate = HOST_IF_CONNECTED;
c5c77ba1 1621
c5c77ba1 1622 PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n");
72ed4dc7 1623 g_obtainingIP = true;
9eb06643
GKH
1624 mod_timer(&hDuringIpTimer,
1625 jiffies + msecs_to_jiffies(10000));
c5c77ba1
JK
1626 } else {
1627 PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus);
a4ab1ade 1628 hif_drv->enuHostIFstate = HOST_IF_IDLE;
ca8540e4 1629 scan_while_connected = false;
c5c77ba1
JK
1630 }
1631
95f840fb
SB
1632 kfree(strConnectInfo.pu8RespIEs);
1633 strConnectInfo.pu8RespIEs = NULL;
c5c77ba1 1634
95f840fb
SB
1635 kfree(strConnectInfo.pu8ReqIEs);
1636 strConnectInfo.pu8ReqIEs = NULL;
a4ab1ade
TC
1637 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
1638 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
1639 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
1640 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
1641 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 1642 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
a4ab1ade 1643 (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)) {
c5c77ba1
JK
1644 PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n");
1645
2cc46837 1646 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
c5c77ba1 1647
a4ab1ade 1648 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
03b2d5e7 1649 PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n");
a4ab1ade
TC
1650 del_timer(&hif_drv->hScanTimer);
1651 Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED);
c5c77ba1
JK
1652 }
1653
1654 strDisconnectNotifInfo.u16reason = 0;
1655 strDisconnectNotifInfo.ie = NULL;
1656 strDisconnectNotifInfo.ie_len = 0;
1657
a4ab1ade 1658 if (hif_drv->strWILC_UsrConnReq.pfUserConnectResult != NULL) {
72ed4dc7 1659 g_obtainingIP = false;
a4ab1ade 1660 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1 1661
a4ab1ade 1662 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF,
c5c77ba1
JK
1663 NULL,
1664 0,
1665 &strDisconnectNotifInfo,
a4ab1ade 1666 hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1
JK
1667
1668 } else {
03b2d5e7 1669 PRINT_ER("Connect result callback function is NULL\n");
c5c77ba1
JK
1670 }
1671
a4ab1ade 1672 eth_zero_addr(hif_drv->au8AssociatedBSSID);
c5c77ba1 1673
a4ab1ade
TC
1674 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
1675 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
1676 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
1677 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
1678 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 1679
870515c1 1680 if (join_req != NULL && join_req_drv == hif_drv) {
044a6410
LK
1681 kfree(join_req);
1682 join_req = NULL;
c5c77ba1 1683 }
48ce2465 1684
870515c1 1685 if (info_element != NULL && join_req_drv == hif_drv) {
48ce2465
LK
1686 kfree(info_element);
1687 info_element = NULL;
c5c77ba1
JK
1688 }
1689
a4ab1ade 1690 hif_drv->enuHostIFstate = HOST_IF_IDLE;
ca8540e4 1691 scan_while_connected = false;
c5c77ba1
JK
1692
1693 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
a4ab1ade 1694 (hif_drv->strWILC_UsrScanReq.pfUserScanResult != NULL)) {
c5c77ba1 1695 PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n");
03b2d5e7 1696 PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n");
ae4dfa57 1697
a4ab1ade
TC
1698 del_timer(&hif_drv->hScanTimer);
1699 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult)
1700 Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
c5c77ba1 1701
c5c77ba1
JK
1702 }
1703
1704 }
1705
95f840fb
SB
1706 kfree(pstrRcvdGnrlAsyncInfo->buffer);
1707 pstrRcvdGnrlAsyncInfo->buffer = NULL;
c5c77ba1 1708
31390eec 1709 return result;
c5c77ba1
JK
1710}
1711
a4ab1ade 1712static int Handle_Key(struct host_if_drv *hif_drv,
c98387a5 1713 struct key_attr *pstrHostIFkeyAttr)
c5c77ba1 1714{
31390eec 1715 s32 result = 0;
e9e0c260
LK
1716 struct wid strWID;
1717 struct wid strWIDList[5];
63d03e47
GKH
1718 u8 i;
1719 u8 *pu8keybuf;
ca356ada
CL
1720 s8 s8idxarray[1];
1721 s8 ret = 0;
c5c77ba1 1722
8e9f427a 1723 switch (pstrHostIFkeyAttr->type) {
c5c77ba1
JK
1724
1725
1726 case WEP:
1727
0d17e382 1728 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
c5c77ba1
JK
1729
1730 PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
73b2e381 1731 PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", (pstrHostIFkeyAttr->attr.wep.index));
daaf16ba 1732 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1733 strWIDList[0].type = WID_CHAR;
2fd3e443 1734 strWIDList[0].size = sizeof(char);
73b2e381 1735 strWIDList[0].val = (s8 *)(&(pstrHostIFkeyAttr->attr.wep.mode));
c5c77ba1 1736
daaf16ba 1737 strWIDList[1].id = WID_AUTH_TYPE;
416d8321 1738 strWIDList[1].type = WID_CHAR;
2fd3e443 1739 strWIDList[1].size = sizeof(char);
73b2e381 1740 strWIDList[1].val = (s8 *)(&(pstrHostIFkeyAttr->attr.wep.auth_type));
c5c77ba1 1741
daaf16ba 1742 strWIDList[2].id = (u16)WID_KEY_ID;
416d8321 1743 strWIDList[2].type = WID_CHAR;
c5c77ba1 1744
73b2e381 1745 strWIDList[2].val = (s8 *)(&(pstrHostIFkeyAttr->attr.wep.index));
2fd3e443 1746 strWIDList[2].size = sizeof(char);
c5c77ba1 1747
543f5b13
SB
1748 pu8keybuf = kmemdup(pstrHostIFkeyAttr->attr.wep.key,
1749 pstrHostIFkeyAttr->attr.wep.key_len,
1750 GFP_KERNEL);
c5c77ba1
JK
1751
1752 if (pu8keybuf == NULL) {
1753 PRINT_ER("No buffer to send Key\n");
1754 return -1;
1755 }
1756
73b2e381 1757 kfree(pstrHostIFkeyAttr->attr.wep.key);
c5c77ba1 1758
daaf16ba 1759 strWIDList[3].id = (u16)WID_WEP_KEY_VALUE;
416d8321 1760 strWIDList[3].type = WID_STR;
73b2e381 1761 strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len;
900bb4a6 1762 strWIDList[3].val = (s8 *)pu8keybuf;
c5c77ba1 1763
31390eec 1764 result = send_config_pkt(SET_CFG, strWIDList, 4,
8c8360b3 1765 get_id_from_handler(hif_drv));
49188af2 1766 kfree(pu8keybuf);
c5c77ba1
JK
1767
1768
1769 }
c5c77ba1 1770
0d17e382 1771 if (pstrHostIFkeyAttr->action & ADDKEY) {
c5c77ba1 1772 PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
73b2e381 1773 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
c5c77ba1
JK
1774 if (pu8keybuf == NULL) {
1775 PRINT_ER("No buffer to send Key\n");
1776 return -1;
1777 }
73b2e381
LK
1778 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1779 memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1780 memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
8c8360b3 1781 pstrHostIFkeyAttr->attr.wep.key_len);
73b2e381 1782 kfree(pstrHostIFkeyAttr->attr.wep.key);
c5c77ba1 1783
daaf16ba 1784 strWID.id = (u16)WID_ADD_WEP_KEY;
416d8321 1785 strWID.type = WID_STR;
900bb4a6 1786 strWID.val = (s8 *)pu8keybuf;
73b2e381 1787 strWID.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
c5c77ba1 1788
31390eec 1789 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 1790 get_id_from_handler(hif_drv));
49188af2 1791 kfree(pu8keybuf);
0d17e382 1792 } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
c5c77ba1
JK
1793
1794 PRINT_D(HOSTINF_DBG, "Removing key\n");
daaf16ba 1795 strWID.id = (u16)WID_REMOVE_WEP_KEY;
416d8321 1796 strWID.type = WID_STR;
c5c77ba1 1797
73b2e381 1798 s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
900bb4a6 1799 strWID.val = s8idxarray;
2fd3e443 1800 strWID.size = 1;
c5c77ba1 1801
31390eec 1802 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 1803 get_id_from_handler(hif_drv));
c5c77ba1 1804 } else {
daaf16ba 1805 strWID.id = (u16)WID_KEY_ID;
416d8321 1806 strWID.type = WID_CHAR;
73b2e381 1807 strWID.val = (s8 *)(&(pstrHostIFkeyAttr->attr.wep.index));
2fd3e443 1808 strWID.size = sizeof(char);
c5c77ba1
JK
1809
1810 PRINT_D(HOSTINF_DBG, "Setting default key index\n");
1811
31390eec 1812 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 1813 get_id_from_handler(hif_drv));
c5c77ba1 1814 }
a4ab1ade 1815 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1816 break;
1817
1818 case WPARxGtk:
0d17e382 1819 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
b156f1ed 1820 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
c5c77ba1
JK
1821 if (pu8keybuf == NULL) {
1822 PRINT_ER("No buffer to send RxGTK Key\n");
1823 ret = -1;
1824 goto _WPARxGtk_end_case_;
1825 }
1826
0e74c009
LK
1827 if (pstrHostIFkeyAttr->attr.wpa.seq != NULL)
1828 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
c5c77ba1 1829
e2dfbac5 1830 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1831 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1832 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1833 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1834
daaf16ba 1835 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1836 strWIDList[0].type = WID_CHAR;
2fd3e443 1837 strWIDList[0].size = sizeof(char);
7b2ebb28 1838 strWIDList[0].val = (s8 *)(&(pstrHostIFkeyAttr->attr.wpa.mode));
c5c77ba1 1839
daaf16ba 1840 strWIDList[1].id = (u16)WID_ADD_RX_GTK;
416d8321 1841 strWIDList[1].type = WID_STR;
900bb4a6 1842 strWIDList[1].val = (s8 *)pu8keybuf;
2fd3e443 1843 strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
c5c77ba1 1844
31390eec 1845 result = send_config_pkt(SET_CFG, strWIDList, 2,
8c8360b3 1846 get_id_from_handler(hif_drv));
c5c77ba1 1847
49188af2 1848 kfree(pu8keybuf);
a4ab1ade 1849 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1850 }
1851
0d17e382 1852 if (pstrHostIFkeyAttr->action & ADDKEY) {
c5c77ba1
JK
1853 PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
1854
b156f1ed 1855 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
c5c77ba1
JK
1856 if (pu8keybuf == NULL) {
1857 PRINT_ER("No buffer to send RxGTK Key\n");
1858 ret = -1;
1859 goto _WPARxGtk_end_case_;
1860 }
1861
a4ab1ade
TC
1862 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
1863 memcpy(pu8keybuf, hif_drv->au8AssociatedBSSID, ETH_ALEN);
78174ada 1864 else
03b2d5e7 1865 PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED\n");
c5c77ba1 1866
0e74c009 1867 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
e2dfbac5 1868 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1869 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1870 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1871 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1872
daaf16ba 1873 strWID.id = (u16)WID_ADD_RX_GTK;
416d8321 1874 strWID.type = WID_STR;
900bb4a6 1875 strWID.val = (s8 *)pu8keybuf;
2fd3e443 1876 strWID.size = RX_MIC_KEY_MSG_LEN;
c5c77ba1 1877
31390eec 1878 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 1879 get_id_from_handler(hif_drv));
c5c77ba1 1880
49188af2 1881 kfree(pu8keybuf);
a4ab1ade 1882 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1883 }
1884_WPARxGtk_end_case_:
124968fc 1885 kfree(pstrHostIFkeyAttr->attr.wpa.key);
0e74c009 1886 kfree(pstrHostIFkeyAttr->attr.wpa.seq);
c5c77ba1
JK
1887 if (ret == -1)
1888 return ret;
1889
1890 break;
1891
1892 case WPAPtk:
0d17e382 1893 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
c5c77ba1
JK
1894
1895
f3052587 1896 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
c5c77ba1
JK
1897
1898
1899
1900 if (pu8keybuf == NULL) {
1901 PRINT_ER("No buffer to send PTK Key\n");
1902 ret = -1;
1903 goto _WPAPtk_end_case_;
1904
1905 }
1906
248080aa 1907 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
e2dfbac5 1908 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
6acf2919 1909 memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1910 memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1911 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1912
daaf16ba 1913 strWIDList[0].id = (u16)WID_11I_MODE;
416d8321 1914 strWIDList[0].type = WID_CHAR;
2fd3e443 1915 strWIDList[0].size = sizeof(char);
7b2ebb28 1916 strWIDList[0].val = (s8 *)(&(pstrHostIFkeyAttr->attr.wpa.mode));
c5c77ba1 1917
daaf16ba 1918 strWIDList[1].id = (u16)WID_ADD_PTK;
416d8321 1919 strWIDList[1].type = WID_STR;
900bb4a6 1920 strWIDList[1].val = (s8 *)pu8keybuf;
2fd3e443 1921 strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
c5c77ba1 1922
31390eec 1923 result = send_config_pkt(SET_CFG, strWIDList, 2,
8c8360b3 1924 get_id_from_handler(hif_drv));
49188af2 1925 kfree(pu8keybuf);
a4ab1ade 1926 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1 1927 }
0d17e382 1928 if (pstrHostIFkeyAttr->action & ADDKEY) {
c5c77ba1
JK
1929
1930
f3052587 1931 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
c5c77ba1
JK
1932
1933
1934
1935 if (pu8keybuf == NULL) {
1936 PRINT_ER("No buffer to send PTK Key\n");
1937 ret = -1;
1938 goto _WPAPtk_end_case_;
1939
1940 }
1941
248080aa 1942 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
6acf2919 1943 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
124968fc 1944 memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
8c8360b3 1945 pstrHostIFkeyAttr->attr.wpa.key_len);
c5c77ba1 1946
daaf16ba 1947 strWID.id = (u16)WID_ADD_PTK;
416d8321 1948 strWID.type = WID_STR;
900bb4a6 1949 strWID.val = (s8 *)pu8keybuf;
2fd3e443 1950 strWID.size = PTK_KEY_MSG_LEN;
c5c77ba1 1951
31390eec 1952 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 1953 get_id_from_handler(hif_drv));
49188af2 1954 kfree(pu8keybuf);
a4ab1ade 1955 up(&hif_drv->hSemTestKeyBlock);
c5c77ba1
JK
1956 }
1957
1958_WPAPtk_end_case_:
124968fc 1959 kfree(pstrHostIFkeyAttr->attr.wpa.key);
c5c77ba1
JK
1960 if (ret == -1)
1961 return ret;
1962
1963 break;
1964
1965
1966 case PMKSA:
1967
1968 PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n");
1969
73b2e381 1970 pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
c5c77ba1
JK
1971 if (pu8keybuf == NULL) {
1972 PRINT_ER("No buffer to send PMKSA Key\n");
1973 return -1;
1974 }
1975
73b2e381 1976 pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
c5c77ba1 1977
73b2e381
LK
1978 for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1979 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1980 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
c5c77ba1
JK
1981 }
1982
daaf16ba 1983 strWID.id = (u16)WID_PMKID_INFO;
416d8321 1984 strWID.type = WID_STR;
900bb4a6 1985 strWID.val = (s8 *)pu8keybuf;
73b2e381 1986 strWID.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
c5c77ba1 1987
31390eec 1988 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 1989 get_id_from_handler(hif_drv));
c5c77ba1 1990
49188af2 1991 kfree(pu8keybuf);
c5c77ba1
JK
1992 break;
1993 }
1994
31390eec 1995 if (result)
c5c77ba1
JK
1996 PRINT_ER("Failed to send key config packet\n");
1997
31390eec 1998 return result;
c5c77ba1
JK
1999}
2000
a4ab1ade 2001static void Handle_Disconnect(struct host_if_drv *hif_drv)
c5c77ba1 2002{
e9e0c260 2003 struct wid strWID;
c5c77ba1 2004
31390eec 2005 s32 result = 0;
d85f5326 2006 u16 u16DummyReasonCode = 0;
c5c77ba1 2007
daaf16ba 2008 strWID.id = (u16)WID_DISCONNECT;
416d8321 2009 strWID.type = WID_CHAR;
900bb4a6 2010 strWID.val = (s8 *)&u16DummyReasonCode;
2fd3e443 2011 strWID.size = sizeof(char);
c5c77ba1
JK
2012
2013
2014
2015 PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
2016
72ed4dc7 2017 g_obtainingIP = false;
a4ab1ade 2018 host_int_set_power_mgmt(hif_drv, 0, 0);
c5c77ba1 2019
281dd5ac 2020 eth_zero_addr(u8ConnectedSSID);
c5c77ba1 2021
31390eec 2022 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2023 get_id_from_handler(hif_drv));
c5c77ba1 2024
31390eec 2025 if (result) {
c5c77ba1 2026 PRINT_ER("Failed to send dissconect config packet\n");
c5c77ba1
JK
2027 } else {
2028 tstrDisconnectNotifInfo strDisconnectNotifInfo;
2029
2cc46837 2030 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
c5c77ba1
JK
2031
2032 strDisconnectNotifInfo.u16reason = 0;
2033 strDisconnectNotifInfo.ie = NULL;
2034 strDisconnectNotifInfo.ie_len = 0;
2035
a4ab1ade
TC
2036 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
2037 del_timer(&hif_drv->hScanTimer);
2038 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
2039 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
c5c77ba1 2040
a4ab1ade 2041 hif_drv->strWILC_UsrScanReq.pfUserScanResult = NULL;
c5c77ba1
JK
2042 }
2043
a4ab1ade 2044 if (hif_drv->strWILC_UsrConnReq.pfUserConnectResult != NULL) {
a4ab1ade 2045 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
c5c77ba1 2046 PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n");
a4ab1ade 2047 del_timer(&hif_drv->hConnectTimer);
c5c77ba1
JK
2048 }
2049
a4ab1ade
TC
2050 hif_drv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
2051 0, &strDisconnectNotifInfo, hif_drv->strWILC_UsrConnReq.u32UserConnectPvoid);
c5c77ba1 2052 } else {
03b2d5e7 2053 PRINT_ER("strWILC_UsrConnReq.pfUserConnectResult = NULL\n");
c5c77ba1
JK
2054 }
2055
ca8540e4 2056 scan_while_connected = false;
c5c77ba1 2057
a4ab1ade 2058 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 2059
a4ab1ade 2060 eth_zero_addr(hif_drv->au8AssociatedBSSID);
c5c77ba1 2061
a4ab1ade
TC
2062 hif_drv->strWILC_UsrConnReq.ssidLen = 0;
2063 kfree(hif_drv->strWILC_UsrConnReq.pu8ssid);
2064 kfree(hif_drv->strWILC_UsrConnReq.pu8bssid);
2065 hif_drv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
2066 kfree(hif_drv->strWILC_UsrConnReq.pu8ConnReqIEs);
c5c77ba1 2067
870515c1 2068 if (join_req != NULL && join_req_drv == hif_drv) {
044a6410
LK
2069 kfree(join_req);
2070 join_req = NULL;
c5c77ba1 2071 }
48ce2465 2072
870515c1 2073 if (info_element != NULL && join_req_drv == hif_drv) {
48ce2465
LK
2074 kfree(info_element);
2075 info_element = NULL;
c5c77ba1
JK
2076 }
2077
2078 }
2079
a4ab1ade 2080 up(&hif_drv->hSemTestDisconnectBlock);
c5c77ba1
JK
2081}
2082
2083
a4ab1ade 2084void resolve_disconnect_aberration(struct host_if_drv *hif_drv)
c5c77ba1 2085{
a4ab1ade 2086 if (!hif_drv)
c5c77ba1 2087 return;
a4ab1ade 2088 if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (hif_drv->enuHostIFstate == HOST_IF_CONNECTING)) {
c5c77ba1 2089 PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n");
a4ab1ade 2090 host_int_disconnect(hif_drv, 1);
c5c77ba1
JK
2091 }
2092}
c5c77ba1 2093
a4ab1ade 2094static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
c5c77ba1 2095{
31390eec 2096 s32 result = 0;
e9e0c260 2097 struct wid strWID;
78c87591 2098
daaf16ba 2099 strWID.id = (u16)WID_CURRENT_CHANNEL;
416d8321 2100 strWID.type = WID_CHAR;
95ebb0ff 2101 strWID.val = (s8 *)&ch_no;
2fd3e443 2102 strWID.size = sizeof(char);
c5c77ba1
JK
2103
2104 PRINT_D(HOSTINF_DBG, "Getting channel value\n");
2105
31390eec 2106 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 2107 get_id_from_handler(hif_drv));
ae4dfa57 2108
31390eec 2109 if (result) {
c5c77ba1 2110 PRINT_ER("Failed to get channel number\n");
31390eec 2111 result = -EFAULT;
c5c77ba1
JK
2112 }
2113
a4ab1ade 2114 up(&hif_drv->hSemGetCHNL);
c5c77ba1 2115
31390eec 2116 return result;
c5c77ba1
JK
2117}
2118
a4ab1ade 2119static void Handle_GetRssi(struct host_if_drv *hif_drv)
c5c77ba1 2120{
31390eec 2121 s32 result = 0;
e9e0c260 2122 struct wid strWID;
c5c77ba1 2123
daaf16ba 2124 strWID.id = (u16)WID_RSSI;
416d8321 2125 strWID.type = WID_CHAR;
144b7b23 2126 strWID.val = &rssi;
2fd3e443 2127 strWID.size = sizeof(char);
c5c77ba1 2128
c5c77ba1
JK
2129 PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
2130
31390eec 2131 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 2132 get_id_from_handler(hif_drv));
31390eec 2133 if (result) {
c5c77ba1 2134 PRINT_ER("Failed to get RSSI value\n");
31390eec 2135 result = -EFAULT;
c5c77ba1
JK
2136 }
2137
a4ab1ade 2138 up(&hif_drv->hSemGetRSSI);
c5c77ba1
JK
2139
2140
2141}
2142
2143
a4ab1ade 2144static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
c5c77ba1 2145{
31390eec 2146 s32 result = 0;
e9e0c260 2147 struct wid strWID;
c5c77ba1 2148
75327a02 2149 link_speed = 0;
c5c77ba1 2150
daaf16ba 2151 strWID.id = (u16)WID_LINKSPEED;
416d8321 2152 strWID.type = WID_CHAR;
75327a02 2153 strWID.val = &link_speed;
2fd3e443 2154 strWID.size = sizeof(char);
ae4dfa57 2155
c5c77ba1
JK
2156 PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
2157
31390eec 2158 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 2159 get_id_from_handler(hif_drv));
31390eec 2160 if (result) {
c5c77ba1 2161 PRINT_ER("Failed to get LINKSPEED value\n");
31390eec 2162 result = -EFAULT;
c5c77ba1
JK
2163 }
2164
a4ab1ade 2165 up(&(hif_drv->hSemGetLINKSPEED));
c5c77ba1
JK
2166
2167
2168}
2169
a4ab1ade 2170s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
c5c77ba1 2171{
e9e0c260 2172 struct wid strWIDList[5];
31390eec 2173 u32 u32WidsCount = 0, result = 0;
c5c77ba1 2174
daaf16ba 2175 strWIDList[u32WidsCount].id = WID_LINKSPEED;
416d8321 2176 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 2177 strWIDList[u32WidsCount].size = sizeof(char);
900bb4a6 2178 strWIDList[u32WidsCount].val = (s8 *)(&(pstrStatistics->u8LinkSpeed));
c5c77ba1
JK
2179 u32WidsCount++;
2180
daaf16ba 2181 strWIDList[u32WidsCount].id = WID_RSSI;
416d8321 2182 strWIDList[u32WidsCount].type = WID_CHAR;
2fd3e443 2183 strWIDList[u32WidsCount].size = sizeof(char);
900bb4a6 2184 strWIDList[u32WidsCount].val = (s8 *)(&(pstrStatistics->s8RSSI));
c5c77ba1
JK
2185 u32WidsCount++;
2186
daaf16ba 2187 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
416d8321 2188 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2189 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 2190 strWIDList[u32WidsCount].val = (s8 *)(&(pstrStatistics->u32TxCount));
c5c77ba1
JK
2191 u32WidsCount++;
2192
daaf16ba 2193 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
416d8321 2194 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2195 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 2196 strWIDList[u32WidsCount].val = (s8 *)(&(pstrStatistics->u32RxCount));
c5c77ba1
JK
2197 u32WidsCount++;
2198
daaf16ba 2199 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
416d8321 2200 strWIDList[u32WidsCount].type = WID_INT;
2fd3e443 2201 strWIDList[u32WidsCount].size = sizeof(u32);
900bb4a6 2202 strWIDList[u32WidsCount].val = (s8 *)(&(pstrStatistics->u32TxFailureCount));
c5c77ba1
JK
2203 u32WidsCount++;
2204
31390eec 2205 result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount,
8c8360b3 2206 get_id_from_handler(hif_drv));
c5c77ba1 2207
31390eec 2208 if (result)
c5c77ba1 2209 PRINT_ER("Failed to send scan paramters config packet\n");
24db713f 2210
2d25af87 2211 up(&hif_sema_wait_response);
c5c77ba1
JK
2212 return 0;
2213
2214}
2215
a4ab1ade 2216static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
3d1eac04 2217 struct sta_inactive_t *strHostIfStaInactiveT)
c5c77ba1 2218{
31390eec 2219 s32 result = 0;
63d03e47 2220 u8 *stamac;
e9e0c260 2221 struct wid strWID;
c5c77ba1 2222
daaf16ba 2223 strWID.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
416d8321 2224 strWID.type = WID_STR;
2fd3e443 2225 strWID.size = ETH_ALEN;
900bb4a6 2226 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
c5c77ba1
JK
2227
2228
900bb4a6 2229 stamac = strWID.val;
d00d2ba3 2230 memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
c5c77ba1
JK
2231
2232
2233 PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
2234
31390eec 2235 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2236 get_id_from_handler(hif_drv));
ae4dfa57 2237
31390eec 2238 if (result) {
c5c77ba1 2239 PRINT_ER("Failed to SET incative time\n");
24db713f 2240 return -EFAULT;
c5c77ba1
JK
2241 }
2242
2243
daaf16ba 2244 strWID.id = (u16)WID_GET_INACTIVE_TIME;
416d8321 2245 strWID.type = WID_INT;
ad26906f 2246 strWID.val = (s8 *)&inactive_time;
2fd3e443 2247 strWID.size = sizeof(u32);
c5c77ba1 2248
31390eec 2249 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 2250 get_id_from_handler(hif_drv));
ae4dfa57 2251
31390eec 2252 if (result) {
c5c77ba1 2253 PRINT_ER("Failed to get incative time\n");
24db713f 2254 return -EFAULT;
c5c77ba1
JK
2255 }
2256
ad26906f 2257 PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time);
c5c77ba1 2258
a4ab1ade 2259 up(&hif_drv->hSemInactiveTime);
c5c77ba1 2260
31390eec 2261 return result;
c5c77ba1
JK
2262}
2263
a4ab1ade 2264static void Handle_AddBeacon(struct host_if_drv *hif_drv,
7f33fecd 2265 struct beacon_attr *pstrSetBeaconParam)
c5c77ba1 2266{
31390eec 2267 s32 result = 0;
e9e0c260 2268 struct wid strWID;
63d03e47 2269 u8 *pu8CurrByte;
78c87591 2270
c5c77ba1
JK
2271 PRINT_D(HOSTINF_DBG, "Adding BEACON\n");
2272
daaf16ba 2273 strWID.id = (u16)WID_ADD_BEACON;
416d8321 2274 strWID.type = WID_BIN;
030c57e2 2275 strWID.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
900bb4a6
LK
2276 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
2277 if (strWID.val == NULL)
24db713f 2278 goto ERRORHANDLER;
c5c77ba1 2279
900bb4a6 2280 pu8CurrByte = strWID.val;
12262dda
LK
2281 *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2282 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2283 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2284 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
c5c77ba1 2285
e76ab770
LK
2286 *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2287 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2288 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2289 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
c5c77ba1 2290
51c66185
LK
2291 *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2292 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2293 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2294 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
c5c77ba1 2295
8ce528b9 2296 memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
51c66185 2297 pu8CurrByte += pstrSetBeaconParam->head_len;
c5c77ba1 2298
030c57e2
LK
2299 *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2300 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2301 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2302 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
c5c77ba1 2303
7dbcb6d3
LK
2304 if (pstrSetBeaconParam->tail > 0)
2305 memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
030c57e2 2306 pu8CurrByte += pstrSetBeaconParam->tail_len;
c5c77ba1 2307
31390eec 2308 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2309 get_id_from_handler(hif_drv));
31390eec 2310 if (result)
c5c77ba1 2311 PRINT_ER("Failed to send add beacon config packet\n");
c5c77ba1 2312
24db713f 2313ERRORHANDLER:
900bb4a6 2314 kfree(strWID.val);
8ce528b9 2315 kfree(pstrSetBeaconParam->head);
7dbcb6d3 2316 kfree(pstrSetBeaconParam->tail);
c5c77ba1
JK
2317}
2318
a4ab1ade 2319static void Handle_DelBeacon(struct host_if_drv *hif_drv)
c5c77ba1 2320{
31390eec 2321 s32 result = 0;
e9e0c260 2322 struct wid strWID;
63d03e47 2323 u8 *pu8CurrByte;
78c87591 2324
daaf16ba 2325 strWID.id = (u16)WID_DEL_BEACON;
416d8321 2326 strWID.type = WID_CHAR;
2fd3e443 2327 strWID.size = sizeof(char);
a74c7bf8 2328 strWID.val = &del_beacon;
c5c77ba1 2329
900bb4a6 2330 if (strWID.val == NULL)
24db713f 2331 return;
c5c77ba1 2332
900bb4a6 2333 pu8CurrByte = strWID.val;
c5c77ba1
JK
2334
2335 PRINT_D(HOSTINF_DBG, "Deleting BEACON\n");
c5c77ba1 2336
31390eec 2337 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2338 get_id_from_handler(hif_drv));
31390eec 2339 if (result)
c5c77ba1 2340 PRINT_ER("Failed to send delete beacon config packet\n");
c5c77ba1
JK
2341}
2342
6a89ba9c
TC
2343static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2344 struct add_sta_param *pstrStationParam)
c5c77ba1 2345{
63d03e47 2346 u8 *pu8CurrByte;
c5c77ba1
JK
2347
2348 pu8CurrByte = pu8Buffer;
2349
2350 PRINT_D(HOSTINF_DBG, "Packing STA params\n");
d00d2ba3 2351 memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN);
c5c77ba1
JK
2352 pu8CurrByte += ETH_ALEN;
2353
2354 *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF;
2355 *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF;
2356
2357 *pu8CurrByte++ = pstrStationParam->u8NumRates;
2b9d5b48 2358 if (pstrStationParam->u8NumRates > 0)
d00d2ba3 2359 memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates);
c5c77ba1
JK
2360 pu8CurrByte += pstrStationParam->u8NumRates;
2361
2362 *pu8CurrByte++ = pstrStationParam->bIsHTSupported;
2363 *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF;
2364 *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF;
2365
2366 *pu8CurrByte++ = pstrStationParam->u8AmpduParams;
d00d2ba3 2367 memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE);
c5c77ba1
JK
2368 pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2369
2370 *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF;
2371 *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF;
2372
2373 *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF;
2374 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF;
2375 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF;
2376 *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF;
2377
2378 *pu8CurrByte++ = pstrStationParam->u8ASELCap;
2379
2380 *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF;
2381 *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF;
2382
2383 *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF;
2384 *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF;
2385
2386 return pu8CurrByte - pu8Buffer;
2387}
2388
a4ab1ade 2389static void Handle_AddStation(struct host_if_drv *hif_drv,
6a89ba9c 2390 struct add_sta_param *pstrStationParam)
c5c77ba1 2391{
31390eec 2392 s32 result = 0;
e9e0c260 2393 struct wid strWID;
63d03e47 2394 u8 *pu8CurrByte;
78c87591 2395
c5c77ba1 2396 PRINT_D(HOSTINF_DBG, "Handling add station\n");
daaf16ba 2397 strWID.id = (u16)WID_ADD_STA;
416d8321 2398 strWID.type = WID_BIN;
2fd3e443 2399 strWID.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
c5c77ba1 2400
900bb4a6
LK
2401 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
2402 if (strWID.val == NULL)
24db713f 2403 goto ERRORHANDLER;
c5c77ba1 2404
900bb4a6 2405 pu8CurrByte = strWID.val;
c5c77ba1
JK
2406 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2407
31390eec 2408 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2409 get_id_from_handler(hif_drv));
31390eec 2410 if (result != 0)
c5c77ba1 2411 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2412
24db713f 2413ERRORHANDLER:
969effe9 2414 kfree(pstrStationParam->pu8Rates);
900bb4a6 2415 kfree(strWID.val);
c5c77ba1
JK
2416}
2417
a4ab1ade 2418static void Handle_DelAllSta(struct host_if_drv *hif_drv,
b4e644e4 2419 struct del_all_sta *pstrDelAllStaParam)
c5c77ba1 2420{
31390eec 2421 s32 result = 0;
78c87591 2422
e9e0c260 2423 struct wid strWID;
63d03e47 2424 u8 *pu8CurrByte;
63d03e47 2425 u8 i;
3703480b 2426 u8 au8Zero_Buff[6] = {0};
78c87591 2427
daaf16ba 2428 strWID.id = (u16)WID_DEL_ALL_STA;
416d8321 2429 strWID.type = WID_STR;
8ba1803f 2430 strWID.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
c5c77ba1 2431
03b2d5e7 2432 PRINT_D(HOSTINF_DBG, "Handling delete station\n");
c5c77ba1 2433
8ba1803f 2434 strWID.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
900bb4a6 2435 if (strWID.val == NULL)
24db713f 2436 goto ERRORHANDLER;
c5c77ba1 2437
900bb4a6 2438 pu8CurrByte = strWID.val;
c5c77ba1 2439
8ba1803f 2440 *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
c5c77ba1
JK
2441
2442 for (i = 0; i < MAX_NUM_STA; i++) {
e51b9216
LK
2443 if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2444 memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
c5c77ba1
JK
2445 else
2446 continue;
2447
2448 pu8CurrByte += ETH_ALEN;
2449 }
2450
31390eec 2451 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2452 get_id_from_handler(hif_drv));
31390eec 2453 if (result)
83cc9be5 2454 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2455
24db713f 2456ERRORHANDLER:
900bb4a6 2457 kfree(strWID.val);
c5c77ba1 2458
2d25af87 2459 up(&hif_sema_wait_response);
c5c77ba1
JK
2460}
2461
a4ab1ade 2462static void Handle_DelStation(struct host_if_drv *hif_drv,
fb93a1e1 2463 struct del_sta *pstrDelStaParam)
c5c77ba1 2464{
31390eec 2465 s32 result = 0;
e9e0c260 2466 struct wid strWID;
63d03e47 2467 u8 *pu8CurrByte;
c5c77ba1 2468
daaf16ba 2469 strWID.id = (u16)WID_REMOVE_STA;
416d8321 2470 strWID.type = WID_BIN;
2fd3e443 2471 strWID.size = ETH_ALEN;
c5c77ba1 2472
03b2d5e7 2473 PRINT_D(HOSTINF_DBG, "Handling delete station\n");
c5c77ba1 2474
900bb4a6
LK
2475 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
2476 if (strWID.val == NULL)
24db713f 2477 goto ERRORHANDLER;
c5c77ba1 2478
900bb4a6 2479 pu8CurrByte = strWID.val;
c5c77ba1 2480
e4839d39 2481 memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
c5c77ba1 2482
31390eec 2483 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2484 get_id_from_handler(hif_drv));
31390eec 2485 if (result)
83cc9be5 2486 PRINT_ER("Failed to send add station config packet\n");
c5c77ba1 2487
24db713f 2488ERRORHANDLER:
900bb4a6 2489 kfree(strWID.val);
c5c77ba1
JK
2490}
2491
a4ab1ade 2492static void Handle_EditStation(struct host_if_drv *hif_drv,
6a89ba9c 2493 struct add_sta_param *pstrStationParam)
c5c77ba1 2494{
31390eec 2495 s32 result = 0;
e9e0c260 2496 struct wid strWID;
63d03e47 2497 u8 *pu8CurrByte;
c5c77ba1 2498
daaf16ba 2499 strWID.id = (u16)WID_EDIT_STA;
416d8321 2500 strWID.type = WID_BIN;
2fd3e443 2501 strWID.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
c5c77ba1
JK
2502
2503 PRINT_D(HOSTINF_DBG, "Handling edit station\n");
900bb4a6
LK
2504 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
2505 if (strWID.val == NULL)
24db713f 2506 goto ERRORHANDLER;
c5c77ba1 2507
900bb4a6 2508 pu8CurrByte = strWID.val;
c5c77ba1
JK
2509 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2510
31390eec 2511 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2512 get_id_from_handler(hif_drv));
31390eec 2513 if (result)
c5c77ba1 2514 PRINT_ER("Failed to send edit station config packet\n");
c5c77ba1 2515
24db713f 2516ERRORHANDLER:
969effe9 2517 kfree(pstrStationParam->pu8Rates);
900bb4a6 2518 kfree(strWID.val);
c5c77ba1 2519}
c5c77ba1 2520
a4ab1ade 2521static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
2f9c03f5 2522 struct remain_ch *pstrHostIfRemainOnChan)
c5c77ba1 2523{
31390eec 2524 s32 result = 0;
63d03e47 2525 u8 u8remain_on_chan_flag;
e9e0c260 2526 struct wid strWID;
c5c77ba1 2527
a4ab1ade
TC
2528 if (!hif_drv->u8RemainOnChan_pendingreq) {
2529 hif_drv->strHostIfRemainOnChan.pVoid = pstrHostIfRemainOnChan->pVoid;
2530 hif_drv->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired;
2531 hif_drv->strHostIfRemainOnChan.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady;
2532 hif_drv->strHostIfRemainOnChan.u16Channel = pstrHostIfRemainOnChan->u16Channel;
2533 hif_drv->strHostIfRemainOnChan.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID;
c5c77ba1 2534 } else {
a4ab1ade 2535 pstrHostIfRemainOnChan->u16Channel = hif_drv->strHostIfRemainOnChan.u16Channel;
c5c77ba1
JK
2536 }
2537
a4ab1ade 2538 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult != NULL) {
c5c77ba1 2539 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n");
a4ab1ade 2540 hif_drv->u8RemainOnChan_pendingreq = 1;
31390eec 2541 result = -EBUSY;
24db713f 2542 goto ERRORHANDLER;
c5c77ba1 2543 }
a4ab1ade 2544 if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
c5c77ba1 2545 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n");
31390eec 2546 result = -EBUSY;
24db713f 2547 goto ERRORHANDLER;
c5c77ba1
JK
2548 }
2549
c5c77ba1
JK
2550 if (g_obtainingIP || connecting) {
2551 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
31390eec 2552 result = -EBUSY;
24db713f 2553 goto ERRORHANDLER;
c5c77ba1 2554 }
c5c77ba1
JK
2555
2556 PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel);
2557
72ed4dc7 2558 u8remain_on_chan_flag = true;
daaf16ba 2559 strWID.id = (u16)WID_REMAIN_ON_CHAN;
416d8321 2560 strWID.type = WID_STR;
2fd3e443 2561 strWID.size = 2;
900bb4a6 2562 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
c5c77ba1 2563
900bb4a6 2564 if (strWID.val == NULL) {
31390eec 2565 result = -ENOMEM;
24db713f
LK
2566 goto ERRORHANDLER;
2567 }
c5c77ba1 2568
900bb4a6
LK
2569 strWID.val[0] = u8remain_on_chan_flag;
2570 strWID.val[1] = (s8)pstrHostIfRemainOnChan->u16Channel;
c5c77ba1 2571
31390eec 2572 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2573 get_id_from_handler(hif_drv));
31390eec 2574 if (result != 0)
c5c77ba1 2575 PRINT_ER("Failed to set remain on channel\n");
c5c77ba1 2576
24db713f 2577ERRORHANDLER:
c5c77ba1
JK
2578 {
2579 P2P_LISTEN_STATE = 1;
a4ab1ade
TC
2580 hif_drv->hRemainOnChannel.data = (unsigned long)hif_drv;
2581 mod_timer(&hif_drv->hRemainOnChannel,
9eb06643
GKH
2582 jiffies +
2583 msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration));
c5c77ba1 2584
a4ab1ade
TC
2585 if (hif_drv->strHostIfRemainOnChan.pRemainOnChanReady)
2586 hif_drv->strHostIfRemainOnChan.pRemainOnChanReady(hif_drv->strHostIfRemainOnChan.pVoid);
c5c77ba1 2587
a4ab1ade
TC
2588 if (hif_drv->u8RemainOnChan_pendingreq)
2589 hif_drv->u8RemainOnChan_pendingreq = 0;
c5c77ba1 2590 }
31390eec
LK
2591
2592 return result;
c5c77ba1
JK
2593}
2594
a4ab1ade 2595static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
bc37c5df 2596 struct reg_frame *pstrHostIfRegisterFrame)
c5c77ba1 2597{
31390eec 2598 s32 result = 0;
e9e0c260 2599 struct wid strWID;
63d03e47 2600 u8 *pu8CurrByte;
c5c77ba1
JK
2601
2602 PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType);
2603
daaf16ba 2604 strWID.id = (u16)WID_REGISTER_FRAME;
416d8321 2605 strWID.type = WID_STR;
900bb4a6
LK
2606 strWID.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2607 if (strWID.val == NULL)
24db713f 2608 return -ENOMEM;
c5c77ba1 2609
900bb4a6 2610 pu8CurrByte = strWID.val;
c5c77ba1
JK
2611
2612 *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg;
2613 *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid;
d00d2ba3 2614 memcpy(pu8CurrByte, &(pstrHostIfRegisterFrame->u16FrameType), sizeof(u16));
c5c77ba1
JK
2615
2616
2fd3e443 2617 strWID.size = sizeof(u16) + 2;
c5c77ba1 2618
31390eec 2619 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2620 get_id_from_handler(hif_drv));
31390eec 2621 if (result) {
c5c77ba1 2622 PRINT_ER("Failed to frame register config packet\n");
31390eec 2623 result = -EINVAL;
c5c77ba1
JK
2624 }
2625
31390eec 2626 return result;
c5c77ba1
JK
2627}
2628
a4ab1ade 2629static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv,
2f9c03f5 2630 struct remain_ch *pstrHostIfRemainOnChan)
c5c77ba1 2631{
63d03e47 2632 u8 u8remain_on_chan_flag;
e9e0c260 2633 struct wid strWID;
31390eec 2634 s32 result = 0;
c5c77ba1
JK
2635
2636 PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n");
2637
c5c77ba1 2638 if (P2P_LISTEN_STATE) {
72ed4dc7 2639 u8remain_on_chan_flag = false;
daaf16ba 2640 strWID.id = (u16)WID_REMAIN_ON_CHAN;
416d8321 2641 strWID.type = WID_STR;
2fd3e443 2642 strWID.size = 2;
900bb4a6 2643 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
c5c77ba1 2644
900bb4a6 2645 if (strWID.val == NULL)
c5c77ba1 2646 PRINT_ER("Failed to allocate memory\n");
c5c77ba1 2647
900bb4a6
LK
2648 strWID.val[0] = u8remain_on_chan_flag;
2649 strWID.val[1] = FALSE_FRMWR_CHANNEL;
c5c77ba1 2650
31390eec 2651 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2652 get_id_from_handler(hif_drv));
31390eec 2653 if (result != 0) {
c5c77ba1
JK
2654 PRINT_ER("Failed to set remain on channel\n");
2655 goto _done_;
2656 }
2657
a4ab1ade
TC
2658 if (hif_drv->strHostIfRemainOnChan.pRemainOnChanExpired) {
2659 hif_drv->strHostIfRemainOnChan.pRemainOnChanExpired(hif_drv->strHostIfRemainOnChan.pVoid
c5c77ba1
JK
2660 , pstrHostIfRemainOnChan->u32ListenSessionID);
2661 }
2662 P2P_LISTEN_STATE = 0;
2663 } else {
2664 PRINT_D(GENERIC_DBG, "Not in listen state\n");
31390eec 2665 result = -EFAULT;
c5c77ba1
JK
2666 }
2667
2668_done_:
31390eec 2669 return result;
c5c77ba1
JK
2670}
2671
93dee8ee 2672static void ListenTimerCB(unsigned long arg)
c5c77ba1 2673{
31390eec 2674 s32 result = 0;
143eb95a 2675 struct host_if_msg msg;
a4ab1ade 2676 struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
ae4dfa57 2677
a4ab1ade 2678 del_timer(&hif_drv->hRemainOnChannel);
c5c77ba1 2679
143eb95a 2680 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 2681 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
a4ab1ade
TC
2682 msg.drv = hif_drv;
2683 msg.body.remain_on_ch.u32ListenSessionID = hif_drv->strHostIfRemainOnChan.u32ListenSessionID;
c5c77ba1 2684
31390eec
LK
2685 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2686 if (result)
24db713f 2687 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 2688}
c5c77ba1 2689
a4ab1ade 2690static void Handle_PowerManagement(struct host_if_drv *hif_drv,
5a008f1c 2691 struct power_mgmt_param *strPowerMgmtParam)
c5c77ba1 2692{
31390eec 2693 s32 result = 0;
e9e0c260 2694 struct wid strWID;
ca356ada 2695 s8 s8PowerMode;
78c87591 2696
daaf16ba 2697 strWID.id = (u16)WID_POWER_MANAGEMENT;
c5c77ba1 2698
33c70c1b 2699 if (strPowerMgmtParam->enabled == true)
c5c77ba1 2700 s8PowerMode = MIN_FAST_PS;
78174ada 2701 else
c5c77ba1 2702 s8PowerMode = NO_POWERSAVE;
c5c77ba1 2703 PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode);
900bb4a6 2704 strWID.val = &s8PowerMode;
2fd3e443 2705 strWID.size = sizeof(char);
c5c77ba1
JK
2706
2707 PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
2708
31390eec 2709 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2710 get_id_from_handler(hif_drv));
31390eec 2711 if (result)
c5c77ba1 2712 PRINT_ER("Failed to send power management config packet\n");
c5c77ba1
JK
2713}
2714
a4ab1ade 2715static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
641210ac 2716 struct set_multicast *strHostIfSetMulti)
c5c77ba1 2717{
31390eec 2718 s32 result = 0;
e9e0c260 2719 struct wid strWID;
63d03e47 2720 u8 *pu8CurrByte;
c5c77ba1
JK
2721
2722 PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n");
2723
daaf16ba 2724 strWID.id = (u16)WID_SETUP_MULTICAST_FILTER;
416d8321 2725 strWID.type = WID_BIN;
adab2f71 2726 strWID.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
900bb4a6
LK
2727 strWID.val = kmalloc(strWID.size, GFP_KERNEL);
2728 if (strWID.val == NULL)
24db713f 2729 goto ERRORHANDLER;
c5c77ba1 2730
900bb4a6 2731 pu8CurrByte = strWID.val;
bae636eb
LK
2732 *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2733 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
2734 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
2735 *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
c5c77ba1 2736
adab2f71
LK
2737 *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2738 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2739 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2740 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
c5c77ba1 2741
adab2f71
LK
2742 if ((strHostIfSetMulti->cnt) > 0)
2743 memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->cnt) * ETH_ALEN));
c5c77ba1 2744
31390eec 2745 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2746 get_id_from_handler(hif_drv));
31390eec 2747 if (result)
c5c77ba1 2748 PRINT_ER("Failed to send setup multicast config packet\n");
c5c77ba1 2749
24db713f 2750ERRORHANDLER:
900bb4a6 2751 kfree(strWID.val);
c5c77ba1
JK
2752
2753}
2754
a4ab1ade 2755static s32 Handle_AddBASession(struct host_if_drv *hif_drv,
54265472 2756 struct ba_session_info *strHostIfBASessionInfo)
c5c77ba1 2757{
31390eec 2758 s32 result = 0;
e9e0c260 2759 struct wid strWID;
c5c77ba1
JK
2760 int AddbaTimeout = 100;
2761 char *ptr = NULL;
c5c77ba1 2762
03b2d5e7 2763 PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n",
c5c77ba1
JK
2764 strHostIfBASessionInfo->au8Bssid[0],
2765 strHostIfBASessionInfo->au8Bssid[1],
2766 strHostIfBASessionInfo->au8Bssid[2],
2767 strHostIfBASessionInfo->u16BufferSize,
2768 strHostIfBASessionInfo->u16SessionTimeout,
2769 strHostIfBASessionInfo->u8Ted);
2770
daaf16ba 2771 strWID.id = (u16)WID_11E_P_ACTION_REQ;
416d8321 2772 strWID.type = WID_STR;
900bb4a6 2773 strWID.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2fd3e443 2774 strWID.size = BLOCK_ACK_REQ_SIZE;
900bb4a6 2775 ptr = strWID.val;
c5c77ba1
JK
2776 *ptr++ = 0x14;
2777 *ptr++ = 0x3;
2778 *ptr++ = 0x0;
d00d2ba3 2779 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1
JK
2780 ptr += ETH_ALEN;
2781 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2782 *ptr++ = 1;
c5c77ba1
JK
2783 *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2784 *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF);
c5c77ba1
JK
2785 *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF);
2786 *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
c5c77ba1
JK
2787 *ptr++ = (AddbaTimeout & 0xFF);
2788 *ptr++ = ((AddbaTimeout >> 16) & 0xFF);
c5c77ba1 2789 *ptr++ = 8;
c5c77ba1
JK
2790 *ptr++ = 0;
2791
31390eec 2792 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2793 get_id_from_handler(hif_drv));
31390eec 2794 if (result)
c5c77ba1
JK
2795 PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
2796
2797
daaf16ba 2798 strWID.id = (u16)WID_11E_P_ACTION_REQ;
416d8321 2799 strWID.type = WID_STR;
2fd3e443 2800 strWID.size = 15;
900bb4a6 2801 ptr = strWID.val;
c5c77ba1
JK
2802 *ptr++ = 15;
2803 *ptr++ = 7;
2804 *ptr++ = 0x2;
d00d2ba3 2805 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1 2806 ptr += ETH_ALEN;
c5c77ba1 2807 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2808 *ptr++ = 8;
c5c77ba1
JK
2809 *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2810 *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
c5c77ba1 2811 *ptr++ = 3;
31390eec 2812 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2813 get_id_from_handler(hif_drv));
c5c77ba1 2814
95f840fb 2815 kfree(strWID.val);
c5c77ba1 2816
31390eec 2817 return result;
c5c77ba1
JK
2818
2819}
2820
a4ab1ade 2821static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv,
54265472 2822 struct ba_session_info *strHostIfBASessionInfo)
c5c77ba1 2823{
31390eec 2824 s32 result = 0;
e9e0c260 2825 struct wid strWID;
c5c77ba1 2826 char *ptr = NULL;
c5c77ba1 2827
03b2d5e7 2828 PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n",
c5c77ba1
JK
2829 strHostIfBASessionInfo->au8Bssid[0],
2830 strHostIfBASessionInfo->au8Bssid[1],
2831 strHostIfBASessionInfo->au8Bssid[2],
2832 strHostIfBASessionInfo->u8Ted);
2833
daaf16ba 2834 strWID.id = (u16)WID_DEL_ALL_RX_BA;
416d8321 2835 strWID.type = WID_STR;
900bb4a6 2836 strWID.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2fd3e443 2837 strWID.size = BLOCK_ACK_REQ_SIZE;
900bb4a6 2838 ptr = strWID.val;
c5c77ba1
JK
2839 *ptr++ = 0x14;
2840 *ptr++ = 0x3;
2841 *ptr++ = 0x2;
d00d2ba3 2842 memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
c5c77ba1
JK
2843 ptr += ETH_ALEN;
2844 *ptr++ = strHostIfBASessionInfo->u8Ted;
c5c77ba1 2845 *ptr++ = 0;
ae4dfa57 2846 *ptr++ = 32;
c5c77ba1 2847
31390eec 2848 result = send_config_pkt(SET_CFG, &strWID, 1,
8c8360b3 2849 get_id_from_handler(hif_drv));
31390eec 2850 if (result)
c5c77ba1
JK
2851 PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
2852
2853
95f840fb 2854 kfree(strWID.val);
c5c77ba1 2855
2d25af87 2856 up(&hif_sema_wait_response);
c5c77ba1 2857
31390eec 2858 return result;
c5c77ba1
JK
2859}
2860
1999bd52 2861static int hostIFthread(void *pvArg)
c5c77ba1 2862{
4e4467fd 2863 u32 u32Ret;
143eb95a 2864 struct host_if_msg msg;
a4ab1ade 2865 struct host_if_drv *hif_drv;
c5c77ba1 2866
143eb95a 2867 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
2868
2869 while (1) {
cb067dcf 2870 wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
a4ab1ade 2871 hif_drv = (struct host_if_drv *)msg.drv;
a9f812a6 2872 if (msg.id == HOST_IF_MSG_EXIT) {
c5c77ba1
JK
2873 PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
2874 break;
2875 }
2876
c5c77ba1
JK
2877 if ((!g_wilc_initialized)) {
2878 PRINT_D(GENERIC_DBG, "--WAIT--");
80e29c7a 2879 usleep_range(200 * 1000, 200 * 1000);
cb067dcf 2880 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
2881 continue;
2882 }
2883
a4ab1ade 2884 if (msg.id == HOST_IF_MSG_CONNECT && hif_drv->strWILC_UsrScanReq.pfUserScanResult != NULL) {
c5c77ba1 2885 PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
cb067dcf 2886 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
80e29c7a 2887 usleep_range(2 * 1000, 2 * 1000);
c5c77ba1
JK
2888 continue;
2889 }
2890
a9f812a6 2891 switch (msg.id) {
c5c77ba1
JK
2892 case HOST_IF_MSG_Q_IDLE:
2893 Handle_wait_msg_q_empty();
2894 break;
2895
2896 case HOST_IF_MSG_SCAN:
2482a79f 2897 Handle_Scan(msg.drv, &msg.body.scan_info);
c5c77ba1
JK
2898 break;
2899
2900 case HOST_IF_MSG_CONNECT:
2482a79f 2901 Handle_Connect(msg.drv, &msg.body.con_info);
c5c77ba1
JK
2902 break;
2903
c5c77ba1 2904 case HOST_IF_MSG_FLUSH_CONNECT:
2482a79f 2905 Handle_FlushConnect(msg.drv);
c5c77ba1
JK
2906 break;
2907
2908 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2482a79f 2909 Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info);
c5c77ba1
JK
2910 break;
2911
2912 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2482a79f 2913 Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info);
c5c77ba1
JK
2914 break;
2915
2916 case HOST_IF_MSG_KEY:
2482a79f 2917 Handle_Key(msg.drv, &msg.body.key_info);
c5c77ba1
JK
2918 break;
2919
2920 case HOST_IF_MSG_CFG_PARAMS:
2921
2482a79f 2922 Handle_CfgParam(msg.drv, &msg.body.cfg_info);
c5c77ba1
JK
2923 break;
2924
2925 case HOST_IF_MSG_SET_CHANNEL:
2482a79f 2926 Handle_SetChannel(msg.drv, &msg.body.channel_info);
c5c77ba1
JK
2927 break;
2928
2929 case HOST_IF_MSG_DISCONNECT:
2482a79f 2930 Handle_Disconnect(msg.drv);
c5c77ba1
JK
2931 break;
2932
2933 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
a4ab1ade 2934 del_timer(&hif_drv->hScanTimer);
c5c77ba1
JK
2935 PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
2936
2b9d5b48 2937 if (!linux_wlan_get_num_conn_ifcs())
c5c77ba1 2938 chip_sleep_manually(INFINITE_SLEEP_TIME);
c5c77ba1 2939
2482a79f 2940 Handle_ScanDone(msg.drv, SCAN_EVENT_DONE);
c5c77ba1 2941
a4ab1ade 2942 if (hif_drv->u8RemainOnChan_pendingreq)
2482a79f 2943 Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
2944
2945 break;
2946
2947 case HOST_IF_MSG_GET_RSSI:
2482a79f 2948 Handle_GetRssi(msg.drv);
c5c77ba1
JK
2949 break;
2950
2951 case HOST_IF_MSG_GET_LINKSPEED:
2482a79f 2952 Handle_GetLinkspeed(msg.drv);
c5c77ba1
JK
2953 break;
2954
2955 case HOST_IF_MSG_GET_STATISTICS:
03e7b9c4 2956 Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data);
c5c77ba1
JK
2957 break;
2958
2959 case HOST_IF_MSG_GET_CHNL:
2482a79f 2960 Handle_GetChnl(msg.drv);
c5c77ba1
JK
2961 break;
2962
c5c77ba1 2963 case HOST_IF_MSG_ADD_BEACON:
2482a79f 2964 Handle_AddBeacon(msg.drv, &msg.body.beacon_info);
c5c77ba1
JK
2965 break;
2966
2967 case HOST_IF_MSG_DEL_BEACON:
2482a79f 2968 Handle_DelBeacon(msg.drv);
c5c77ba1
JK
2969 break;
2970
2971 case HOST_IF_MSG_ADD_STATION:
2482a79f 2972 Handle_AddStation(msg.drv, &msg.body.add_sta_info);
c5c77ba1
JK
2973 break;
2974
2975 case HOST_IF_MSG_DEL_STATION:
2482a79f 2976 Handle_DelStation(msg.drv, &msg.body.del_sta_info);
c5c77ba1
JK
2977 break;
2978
2979 case HOST_IF_MSG_EDIT_STATION:
2482a79f 2980 Handle_EditStation(msg.drv, &msg.body.edit_sta_info);
c5c77ba1
JK
2981 break;
2982
2983 case HOST_IF_MSG_GET_INACTIVETIME:
2482a79f 2984 Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info);
c5c77ba1
JK
2985 break;
2986
c5c77ba1
JK
2987 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2988 PRINT_D(HOSTINF_DBG, "Scan Timeout\n");
2989
2482a79f 2990 Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED);
c5c77ba1
JK
2991 break;
2992
2993 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
03b2d5e7 2994 PRINT_D(HOSTINF_DBG, "Connect Timeout\n");
2482a79f 2995 Handle_ConnectTimeout(msg.drv);
c5c77ba1
JK
2996 break;
2997
2998 case HOST_IF_MSG_POWER_MGMT:
2482a79f 2999 Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info);
c5c77ba1
JK
3000 break;
3001
3002 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2482a79f 3003 Handle_SetWfiDrvHandler(msg.drv,
5e4377e6 3004 &msg.body.drv);
c5c77ba1
JK
3005 break;
3006
3007 case HOST_IF_MSG_SET_OPERATION_MODE:
2482a79f 3008 Handle_SetOperationMode(msg.drv, &msg.body.mode);
c5c77ba1
JK
3009 break;
3010
3011 case HOST_IF_MSG_SET_IPADDRESS:
3012 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
78675be5 3013 Handle_set_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
c5c77ba1
JK
3014 break;
3015
3016 case HOST_IF_MSG_GET_IPADDRESS:
3017 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
78675be5 3018 Handle_get_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
c5c77ba1
JK
3019 break;
3020
c5c77ba1 3021 case HOST_IF_MSG_SET_MAC_ADDRESS:
2482a79f 3022 Handle_SetMacAddress(msg.drv, &msg.body.set_mac_info);
c5c77ba1
JK
3023 break;
3024
c5c77ba1 3025 case HOST_IF_MSG_GET_MAC_ADDRESS:
2482a79f 3026 Handle_GetMacAddress(msg.drv, &msg.body.get_mac_info);
c5c77ba1
JK
3027 break;
3028
c5c77ba1
JK
3029 case HOST_IF_MSG_REMAIN_ON_CHAN:
3030 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n");
2482a79f 3031 Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
3032 break;
3033
3034 case HOST_IF_MSG_REGISTER_FRAME:
3035 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n");
2482a79f 3036 Handle_RegisterFrame(msg.drv, &msg.body.reg_frame);
c5c77ba1
JK
3037 break;
3038
3039 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2482a79f 3040 Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch);
c5c77ba1
JK
3041 break;
3042
c5c77ba1
JK
3043 case HOST_IF_MSG_SET_MULTICAST_FILTER:
3044 PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n");
2482a79f 3045 Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info);
c5c77ba1
JK
3046 break;
3047
c5c77ba1 3048 case HOST_IF_MSG_ADD_BA_SESSION:
2482a79f 3049 Handle_AddBASession(msg.drv, &msg.body.session_info);
c5c77ba1
JK
3050 break;
3051
3052 case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
2482a79f 3053 Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info);
c5c77ba1
JK
3054 break;
3055
3056 case HOST_IF_MSG_DEL_ALL_STA:
2482a79f 3057 Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info);
c5c77ba1
JK
3058 break;
3059
3060 default:
03b2d5e7 3061 PRINT_ER("[Host Interface] undefined Received Msg ID\n");
c5c77ba1
JK
3062 break;
3063 }
3064 }
3065
3066 PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n");
834e0cb0 3067 up(&hif_sema_thread);
1999bd52 3068 return 0;
c5c77ba1
JK
3069}
3070
93dee8ee 3071static void TimerCB_Scan(unsigned long arg)
c5c77ba1 3072{
93dee8ee 3073 void *pvArg = (void *)arg;
143eb95a 3074 struct host_if_msg msg;
c5c77ba1 3075
143eb95a 3076 memset(&msg, 0, sizeof(struct host_if_msg));
2482a79f 3077 msg.drv = pvArg;
a9f812a6 3078 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
c5c77ba1 3079
cb067dcf 3080 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
3081}
3082
93dee8ee 3083static void TimerCB_Connect(unsigned long arg)
c5c77ba1 3084{
93dee8ee 3085 void *pvArg = (void *)arg;
143eb95a 3086 struct host_if_msg msg;
c5c77ba1 3087
143eb95a 3088 memset(&msg, 0, sizeof(struct host_if_msg));
2482a79f 3089 msg.drv = pvArg;
a9f812a6 3090 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
c5c77ba1 3091
cb067dcf 3092 wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1
JK
3093}
3094
a4ab1ade 3095s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
c5c77ba1 3096{
e9e0c260 3097 struct wid strWID;
c5c77ba1 3098
daaf16ba 3099 strWID.id = (u16)WID_REMOVE_KEY;
416d8321 3100 strWID.type = WID_STR;
900bb4a6 3101 strWID.val = (s8 *)pu8StaAddress;
2fd3e443 3102 strWID.size = 6;
c5c77ba1 3103
b68d820b 3104 return 0;
c5c77ba1
JK
3105}
3106
a4ab1ade 3107int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
c5c77ba1 3108{
9e5e8b44 3109 int result = 0;
143eb95a 3110 struct host_if_msg msg;
c5c77ba1 3111
a4ab1ade 3112 if (!hif_drv) {
9e5e8b44 3113 result = -EFAULT;
24db713f 3114 PRINT_ER("Failed to send setup multicast config packet\n");
9e5e8b44 3115 return result;
24db713f 3116 }
c5c77ba1 3117
143eb95a 3118 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3119
a9f812a6 3120 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3121 msg.body.key_info.type = WEP;
0d17e382 3122 msg.body.key_info.action = REMOVEKEY;
a4ab1ade 3123 msg.drv = hif_drv;
73b2e381 3124 msg.body.key_info.attr.wep.index = index;
c5c77ba1 3125
cb067dcf 3126 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
9e5e8b44 3127 if (result)
03b2d5e7 3128 PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
a4ab1ade 3129 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3130
9e5e8b44 3131 return result;
c5c77ba1
JK
3132}
3133
a4ab1ade 3134s32 host_int_set_WEPDefaultKeyID(struct host_if_drv *hif_drv, u8 u8Index)
c5c77ba1 3135{
31390eec 3136 s32 result = 0;
143eb95a 3137 struct host_if_msg msg;
c5c77ba1
JK
3138
3139
a4ab1ade 3140 if (!hif_drv) {
31390eec 3141 result = -EFAULT;
24db713f 3142 PRINT_ER("driver is null\n");
31390eec 3143 return result;
24db713f 3144 }
c5c77ba1 3145
143eb95a 3146 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
3147
3148
a9f812a6 3149 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3150 msg.body.key_info.type = WEP;
0d17e382 3151 msg.body.key_info.action = DEFAULTKEY;
a4ab1ade 3152 msg.drv = hif_drv;
73b2e381 3153 msg.body.key_info.attr.wep.index = u8Index;
c5c77ba1 3154
31390eec
LK
3155 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3156 if (result)
c5c77ba1 3157 PRINT_ER("Error in sending message queue : Default key index\n");
a4ab1ade 3158 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3159
31390eec 3160 return result;
c5c77ba1
JK
3161}
3162
a4ab1ade
TC
3163s32 host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
3164 const u8 *pu8WepKey,
3165 u8 u8WepKeylen,
3166 u8 u8Keyidx)
c5c77ba1 3167{
31390eec 3168 s32 result = 0;
143eb95a 3169 struct host_if_msg msg;
c5c77ba1 3170
a4ab1ade 3171 if (!hif_drv) {
24db713f 3172 PRINT_ER("driver is null\n");
77178807 3173 return -EFAULT;
24db713f 3174 }
c5c77ba1 3175
143eb95a 3176 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
3177
3178
a9f812a6 3179 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3180 msg.body.key_info.type = WEP;
0d17e382 3181 msg.body.key_info.action = ADDKEY;
a4ab1ade 3182 msg.drv = hif_drv;
73b2e381
LK
3183 msg.body.key_info.attr.wep.key = kmalloc(u8WepKeylen, GFP_KERNEL);
3184 memcpy(msg.body.key_info.attr.wep.key, pu8WepKey, u8WepKeylen);
3185 msg.body.key_info.attr.wep.key_len = (u8WepKeylen);
3186 msg.body.key_info.attr.wep.index = u8Keyidx;
c5c77ba1 3187
31390eec
LK
3188 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3189 if (result)
c5c77ba1 3190 PRINT_ER("Error in sending message queue :WEP Key\n");
a4ab1ade 3191 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3192
31390eec 3193 return result;
c5c77ba1
JK
3194}
3195
a4ab1ade
TC
3196s32 host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
3197 const u8 *pu8WepKey,
3198 u8 u8WepKeylen,
3199 u8 u8Keyidx,
3200 u8 u8mode,
3201 enum AUTHTYPE tenuAuth_type)
c5c77ba1 3202{
31390eec 3203 s32 result = 0;
143eb95a 3204 struct host_if_msg msg;
63d03e47 3205 u8 i;
c5c77ba1 3206
a4ab1ade 3207 if (!hif_drv) {
24db713f 3208 PRINT_ER("driver is null\n");
77178807 3209 return -EFAULT;
24db713f 3210 }
c5c77ba1 3211
143eb95a 3212 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
3213
3214 if (INFO) {
3215 for (i = 0; i < u8WepKeylen; i++)
3216 PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", pu8WepKey[i]);
3217 }
a9f812a6 3218 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3219 msg.body.key_info.type = WEP;
0d17e382 3220 msg.body.key_info.action = ADDKEY_AP;
a4ab1ade 3221 msg.drv = hif_drv;
73b2e381
LK
3222 msg.body.key_info.attr.wep.key = kmalloc(u8WepKeylen, GFP_KERNEL);
3223 memcpy(msg.body.key_info.attr.wep.key, pu8WepKey, (u8WepKeylen));
3224 msg.body.key_info.attr.wep.key_len = (u8WepKeylen);
3225 msg.body.key_info.attr.wep.index = u8Keyidx;
3226 msg.body.key_info.attr.wep.mode = u8mode;
3227 msg.body.key_info.attr.wep.auth_type = tenuAuth_type;
ae4dfa57 3228
31390eec 3229 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3230
31390eec 3231 if (result)
c5c77ba1 3232 PRINT_ER("Error in sending message queue :WEP Key\n");
a4ab1ade 3233 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3234
31390eec 3235 return result;
c5c77ba1 3236}
108b3439 3237
a4ab1ade
TC
3238s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
3239 u8 u8PtkKeylen, const u8 *mac_addr,
3240 const u8 *pu8RxMic, const u8 *pu8TxMic,
3241 u8 mode, u8 u8Ciphermode, u8 u8Idx)
c5c77ba1 3242{
31390eec 3243 s32 result = 0;
143eb95a 3244 struct host_if_msg msg;
63d03e47 3245 u8 u8KeyLen = u8PtkKeylen;
4e4467fd 3246 u32 i;
78c87591 3247
a4ab1ade 3248 if (!hif_drv) {
24db713f 3249 PRINT_ER("driver is null\n");
77178807 3250 return -EFAULT;
24db713f 3251 }
2b9d5b48 3252 if (pu8RxMic != NULL)
c5c77ba1 3253 u8KeyLen += RX_MIC_KEY_LEN;
2b9d5b48 3254 if (pu8TxMic != NULL)
c5c77ba1 3255 u8KeyLen += TX_MIC_KEY_LEN;
c5c77ba1 3256
143eb95a 3257 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
3258
3259
a9f812a6 3260 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3261 msg.body.key_info.type = WPAPtk;
c5c77ba1 3262 if (mode == AP_MODE) {
0d17e382 3263 msg.body.key_info.action = ADDKEY_AP;
e2dfbac5 3264 msg.body.key_info.attr.wpa.index = u8Idx;
c5c77ba1 3265 }
c5c77ba1 3266 if (mode == STATION_MODE)
0d17e382 3267 msg.body.key_info.action = ADDKEY;
c5c77ba1 3268
124968fc
LK
3269 msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
3270 memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
c5c77ba1
JK
3271
3272 if (pu8RxMic != NULL) {
124968fc 3273 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
c5c77ba1
JK
3274 if (INFO) {
3275 for (i = 0; i < RX_MIC_KEY_LEN; i++)
3276 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
3277 }
3278 }
3279 if (pu8TxMic != NULL) {
124968fc 3280 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
c5c77ba1
JK
3281 if (INFO) {
3282 for (i = 0; i < TX_MIC_KEY_LEN; i++)
3283 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
3284 }
3285 }
3286
6acf2919 3287 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
248080aa 3288 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
7b2ebb28 3289 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
a4ab1ade 3290 msg.drv = hif_drv;
c5c77ba1 3291
31390eec 3292 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3293
31390eec 3294 if (result)
c5c77ba1
JK
3295 PRINT_ER("Error in sending message queue: PTK Key\n");
3296
a4ab1ade 3297 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3298
31390eec 3299 return result;
c5c77ba1
JK
3300}
3301
a4ab1ade
TC
3302s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
3303 u8 u8GtkKeylen, u8 u8KeyIdx,
3304 u32 u32KeyRSClen, const u8 *KeyRSC,
3305 const u8 *pu8RxMic, const u8 *pu8TxMic,
3306 u8 mode, u8 u8Ciphermode)
c5c77ba1 3307{
31390eec 3308 s32 result = 0;
143eb95a 3309 struct host_if_msg msg;
63d03e47 3310 u8 u8KeyLen = u8GtkKeylen;
c5c77ba1 3311
a4ab1ade 3312 if (!hif_drv) {
24db713f 3313 PRINT_ER("driver is null\n");
77178807 3314 return -EFAULT;
24db713f 3315 }
143eb95a 3316 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
3317
3318
2b9d5b48 3319 if (pu8RxMic != NULL)
c5c77ba1 3320 u8KeyLen += RX_MIC_KEY_LEN;
2b9d5b48 3321 if (pu8TxMic != NULL)
c5c77ba1 3322 u8KeyLen += TX_MIC_KEY_LEN;
c5c77ba1 3323 if (KeyRSC != NULL) {
0e74c009
LK
3324 msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
3325 memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
c5c77ba1
JK
3326 }
3327
3328
a9f812a6 3329 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3330 msg.body.key_info.type = WPARxGtk;
a4ab1ade 3331 msg.drv = hif_drv;
c5c77ba1 3332
c5c77ba1 3333 if (mode == AP_MODE) {
0d17e382 3334 msg.body.key_info.action = ADDKEY_AP;
7b2ebb28 3335 msg.body.key_info.attr.wpa.mode = u8Ciphermode;
c5c77ba1 3336 }
c5c77ba1 3337 if (mode == STATION_MODE)
0d17e382 3338 msg.body.key_info.action = ADDKEY;
c5c77ba1 3339
124968fc
LK
3340 msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
3341 memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
c5c77ba1
JK
3342
3343 if (pu8RxMic != NULL) {
124968fc 3344 memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
c5c77ba1
JK
3345 }
3346 if (pu8TxMic != NULL) {
124968fc 3347 memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
c5c77ba1
JK
3348 }
3349
e2dfbac5 3350 msg.body.key_info.attr.wpa.index = u8KeyIdx;
6acf2919 3351 msg.body.key_info.attr.wpa.key_len = u8KeyLen;
dacc594d 3352 msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
c5c77ba1 3353
31390eec
LK
3354 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3355 if (result)
c5c77ba1 3356 PRINT_ER("Error in sending message queue: RX GTK\n");
ae4dfa57 3357
a4ab1ade 3358 down(&hif_drv->hSemTestKeyBlock);
c5c77ba1 3359
31390eec 3360 return result;
c5c77ba1 3361}
c5c77ba1 3362
a4ab1ade 3363s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
c5c77ba1 3364{
31390eec 3365 s32 result = 0;
143eb95a 3366 struct host_if_msg msg;
4e4467fd 3367 u32 i;
c5c77ba1
JK
3368
3369
a4ab1ade 3370 if (!hif_drv) {
24db713f 3371 PRINT_ER("driver is null\n");
77178807 3372 return -EFAULT;
24db713f 3373 }
c5c77ba1 3374
143eb95a 3375 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3376
a9f812a6 3377 msg.id = HOST_IF_MSG_KEY;
8e9f427a 3378 msg.body.key_info.type = PMKSA;
0d17e382 3379 msg.body.key_info.action = ADDKEY;
a4ab1ade 3380 msg.drv = hif_drv;
c5c77ba1
JK
3381
3382 for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
8c8360b3
LK
3383 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3384 &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN);
3385 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3386 &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN);
c5c77ba1
JK
3387 }
3388
31390eec
LK
3389 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3390 if (result)
c5c77ba1
JK
3391 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3392
31390eec 3393 return result;
c5c77ba1
JK
3394}
3395
a4ab1ade
TC
3396s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
3397 u8 *pu8PmkidInfoArray,
3398 u32 u32PmkidInfoLen)
c5c77ba1 3399{
e9e0c260 3400 struct wid strWID;
c5c77ba1 3401
daaf16ba 3402 strWID.id = (u16)WID_PMKID_INFO;
416d8321 3403 strWID.type = WID_STR;
2fd3e443 3404 strWID.size = u32PmkidInfoLen;
900bb4a6 3405 strWID.val = pu8PmkidInfoArray;
c5c77ba1 3406
b68d820b 3407 return 0;
c5c77ba1
JK
3408}
3409
a4ab1ade
TC
3410s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3411 u8 *pu8PassPhrase,
3412 u8 u8Psklength)
c5c77ba1 3413{
e9e0c260 3414 struct wid strWID;
c5c77ba1 3415
c5c77ba1 3416 if ((u8Psklength > 7) && (u8Psklength < 65)) {
daaf16ba 3417 strWID.id = (u16)WID_11I_PSK;
416d8321 3418 strWID.type = WID_STR;
900bb4a6 3419 strWID.val = pu8PassPhrase;
2fd3e443 3420 strWID.size = u8Psklength;
c5c77ba1
JK
3421 }
3422
b68d820b 3423 return 0;
c5c77ba1 3424}
ae4dfa57 3425
a4ab1ade 3426s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3427{
31390eec 3428 s32 result = 0;
143eb95a 3429 struct host_if_msg msg;
c5c77ba1 3430
143eb95a 3431 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3432
a9f812a6 3433 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
a5848695 3434 msg.body.get_mac_info.u8MacAddress = pu8MacAddress;
a4ab1ade 3435 msg.drv = hif_drv;
ae4dfa57 3436
31390eec
LK
3437 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3438 if (result) {
c5c77ba1 3439 PRINT_ER("Failed to send get mac address\n");
e6e12661 3440 return -EFAULT;
c5c77ba1
JK
3441 }
3442
2d25af87 3443 down(&hif_sema_wait_response);
31390eec 3444 return result;
c5c77ba1
JK
3445}
3446
a4ab1ade 3447s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
c5c77ba1 3448{
31390eec 3449 s32 result = 0;
143eb95a 3450 struct host_if_msg msg;
c5c77ba1
JK
3451
3452 PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
3453
143eb95a 3454 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3455 msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
15326e28 3456 memcpy(msg.body.set_mac_info.u8MacAddress, pu8MacAddress, ETH_ALEN);
a4ab1ade 3457 msg.drv = hif_drv;
c5c77ba1 3458
31390eec
LK
3459 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3460 if (result)
c5c77ba1 3461 PRINT_ER("Failed to send message queue: Set mac address\n");
c5c77ba1 3462
31390eec 3463 return result;
c5c77ba1
JK
3464}
3465
a4ab1ade
TC
3466s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3467 u8 *pu8PassPhrase, u8 u8Psklength)
c5c77ba1 3468{
e9e0c260 3469 struct wid strWID;
c5c77ba1 3470
daaf16ba 3471 strWID.id = (u16)WID_11I_PSK;
416d8321 3472 strWID.type = WID_STR;
2fd3e443 3473 strWID.size = u8Psklength;
900bb4a6 3474 strWID.val = pu8PassPhrase;
c5c77ba1 3475
b68d820b 3476 return 0;
c5c77ba1
JK
3477}
3478
a4ab1ade 3479s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
c5c77ba1 3480{
e9e0c260 3481 struct wid strWID;
c5c77ba1 3482
daaf16ba 3483 strWID.id = (u16)WID_START_SCAN_REQ;
416d8321 3484 strWID.type = WID_CHAR;
900bb4a6 3485 strWID.val = (s8 *)&scanSource;
2fd3e443 3486 strWID.size = sizeof(char);
c5c77ba1 3487
b68d820b 3488 return 0;
c5c77ba1
JK
3489}
3490
a4ab1ade 3491s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
c5c77ba1 3492{
e9e0c260 3493 struct wid strWID;
c5c77ba1 3494
daaf16ba 3495 strWID.id = (u16)WID_START_SCAN_REQ;
416d8321 3496 strWID.type = WID_CHAR;
900bb4a6 3497 strWID.val = (s8 *)pu8ScanSource;
2fd3e443 3498 strWID.size = sizeof(char);
c5c77ba1 3499
b68d820b 3500 return 0;
c5c77ba1
JK
3501}
3502
a4ab1ade
TC
3503s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
3504 const u8 *pu8ssid, size_t ssidLen,
3505 const u8 *pu8IEs, size_t IEsLen,
3506 wilc_connect_result pfConnectResult, void *pvUserArg,
3507 u8 u8security, enum AUTHTYPE tenuAuth_type,
3508 u8 u8channel, void *pJoinParams)
c5c77ba1 3509{
31390eec 3510 s32 result = 0;
143eb95a 3511 struct host_if_msg msg;
c5c77ba1 3512
a4ab1ade 3513 if (!hif_drv || pfConnectResult == NULL) {
24db713f 3514 PRINT_ER("Driver is null\n");
77178807 3515 return -EFAULT;
24db713f 3516 }
c5c77ba1 3517
c5c77ba1
JK
3518 if (pJoinParams == NULL) {
3519 PRINT_ER("Unable to Join - JoinParams is NULL\n");
24db713f 3520 return -EFAULT;
c5c77ba1 3521 }
24db713f 3522
143eb95a 3523 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3524
a9f812a6 3525 msg.id = HOST_IF_MSG_CONNECT;
c5c77ba1 3526
a64fd677 3527 msg.body.con_info.security = u8security;
61b4fd02 3528 msg.body.con_info.auth_type = tenuAuth_type;
0d1527e6 3529 msg.body.con_info.ch = u8channel;
6abcc11d 3530 msg.body.con_info.result = pfConnectResult;
8f38db89 3531 msg.body.con_info.arg = pvUserArg;
f2bed2ca 3532 msg.body.con_info.params = pJoinParams;
a4ab1ade 3533 msg.drv = hif_drv ;
c5c77ba1
JK
3534
3535 if (pu8bssid != NULL) {
9254db07
LK
3536 msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
3537 memcpy(msg.body.con_info.bssid, pu8bssid, 6);
c5c77ba1
JK
3538 }
3539
3540 if (pu8ssid != NULL) {
8b3c9fa6 3541 msg.body.con_info.ssid_len = ssidLen;
f7bbd9cf
LK
3542 msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL);
3543 memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen);
c5c77ba1
JK
3544 }
3545
3546 if (pu8IEs != NULL) {
b59d5c5b 3547 msg.body.con_info.ies_len = IEsLen;
2ea158c4
LK
3548 msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3549 memcpy(msg.body.con_info.ies, pu8IEs, IEsLen);
c5c77ba1 3550 }
a4ab1ade
TC
3551 if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING)
3552 hif_drv->enuHostIFstate = HOST_IF_CONNECTING;
78174ada 3553 else
a4ab1ade 3554 PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate);
c5c77ba1 3555
31390eec
LK
3556 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3557 if (result) {
c5c77ba1 3558 PRINT_ER("Failed to send message queue: Set join request\n");
24db713f 3559 return -EFAULT;
c5c77ba1
JK
3560 }
3561
a4ab1ade
TC
3562 hif_drv->hConnectTimer.data = (unsigned long)hif_drv;
3563 mod_timer(&hif_drv->hConnectTimer,
9eb06643 3564 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
c5c77ba1 3565
31390eec 3566 return result;
c5c77ba1
JK
3567}
3568
a4ab1ade 3569s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
c5c77ba1 3570{
31390eec 3571 s32 result = 0;
143eb95a 3572 struct host_if_msg msg;
c5c77ba1 3573
77178807
LK
3574 if (!join_req)
3575 return -EFAULT;
c5c77ba1 3576
a4ab1ade 3577 if (!hif_drv) {
24db713f 3578 PRINT_ER("Driver is null\n");
77178807 3579 return -EFAULT;
24db713f 3580 }
c5c77ba1 3581
a9f812a6 3582 msg.id = HOST_IF_MSG_FLUSH_CONNECT;
a4ab1ade 3583 msg.drv = hif_drv;
c5c77ba1 3584
31390eec
LK
3585 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3586 if (result) {
c5c77ba1 3587 PRINT_ER("Failed to send message queue: Flush join request\n");
24db713f 3588 return -EFAULT;
c5c77ba1
JK
3589 }
3590
31390eec 3591 return result;
c5c77ba1
JK
3592}
3593
a4ab1ade 3594s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
c5c77ba1 3595{
31390eec 3596 s32 result = 0;
143eb95a 3597 struct host_if_msg msg;
c5c77ba1 3598
a4ab1ade 3599 if (!hif_drv) {
24db713f
LK
3600 PRINT_ER("Driver is null\n");
3601 return -EFAULT;
c5c77ba1
JK
3602 }
3603
143eb95a 3604 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3605
a9f812a6 3606 msg.id = HOST_IF_MSG_DISCONNECT;
a4ab1ade 3607 msg.drv = hif_drv;
c5c77ba1 3608
31390eec
LK
3609 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3610 if (result)
c5c77ba1 3611 PRINT_ER("Failed to send message queue: disconnect\n");
ae4dfa57 3612
a4ab1ade 3613 down(&hif_drv->hSemTestDisconnectBlock);
c5c77ba1 3614
31390eec 3615 return result;
c5c77ba1
JK
3616}
3617
a4ab1ade 3618s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
c5c77ba1 3619{
e9e0c260 3620 struct wid strWID;
c5c77ba1 3621
daaf16ba 3622 strWID.id = (u16)WID_DISCONNECT;
416d8321 3623 strWID.type = WID_CHAR;
900bb4a6 3624 strWID.val = (s8 *)&assoc_id;
2fd3e443 3625 strWID.size = sizeof(char);
c5c77ba1 3626
b68d820b 3627 return 0;
c5c77ba1
JK
3628}
3629
8c8360b3
LK
3630s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
3631 u8 *pu8AssocReqInfo,
3632 u32 u32AssocReqInfoLen)
c5c77ba1 3633{
e9e0c260 3634 struct wid strWID;
c5c77ba1 3635
daaf16ba 3636 strWID.id = (u16)WID_ASSOC_REQ_INFO;
416d8321 3637 strWID.type = WID_STR;
900bb4a6 3638 strWID.val = pu8AssocReqInfo;
2fd3e443 3639 strWID.size = u32AssocReqInfoLen;
c5c77ba1 3640
b68d820b 3641 return 0;
c5c77ba1
JK
3642}
3643
8c8360b3
LK
3644s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
3645 u8 *pu8AssocRespInfo,
3646 u32 u32MaxAssocRespInfoLen,
3647 u32 *pu32RcvdAssocRespInfoLen)
c5c77ba1 3648{
31390eec 3649 s32 result = 0;
e9e0c260 3650 struct wid strWID;
c5c77ba1 3651
a4ab1ade 3652 if (!hif_drv) {
24db713f
LK
3653 PRINT_ER("Driver is null\n");
3654 return -EFAULT;
c5c77ba1
JK
3655 }
3656
daaf16ba 3657 strWID.id = (u16)WID_ASSOC_RES_INFO;
416d8321 3658 strWID.type = WID_STR;
900bb4a6 3659 strWID.val = pu8AssocRespInfo;
2fd3e443 3660 strWID.size = u32MaxAssocRespInfoLen;
c5c77ba1 3661
31390eec 3662 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 3663 get_id_from_handler(hif_drv));
31390eec 3664 if (result) {
c5c77ba1 3665 *pu32RcvdAssocRespInfoLen = 0;
24db713f
LK
3666 PRINT_ER("Failed to send association response config packet\n");
3667 return -EINVAL;
c5c77ba1 3668 } else {
2fd3e443 3669 *pu32RcvdAssocRespInfoLen = strWID.size;
c5c77ba1
JK
3670 }
3671
31390eec 3672 return result;
c5c77ba1
JK
3673}
3674
8c8360b3
LK
3675s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
3676 u8 *pu8RxPowerLevel,
3677 u32 u32RxPowerLevelLen)
c5c77ba1 3678{
e9e0c260 3679 struct wid strWID;
c5c77ba1 3680
daaf16ba 3681 strWID.id = (u16)WID_RX_POWER_LEVEL;
416d8321 3682 strWID.type = WID_STR;
900bb4a6 3683 strWID.val = pu8RxPowerLevel;
2fd3e443 3684 strWID.size = u32RxPowerLevelLen;
c5c77ba1 3685
b68d820b 3686 return 0;
c5c77ba1
JK
3687}
3688
a4ab1ade 3689int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
c5c77ba1 3690{
792fb25b 3691 int result;
143eb95a 3692 struct host_if_msg msg;
c5c77ba1 3693
a4ab1ade 3694 if (!hif_drv) {
24db713f
LK
3695 PRINT_ER("driver is null\n");
3696 return -EFAULT;
3697 }
c5c77ba1 3698
143eb95a 3699 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3700 msg.id = HOST_IF_MSG_SET_CHANNEL;
730ee059 3701 msg.body.channel_info.set_ch = channel;
a4ab1ade 3702 msg.drv = hif_drv;
c5c77ba1 3703
cb067dcf 3704 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
1ef58e42 3705 if (result) {
24db713f 3706 PRINT_ER("wilc mq send fail\n");
792fb25b 3707 return -EINVAL;
c5c77ba1
JK
3708 }
3709
792fb25b 3710 return 0;
c5c77ba1
JK
3711}
3712
244efb1f 3713int host_int_wait_msg_queue_idle(void)
c5c77ba1 3714{
6d6c9bbb 3715 int result = 0;
c5c77ba1 3716
143eb95a 3717 struct host_if_msg msg;
143eb95a 3718 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3719 msg.id = HOST_IF_MSG_Q_IDLE;
cb067dcf 3720 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
6d6c9bbb 3721 if (result) {
24db713f 3722 PRINT_ER("wilc mq send fail\n");
6d6c9bbb 3723 result = -EINVAL;
c5c77ba1
JK
3724 }
3725
2d25af87 3726 down(&hif_sema_wait_response);
c5c77ba1 3727
6d6c9bbb 3728 return result;
c5c77ba1
JK
3729}
3730
a4ab1ade 3731int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
c5c77ba1 3732{
a094101c 3733 int result = 0;
c5c77ba1 3734
143eb95a 3735 struct host_if_msg msg;
143eb95a 3736 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3737 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
a4ab1ade
TC
3738 msg.body.drv.u32Address = get_id_from_handler(hif_drv);
3739 msg.drv = hif_drv;
c5c77ba1 3740
cb067dcf 3741 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a094101c 3742 if (result) {
24db713f 3743 PRINT_ER("wilc mq send fail\n");
a094101c 3744 result = -EINVAL;
c5c77ba1
JK
3745 }
3746
a094101c 3747 return result;
c5c77ba1
JK
3748}
3749
a4ab1ade 3750int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
c5c77ba1 3751{
a0c1ee0c 3752 int result = 0;
c5c77ba1 3753
143eb95a 3754 struct host_if_msg msg;
143eb95a 3755 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3756 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
49fb6f71 3757 msg.body.mode.u32Mode = mode;
a4ab1ade 3758 msg.drv = hif_drv;
c5c77ba1 3759
cb067dcf 3760 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
a0c1ee0c 3761 if (result) {
24db713f 3762 PRINT_ER("wilc mq send fail\n");
a0c1ee0c 3763 result = -EINVAL;
c5c77ba1
JK
3764 }
3765
a0c1ee0c 3766 return result;
c5c77ba1
JK
3767}
3768
a4ab1ade 3769s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
c5c77ba1 3770{
31390eec 3771 s32 result = 0;
143eb95a 3772 struct host_if_msg msg;
c5c77ba1 3773
a4ab1ade 3774 if (!hif_drv) {
24db713f
LK
3775 PRINT_ER("driver is null\n");
3776 return -EFAULT;
c5c77ba1
JK
3777 }
3778
143eb95a 3779 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3780
a9f812a6 3781 msg.id = HOST_IF_MSG_GET_CHNL;
a4ab1ade 3782 msg.drv = hif_drv;
c5c77ba1 3783
31390eec
LK
3784 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3785 if (result)
24db713f 3786 PRINT_ER("wilc mq send fail\n");
a4ab1ade 3787 down(&hif_drv->hSemGetCHNL);
c5c77ba1 3788
95ebb0ff 3789 *pu8ChNo = ch_no;
c5c77ba1 3790
31390eec 3791 return result;
c5c77ba1
JK
3792}
3793
a4ab1ade
TC
3794s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
3795 const u8 *mac, u32 *pu32InactiveTime)
c5c77ba1 3796{
31390eec 3797 s32 result = 0;
143eb95a 3798 struct host_if_msg msg;
c5c77ba1 3799
a4ab1ade 3800 if (!hif_drv) {
24db713f
LK
3801 PRINT_ER("driver is null\n");
3802 return -EFAULT;
c5c77ba1
JK
3803 }
3804
143eb95a 3805 memset(&msg, 0, sizeof(struct host_if_msg));
8c8360b3 3806 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
c5c77ba1 3807
a9f812a6 3808 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
a4ab1ade 3809 msg.drv = hif_drv;
c5c77ba1 3810
31390eec
LK
3811 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3812 if (result)
c5c77ba1
JK
3813 PRINT_ER("Failed to send get host channel param's message queue ");
3814
a4ab1ade 3815 down(&hif_drv->hSemInactiveTime);
c5c77ba1 3816
ad26906f 3817 *pu32InactiveTime = inactive_time;
c5c77ba1 3818
31390eec 3819 return result;
c5c77ba1 3820}
108b3439 3821
a4ab1ade 3822s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
c5c77ba1 3823{
31390eec 3824 s32 result = 0;
e9e0c260 3825 struct wid strWID;
c5c77ba1 3826
a4ab1ade 3827 if (!hif_drv) {
24db713f
LK
3828 PRINT_ER("driver is null\n");
3829 return -EFAULT;
c5c77ba1
JK
3830 }
3831
daaf16ba 3832 strWID.id = (u16)WID_MEMORY_ADDRESS;
416d8321 3833 strWID.type = WID_INT;
900bb4a6 3834 strWID.val = (s8 *)pu32TestMemAddr;
2fd3e443 3835 strWID.size = sizeof(u32);
c5c77ba1 3836
31390eec 3837 result = send_config_pkt(GET_CFG, &strWID, 1,
8c8360b3 3838 get_id_from_handler(hif_drv));
ae4dfa57 3839
31390eec 3840 if (result) {
24db713f
LK
3841 PRINT_ER("Failed to get wid value\n");
3842 return -EINVAL;
c5c77ba1
JK
3843 } else {
3844 PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
3845
3846 }
3847
31390eec 3848 return result;
c5c77ba1
JK
3849}
3850
a4ab1ade 3851s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
c5c77ba1 3852{
31390eec 3853 s32 result = 0;
143eb95a 3854 struct host_if_msg msg;
143eb95a 3855 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3856
a9f812a6 3857 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 3858 msg.drv = hif_drv;
c5c77ba1 3859
31390eec
LK
3860 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3861 if (result) {
c5c77ba1 3862 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3863 return -EFAULT;
c5c77ba1
JK
3864 }
3865
a4ab1ade 3866 down(&hif_drv->hSemGetRSSI);
c5c77ba1
JK
3867
3868
3869 if (ps8Rssi == NULL) {
3870 PRINT_ER("RSS pointer value is null");
e6e12661 3871 return -EFAULT;
c5c77ba1
JK
3872 }
3873
144b7b23 3874 *ps8Rssi = rssi;
c5c77ba1 3875
31390eec 3876 return result;
c5c77ba1
JK
3877}
3878
a4ab1ade 3879s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
c5c77ba1 3880{
143eb95a 3881 struct host_if_msg msg;
31390eec 3882 s32 result = 0;
143eb95a 3883 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3884
a9f812a6 3885 msg.id = HOST_IF_MSG_GET_LINKSPEED;
a4ab1ade 3886 msg.drv = hif_drv;
c5c77ba1 3887
31390eec
LK
3888 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3889 if (result) {
c5c77ba1 3890 PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
e6e12661 3891 return -EFAULT;
c5c77ba1
JK
3892 }
3893
a4ab1ade 3894 down(&hif_drv->hSemGetLINKSPEED);
c5c77ba1
JK
3895
3896
3897 if (ps8lnkspd == NULL) {
3898 PRINT_ER("LINKSPEED pointer value is null");
e6e12661 3899 return -EFAULT;
c5c77ba1
JK
3900 }
3901
75327a02 3902 *ps8lnkspd = link_speed;
c5c77ba1 3903
31390eec 3904 return result;
c5c77ba1
JK
3905}
3906
a4ab1ade 3907s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
c5c77ba1 3908{
31390eec 3909 s32 result = 0;
143eb95a 3910 struct host_if_msg msg;
143eb95a 3911 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3912
a9f812a6 3913 msg.id = HOST_IF_MSG_GET_STATISTICS;
e60831e9 3914 msg.body.data = (char *)pstrStatistics;
a4ab1ade 3915 msg.drv = hif_drv;
ae4dfa57 3916
31390eec
LK
3917 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3918 if (result) {
c5c77ba1 3919 PRINT_ER("Failed to send get host channel param's message queue ");
e6e12661 3920 return -EFAULT;
c5c77ba1
JK
3921 }
3922
2d25af87 3923 down(&hif_sema_wait_response);
31390eec 3924 return result;
c5c77ba1
JK
3925}
3926
a4ab1ade
TC
3927s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
3928 u8 u8ScanType, u8 *pu8ChnlFreqList,
3929 u8 u8ChnlListLen, const u8 *pu8IEs,
3930 size_t IEsLen, wilc_scan_result ScanResult,
3931 void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
c5c77ba1 3932{
31390eec 3933 s32 result = 0;
143eb95a 3934 struct host_if_msg msg;
c5c77ba1 3935
a4ab1ade
TC
3936 if (!hif_drv || ScanResult == NULL) {
3937 PRINT_ER("hif_drv or ScanResult = NULL\n");
24db713f
LK
3938 return -EFAULT;
3939 }
c5c77ba1 3940
143eb95a 3941 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 3942
a9f812a6 3943 msg.id = HOST_IF_MSG_SCAN;
c5c77ba1
JK
3944
3945 if (pstrHiddenNetwork != NULL) {
629b9ca0
LK
3946 msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
3947 msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
c5c77ba1
JK
3948
3949 } else
3950 PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
3951
a4ab1ade 3952 msg.drv = hif_drv;
42568898 3953 msg.body.scan_info.src = u8ScanSource;
1e276c88 3954 msg.body.scan_info.type = u8ScanType;
c17c6da6 3955 msg.body.scan_info.result = ScanResult;
5f2b50c8 3956 msg.body.scan_info.arg = pvUserArg;
4528bdb5 3957
f97bd9ca 3958 msg.body.scan_info.ch_list_len = u8ChnlListLen;
82eeb0ad
LK
3959 msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL);
3960 memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen);
c5c77ba1 3961
7b1f76cd 3962 msg.body.scan_info.ies_len = IEsLen;
d6f19aa5
LK
3963 msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3964 memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen);
c5c77ba1 3965
31390eec
LK
3966 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3967 if (result) {
24db713f
LK
3968 PRINT_ER("Error in sending message queue\n");
3969 return -EINVAL;
c5c77ba1
JK
3970 }
3971
c5c77ba1 3972 PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
a4ab1ade
TC
3973 hif_drv->hScanTimer.data = (unsigned long)hif_drv;
3974 mod_timer(&hif_drv->hScanTimer,
9eb06643 3975 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
c5c77ba1 3976
31390eec 3977 return result;
c5c77ba1 3978}
ae4dfa57 3979
a4ab1ade
TC
3980s32 hif_set_cfg(struct host_if_drv *hif_drv,
3981 struct cfg_param_val *pstrCfgParamVal)
c5c77ba1 3982{
31390eec 3983 s32 result = 0;
143eb95a 3984 struct host_if_msg msg;
c5c77ba1
JK
3985
3986
a4ab1ade
TC
3987 if (!hif_drv) {
3988 PRINT_ER("hif_drv NULL\n");
24db713f
LK
3989 return -EFAULT;
3990 }
ae4dfa57 3991
143eb95a 3992 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 3993 msg.id = HOST_IF_MSG_CFG_PARAMS;
221371e5 3994 msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
a4ab1ade 3995 msg.drv = hif_drv;
c5c77ba1 3996
31390eec 3997 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 3998
31390eec 3999 return result;
c5c77ba1
JK
4000}
4001
a4ab1ade 4002s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
c5c77ba1 4003{
31390eec 4004 s32 result = 0;
c5c77ba1 4005
a4ab1ade 4006 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4007
a4ab1ade
TC
4008 if (!hif_drv) {
4009 PRINT_ER("hif_drv NULL\n");
24db713f 4010 return -EFAULT;
c5c77ba1
JK
4011 }
4012 PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
4013 switch (u16WID) {
4014
4015 case WID_BSS_TYPE:
a4ab1ade 4016 *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type;
c5c77ba1
JK
4017 break;
4018
4019 case WID_AUTH_TYPE:
a4ab1ade 4020 *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type;
c5c77ba1
JK
4021 break;
4022
4023 case WID_AUTH_TIMEOUT:
a4ab1ade 4024 *pu16WID_Value = hif_drv->strCfgValues.auth_timeout;
c5c77ba1
JK
4025 break;
4026
4027 case WID_POWER_MANAGEMENT:
a4ab1ade 4028 *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode;
c5c77ba1
JK
4029 break;
4030
4031 case WID_SHORT_RETRY_LIMIT:
a4ab1ade 4032 *pu16WID_Value = hif_drv->strCfgValues.short_retry_limit;
c5c77ba1
JK
4033 break;
4034
4035 case WID_LONG_RETRY_LIMIT:
a4ab1ade 4036 *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit;
c5c77ba1
JK
4037 break;
4038
4039 case WID_FRAG_THRESHOLD:
a4ab1ade 4040 *pu16WID_Value = hif_drv->strCfgValues.frag_threshold;
c5c77ba1
JK
4041 break;
4042
4043 case WID_RTS_THRESHOLD:
a4ab1ade 4044 *pu16WID_Value = hif_drv->strCfgValues.rts_threshold;
c5c77ba1
JK
4045 break;
4046
4047 case WID_PREAMBLE:
a4ab1ade 4048 *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type;
c5c77ba1
JK
4049 break;
4050
4051 case WID_SHORT_SLOT_ALLOWED:
a4ab1ade 4052 *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed;
c5c77ba1
JK
4053 break;
4054
4055 case WID_11N_TXOP_PROT_DISABLE:
a4ab1ade 4056 *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled;
c5c77ba1
JK
4057 break;
4058
4059 case WID_BEACON_INTERVAL:
a4ab1ade 4060 *pu16WID_Value = hif_drv->strCfgValues.beacon_interval;
c5c77ba1
JK
4061 break;
4062
4063 case WID_DTIM_PERIOD:
a4ab1ade 4064 *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period;
c5c77ba1
JK
4065 break;
4066
4067 case WID_SITE_SURVEY:
a4ab1ade 4068 *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled;
c5c77ba1
JK
4069 break;
4070
4071 case WID_SITE_SURVEY_SCAN_TIME:
a4ab1ade 4072 *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time;
c5c77ba1
JK
4073 break;
4074
4075 case WID_ACTIVE_SCAN_TIME:
a4ab1ade 4076 *pu16WID_Value = hif_drv->strCfgValues.active_scan_time;
c5c77ba1
JK
4077 break;
4078
4079 case WID_PASSIVE_SCAN_TIME:
a4ab1ade 4080 *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time;
c5c77ba1
JK
4081 break;
4082
4083 case WID_CURRENT_TX_RATE:
a4ab1ade 4084 *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate;
c5c77ba1
JK
4085 break;
4086
4087 default:
4088 break;
4089 }
4090
a4ab1ade 4091 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4092
31390eec 4093 return result;
c5c77ba1
JK
4094}
4095
c5c77ba1 4096void host_int_send_join_leave_info_to_host
72ed4dc7 4097 (u16 assocId, u8 *stationAddr, bool joining)
c5c77ba1
JK
4098{
4099}
c5c77ba1 4100
93dee8ee 4101static void GetPeriodicRSSI(unsigned long arg)
c5c77ba1 4102{
a4ab1ade 4103 struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
78c87591 4104
a4ab1ade 4105 if (!hif_drv) {
c5c77ba1
JK
4106 PRINT_ER("Driver handler is NULL\n");
4107 return;
4108 }
4109
a4ab1ade 4110 if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) {
31390eec 4111 s32 result = 0;
143eb95a 4112 struct host_if_msg msg;
c5c77ba1 4113
143eb95a 4114 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4115
a9f812a6 4116 msg.id = HOST_IF_MSG_GET_RSSI;
a4ab1ade 4117 msg.drv = hif_drv;
c5c77ba1 4118
31390eec
LK
4119 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4120 if (result) {
c5c77ba1
JK
4121 PRINT_ER("Failed to send get host channel param's message queue ");
4122 return;
4123 }
4124 }
262f55e1
LK
4125 periodic_rssi.data = (unsigned long)hif_drv;
4126 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4127}
4128
4129
4130void host_int_send_network_info_to_host
ca356ada 4131 (u8 *macStartAddress, u16 u16RxFrameLen, s8 s8Rssi)
c5c77ba1
JK
4132{
4133}
ae4dfa57 4134
a4ab1ade 4135s32 host_int_init(struct host_if_drv **hif_drv_handler)
c5c77ba1 4136{
5b09bd32 4137 s32 result = 0;
a4ab1ade 4138 struct host_if_drv *hif_drv;
d42ab083 4139 int err;
c5c77ba1 4140
c5c77ba1
JK
4141 PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
4142
ca8540e4 4143 scan_while_connected = false;
c5c77ba1 4144
2d25af87 4145 sema_init(&hif_sema_wait_response, 0);
c5c77ba1 4146
a4ab1ade
TC
4147 hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
4148 if (!hif_drv) {
5b09bd32 4149 result = -ENOMEM;
17db84eb 4150 goto _fail_;
c5c77ba1 4151 }
a4ab1ade
TC
4152 *hif_drv_handler = hif_drv;
4153 err = add_handler_in_list(hif_drv);
d42ab083 4154 if (err) {
5b09bd32 4155 result = -EFAULT;
d42ab083
JK
4156 goto _fail_timer_2;
4157 }
c5c77ba1 4158
72ed4dc7 4159 g_obtainingIP = false;
c5c77ba1 4160
a4ab1ade 4161 PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
c5c77ba1 4162 if (clients_count == 0) {
834e0cb0 4163 sema_init(&hif_sema_thread, 0);
27ff2168 4164 sema_init(&hif_sema_driver, 0);
440e8993 4165 sema_init(&hif_sema_deinit, 1);
83383ea3
AB
4166 }
4167
a4ab1ade
TC
4168 sema_init(&hif_drv->hSemTestKeyBlock, 0);
4169 sema_init(&hif_drv->hSemTestDisconnectBlock, 0);
4170 sema_init(&hif_drv->hSemGetRSSI, 0);
4171 sema_init(&hif_drv->hSemGetLINKSPEED, 0);
4172 sema_init(&hif_drv->hSemGetCHNL, 0);
4173 sema_init(&hif_drv->hSemInactiveTime, 0);
c5c77ba1 4174
c5c77ba1
JK
4175 PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
4176
4177 if (clients_count == 0) {
cb067dcf 4178 result = wilc_mq_create(&hif_msg_q);
c5c77ba1 4179
5b09bd32 4180 if (result < 0) {
c5c77ba1
JK
4181 PRINT_ER("Failed to creat MQ\n");
4182 goto _fail_;
4183 }
c2115d8e
LK
4184
4185 hif_thread_handler = kthread_run(hostIFthread, NULL, "WILC_kthread");
4186
4187 if (IS_ERR(hif_thread_handler)) {
c5c77ba1 4188 PRINT_ER("Failed to creat Thread\n");
5b09bd32 4189 result = -EFAULT;
c5c77ba1
JK
4190 goto _fail_mq_;
4191 }
262f55e1 4192 setup_timer(&periodic_rssi, GetPeriodicRSSI,
a4ab1ade 4193 (unsigned long)hif_drv);
262f55e1 4194 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
c5c77ba1
JK
4195 }
4196
a4ab1ade 4197 setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0);
c5c77ba1 4198
a4ab1ade 4199 setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0);
c5c77ba1 4200
a4ab1ade 4201 setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0);
c5c77ba1 4202
a4ab1ade
TC
4203 sema_init(&(hif_drv->gtOsCfgValuesSem), 1);
4204 down(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4205
a4ab1ade 4206 hif_drv->enuHostIFstate = HOST_IF_IDLE;
a4ab1ade
TC
4207 hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
4208 hif_drv->strCfgValues.scan_source = DEFAULT_SCAN;
4209 hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
4210 hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
4211 hif_drv->strCfgValues.curr_tx_rate = AUTORATE;
c5c77ba1 4212
a4ab1ade 4213 hif_drv->u64P2p_MgmtTimeout = 0;
c5c77ba1 4214
c5c77ba1
JK
4215 PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n",
4216
a4ab1ade
TC
4217 hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source,
4218 hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time,
4219 hif_drv->strCfgValues.curr_tx_rate);
c5c77ba1 4220
a4ab1ade 4221 up(&hif_drv->gtOsCfgValuesSem);
c5c77ba1 4222
ae4dfa57 4223 clients_count++;
c5c77ba1 4224
5b09bd32 4225 return result;
c5c77ba1 4226
c5c77ba1 4227_fail_timer_2:
a4ab1ade
TC
4228 up(&hif_drv->gtOsCfgValuesSem);
4229 del_timer_sync(&hif_drv->hConnectTimer);
4230 del_timer_sync(&hif_drv->hScanTimer);
c2115d8e 4231 kthread_stop(hif_thread_handler);
c5c77ba1 4232_fail_mq_:
cb067dcf 4233 wilc_mq_destroy(&hif_msg_q);
c5c77ba1 4234_fail_:
5b09bd32 4235 return result;
c5c77ba1 4236}
c5c77ba1 4237
a4ab1ade 4238s32 host_int_deinit(struct host_if_drv *hif_drv)
c5c77ba1 4239{
31390eec 4240 s32 result = 0;
143eb95a 4241 struct host_if_msg msg;
d42ab083 4242 int ret;
c5c77ba1 4243
a4ab1ade
TC
4244 if (!hif_drv) {
4245 PRINT_ER("hif_drv = NULL\n");
c5c77ba1
JK
4246 return 0;
4247 }
4248
440e8993 4249 down(&hif_sema_deinit);
c5c77ba1 4250
a4ab1ade 4251 terminated_handle = hif_drv;
c5c77ba1
JK
4252 PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
4253
a4ab1ade 4254 if (del_timer_sync(&hif_drv->hScanTimer)) {
03b2d5e7 4255 PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
c5c77ba1
JK
4256 }
4257
a4ab1ade 4258 if (del_timer_sync(&hif_drv->hConnectTimer)) {
03b2d5e7 4259 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1
JK
4260 }
4261
262f55e1 4262 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4263 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
c5c77ba1 4264
a4ab1ade 4265 del_timer_sync(&hif_drv->hRemainOnChannel);
c5c77ba1 4266
218dc407 4267 host_int_set_wfi_drv_handler(NULL);
27ff2168 4268 down(&hif_sema_driver);
c5c77ba1 4269
a4ab1ade
TC
4270 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
4271 hif_drv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
4272 hif_drv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
c5c77ba1 4273
a4ab1ade 4274 hif_drv->strWILC_UsrScanReq.pfUserScanResult = NULL;
c5c77ba1 4275 }
c5c77ba1 4276
a4ab1ade 4277 hif_drv->enuHostIFstate = HOST_IF_IDLE;
c5c77ba1 4278
ca8540e4 4279 scan_while_connected = false;
c5c77ba1 4280
143eb95a 4281 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4282
4283 if (clients_count == 1) {
262f55e1 4284 if (del_timer_sync(&periodic_rssi))
03b2d5e7 4285 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
262f55e1 4286
a9f812a6 4287 msg.id = HOST_IF_MSG_EXIT;
a4ab1ade 4288 msg.drv = hif_drv;
c5c77ba1 4289
31390eec
LK
4290 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4291 if (result != 0)
4292 PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
c5c77ba1 4293
834e0cb0 4294 down(&hif_sema_thread);
c5c77ba1 4295
cb067dcf 4296 wilc_mq_destroy(&hif_msg_q);
c5c77ba1
JK
4297 }
4298
a4ab1ade 4299 down(&(hif_drv->gtOsCfgValuesSem));
c5c77ba1 4300
a4ab1ade 4301 ret = remove_handler_in_list(hif_drv);
d42ab083 4302 if (ret)
31390eec 4303 result = -ENOENT;
d42ab083 4304
a4ab1ade 4305 kfree(hif_drv);
c5c77ba1 4306
ae4dfa57 4307 clients_count--;
b1413b60 4308 terminated_handle = NULL;
440e8993 4309 up(&hif_sema_deinit);
31390eec 4310 return result;
c5c77ba1
JK
4311}
4312
4e4467fd 4313void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4314{
31390eec 4315 s32 result = 0;
143eb95a 4316 struct host_if_msg msg;
d42ab083 4317 int id;
a4ab1ade 4318 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4319
d42ab083 4320 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4321 hif_drv = get_handler_from_id(id);
c5c77ba1
JK
4322
4323
4324
4325
a4ab1ade
TC
4326 if (!hif_drv || hif_drv == terminated_handle) {
4327 PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
c5c77ba1
JK
4328 return;
4329 }
4330
143eb95a 4331 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4332
a9f812a6 4333 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
a4ab1ade 4334 msg.drv = hif_drv;
c5c77ba1 4335
3bffac68 4336 msg.body.net_info.len = u32Length;
b021b80b
LK
4337 msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4338 memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4339
31390eec
LK
4340 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4341 if (result)
4342 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
c5c77ba1
JK
4343}
4344
4e4467fd 4345void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4346{
31390eec 4347 s32 result = 0;
143eb95a 4348 struct host_if_msg msg;
d42ab083 4349 int id;
a4ab1ade 4350 struct host_if_drv *hif_drv = NULL;
c5c77ba1 4351
440e8993 4352 down(&hif_sema_deinit);
c5c77ba1 4353
d42ab083 4354 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4355 hif_drv = get_handler_from_id(id);
03b2d5e7 4356 PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
c5c77ba1
JK
4357
4358
a4ab1ade 4359 if (!hif_drv || hif_drv == terminated_handle) {
c5c77ba1 4360 PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
440e8993 4361 up(&hif_sema_deinit);
c5c77ba1
JK
4362 return;
4363 }
4364
a4ab1ade 4365 if (!hif_drv->strWILC_UsrConnReq.pfUserConnectResult) {
c5c77ba1 4366 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
440e8993 4367 up(&hif_sema_deinit);
c5c77ba1
JK
4368 return;
4369 }
4370
143eb95a 4371 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4372
4373
a9f812a6 4374 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
a4ab1ade 4375 msg.drv = hif_drv;
c5c77ba1 4376
f94f4889 4377 msg.body.async_info.len = u32Length;
33722ac7
LK
4378 msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4379 memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
c5c77ba1 4380
31390eec
LK
4381 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4382 if (result)
4383 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
c5c77ba1 4384
440e8993 4385 up(&hif_sema_deinit);
c5c77ba1
JK
4386}
4387
4e4467fd 4388void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
c5c77ba1 4389{
31390eec 4390 s32 result = 0;
143eb95a 4391 struct host_if_msg msg;
d42ab083 4392 int id;
a4ab1ade 4393 struct host_if_drv *hif_drv = NULL;
78c87591 4394
d42ab083 4395 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
a4ab1ade 4396 hif_drv = get_handler_from_id(id);
c5c77ba1
JK
4397
4398
a4ab1ade 4399 PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
c5c77ba1 4400
a4ab1ade 4401 if (!hif_drv || hif_drv == terminated_handle)
c5c77ba1 4402 return;
c5c77ba1 4403
a4ab1ade 4404 if (hif_drv->strWILC_UsrScanReq.pfUserScanResult) {
143eb95a 4405 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4406
a9f812a6 4407 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
a4ab1ade 4408 msg.drv = hif_drv;
c5c77ba1 4409
31390eec
LK
4410 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4411 if (result)
4412 PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
c5c77ba1
JK
4413 }
4414
4415
4416 return;
4417
4418}
4419
a4ab1ade
TC
4420s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
4421 u32 u32duration, u16 chan,
4422 wilc_remain_on_chan_expired RemainOnChanExpired,
4423 wilc_remain_on_chan_ready RemainOnChanReady,
4424 void *pvUserArg)
c5c77ba1 4425{
31390eec 4426 s32 result = 0;
143eb95a 4427 struct host_if_msg msg;
c5c77ba1 4428
a4ab1ade 4429 if (!hif_drv) {
24db713f
LK
4430 PRINT_ER("driver is null\n");
4431 return -EFAULT;
4432 }
c5c77ba1 4433
143eb95a 4434 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4435
a9f812a6 4436 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
070d365c
TC
4437 msg.body.remain_on_ch.u16Channel = chan;
4438 msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
4439 msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
4440 msg.body.remain_on_ch.pVoid = pvUserArg;
4441 msg.body.remain_on_ch.u32duration = u32duration;
4442 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
a4ab1ade 4443 msg.drv = hif_drv;
143eb95a 4444
31390eec
LK
4445 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4446 if (result)
24db713f 4447 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4448
31390eec 4449 return result;
c5c77ba1
JK
4450}
4451
a4ab1ade 4452s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
c5c77ba1 4453{
31390eec 4454 s32 result = 0;
143eb95a 4455 struct host_if_msg msg;
c5c77ba1 4456
a4ab1ade 4457 if (!hif_drv) {
24db713f
LK
4458 PRINT_ER("driver is null\n");
4459 return -EFAULT;
4460 }
c5c77ba1 4461
a4ab1ade 4462 del_timer(&hif_drv->hRemainOnChannel);
c5c77ba1 4463
143eb95a 4464 memset(&msg, 0, sizeof(struct host_if_msg));
a9f812a6 4465 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
a4ab1ade 4466 msg.drv = hif_drv;
070d365c 4467 msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
c5c77ba1 4468
31390eec
LK
4469 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4470 if (result)
24db713f 4471 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4472
31390eec 4473 return result;
c5c77ba1
JK
4474}
4475
a4ab1ade 4476s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
c5c77ba1 4477{
31390eec 4478 s32 result = 0;
143eb95a 4479 struct host_if_msg msg;
c5c77ba1 4480
a4ab1ade 4481 if (!hif_drv) {
24db713f
LK
4482 PRINT_ER("driver is null\n");
4483 return -EFAULT;
4484 }
c5c77ba1 4485
143eb95a 4486 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4487
a9f812a6 4488 msg.id = HOST_IF_MSG_REGISTER_FRAME;
c5c77ba1
JK
4489 switch (u16FrameType) {
4490 case ACTION:
4491 PRINT_D(HOSTINF_DBG, "ACTION\n");
5c4008db 4492 msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
c5c77ba1
JK
4493 break;
4494
4495 case PROBE_REQ:
4496 PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
5c4008db 4497 msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
c5c77ba1
JK
4498 break;
4499
4500 default:
4501 PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
4502 break;
4503 }
5c4008db
TC
4504 msg.body.reg_frame.u16FrameType = u16FrameType;
4505 msg.body.reg_frame.bReg = bReg;
a4ab1ade 4506 msg.drv = hif_drv;
c5c77ba1 4507
31390eec
LK
4508 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4509 if (result)
24db713f 4510 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4511
31390eec 4512 return result;
c5c77ba1 4513}
c5c77ba1 4514
a4ab1ade
TC
4515s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
4516 u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
4517 u32 u32TailLen, u8 *pu8Tail)
c5c77ba1 4518{
31390eec 4519 s32 result = 0;
143eb95a 4520 struct host_if_msg msg;
a98491e5 4521 struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
c5c77ba1 4522
a4ab1ade 4523 if (!hif_drv) {
24db713f
LK
4524 PRINT_ER("driver is null\n");
4525 return -EFAULT;
4526 }
c5c77ba1 4527
143eb95a 4528 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4529
4530 PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
4531
a9f812a6 4532 msg.id = HOST_IF_MSG_ADD_BEACON;
a4ab1ade 4533 msg.drv = hif_drv;
12262dda 4534 pstrSetBeaconParam->interval = u32Interval;
e76ab770 4535 pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
51c66185 4536 pstrSetBeaconParam->head_len = u32HeadLen;
543f5b13 4537 pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL);
8ce528b9 4538 if (pstrSetBeaconParam->head == NULL) {
31390eec 4539 result = -ENOMEM;
24db713f
LK
4540 goto ERRORHANDLER;
4541 }
030c57e2 4542 pstrSetBeaconParam->tail_len = u32TailLen;
c5c77ba1 4543
c5c77ba1 4544 if (u32TailLen > 0) {
543f5b13
SB
4545 pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen,
4546 GFP_KERNEL);
7dbcb6d3 4547 if (pstrSetBeaconParam->tail == NULL) {
31390eec 4548 result = -ENOMEM;
24db713f
LK
4549 goto ERRORHANDLER;
4550 }
c5c77ba1 4551 } else {
7dbcb6d3 4552 pstrSetBeaconParam->tail = NULL;
c5c77ba1
JK
4553 }
4554
31390eec
LK
4555 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4556 if (result)
24db713f 4557 PRINT_ER("wilc mq send fail\n");
c5c77ba1 4558
24db713f 4559ERRORHANDLER:
31390eec 4560 if (result) {
95f840fb 4561 kfree(pstrSetBeaconParam->head);
c5c77ba1 4562
95f840fb 4563 kfree(pstrSetBeaconParam->tail);
c5c77ba1
JK
4564 }
4565
31390eec 4566 return result;
c5c77ba1
JK
4567
4568}
4569
a4ab1ade 4570s32 host_int_del_beacon(struct host_if_drv *hif_drv)
c5c77ba1 4571{
31390eec 4572 s32 result = 0;
143eb95a 4573 struct host_if_msg msg;
c5c77ba1 4574
a4ab1ade 4575 if (!hif_drv) {
24db713f
LK
4576 PRINT_ER("driver is null\n");
4577 return -EFAULT;
4578 }
c5c77ba1 4579
a9f812a6 4580 msg.id = HOST_IF_MSG_DEL_BEACON;
a4ab1ade 4581 msg.drv = hif_drv;
c5c77ba1
JK
4582 PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
4583
31390eec
LK
4584 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4585 if (result)
7dc1d0cc 4586 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4587
31390eec 4588 return result;
c5c77ba1
JK
4589}
4590
a4ab1ade 4591s32 host_int_add_station(struct host_if_drv *hif_drv,
6a89ba9c 4592 struct add_sta_param *pstrStaParams)
c5c77ba1 4593{
31390eec 4594 s32 result = 0;
143eb95a 4595 struct host_if_msg msg;
ca8f47f8 4596 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1
JK
4597
4598
a4ab1ade 4599 if (!hif_drv) {
24db713f
LK
4600 PRINT_ER("driver is null\n");
4601 return -EFAULT;
4602 }
c5c77ba1 4603
143eb95a 4604 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4605
4606 PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
4607
a9f812a6 4608 msg.id = HOST_IF_MSG_ADD_STATION;
a4ab1ade 4609 msg.drv = hif_drv;
c5c77ba1 4610
6a89ba9c 4611 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4612 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4613 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
78c87591 4614
7ae43363
LK
4615 if (!rates)
4616 return -ENOMEM;
c5c77ba1 4617
d00d2ba3 4618 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4619 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4620 }
4621
31390eec
LK
4622 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4623 if (result)
24db713f 4624 PRINT_ER("wilc_mq_send fail\n");
31390eec 4625 return result;
c5c77ba1
JK
4626}
4627
a4ab1ade 4628s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr)
c5c77ba1 4629{
31390eec 4630 s32 result = 0;
143eb95a 4631 struct host_if_msg msg;
889c25be 4632 struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
c5c77ba1 4633
a4ab1ade 4634 if (!hif_drv) {
24db713f
LK
4635 PRINT_ER("driver is null\n");
4636 return -EFAULT;
4637 }
c5c77ba1 4638
143eb95a 4639 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4640
4641 PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
4642
a9f812a6 4643 msg.id = HOST_IF_MSG_DEL_STATION;
a4ab1ade 4644 msg.drv = hif_drv;
c5c77ba1 4645
b1413b60 4646 if (pu8MacAddr == NULL)
e4839d39 4647 memset(pstrDelStationMsg->mac_addr, 255, ETH_ALEN);
c5c77ba1 4648 else
e4839d39 4649 memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN);
c5c77ba1 4650
31390eec
LK
4651 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4652 if (result)
24db713f 4653 PRINT_ER("wilc_mq_send fail\n");
31390eec 4654 return result;
c5c77ba1 4655}
ae4dfa57 4656
a4ab1ade 4657s32 host_int_del_allstation(struct host_if_drv *hif_drv,
441dc609 4658 u8 pu8MacAddr[][ETH_ALEN])
c5c77ba1 4659{
31390eec 4660 s32 result = 0;
143eb95a 4661 struct host_if_msg msg;
b0c1e80e 4662 struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
63d03e47 4663 u8 au8Zero_Buff[ETH_ALEN] = {0};
4e4467fd 4664 u32 i;
63d03e47 4665 u8 u8AssocNumb = 0;
c5c77ba1
JK
4666
4667
a4ab1ade 4668 if (!hif_drv) {
24db713f
LK
4669 PRINT_ER("driver is null\n");
4670 return -EFAULT;
4671 }
c5c77ba1 4672
143eb95a 4673 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1
JK
4674
4675 PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
4676
a9f812a6 4677 msg.id = HOST_IF_MSG_DEL_ALL_STA;
a4ab1ade 4678 msg.drv = hif_drv;
c5c77ba1 4679
c5c77ba1
JK
4680 for (i = 0; i < MAX_NUM_STA; i++) {
4681 if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
e51b9216
LK
4682 memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN);
4683 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4684 pstrDelAllStationMsg->del_all_sta[i][0],
4685 pstrDelAllStationMsg->del_all_sta[i][1],
4686 pstrDelAllStationMsg->del_all_sta[i][2],
4687 pstrDelAllStationMsg->del_all_sta[i][3],
4688 pstrDelAllStationMsg->del_all_sta[i][4],
4689 pstrDelAllStationMsg->del_all_sta[i][5]);
c5c77ba1
JK
4690 u8AssocNumb++;
4691 }
4692 }
4693 if (!u8AssocNumb) {
4694 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
31390eec 4695 return result;
c5c77ba1
JK
4696 }
4697
8ba1803f 4698 pstrDelAllStationMsg->assoc_sta = u8AssocNumb;
31390eec 4699 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
c5c77ba1 4700
31390eec 4701 if (result)
24db713f 4702 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4703
2d25af87 4704 down(&hif_sema_wait_response);
c5c77ba1 4705
31390eec 4706 return result;
c5c77ba1
JK
4707}
4708
a4ab1ade 4709s32 host_int_edit_station(struct host_if_drv *hif_drv,
6a89ba9c 4710 struct add_sta_param *pstrStaParams)
c5c77ba1 4711{
31390eec 4712 s32 result = 0;
143eb95a 4713 struct host_if_msg msg;
ca8f47f8 4714 struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
c5c77ba1 4715
a4ab1ade 4716 if (!hif_drv) {
24db713f
LK
4717 PRINT_ER("driver is null\n");
4718 return -EFAULT;
4719 }
c5c77ba1
JK
4720
4721 PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
4722
143eb95a 4723 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4724
a9f812a6 4725 msg.id = HOST_IF_MSG_EDIT_STATION;
a4ab1ade 4726 msg.drv = hif_drv;
c5c77ba1 4727
6a89ba9c 4728 memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
c5c77ba1 4729 if (pstrAddStationMsg->u8NumRates > 0) {
f3052587 4730 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
78c87591 4731
7ae43363
LK
4732 if (!rates)
4733 return -ENOMEM;
4734
d00d2ba3 4735 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
057d1e97 4736 pstrAddStationMsg->pu8Rates = rates;
c5c77ba1
JK
4737 }
4738
31390eec
LK
4739 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4740 if (result)
24db713f
LK
4741 PRINT_ER("wilc_mq_send fail\n");
4742
31390eec 4743 return result;
c5c77ba1 4744}
108b3439 4745
a4ab1ade
TC
4746s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
4747 bool bIsEnabled,
4748 u32 u32Timeout)
c5c77ba1 4749{
31390eec 4750 s32 result = 0;
143eb95a 4751 struct host_if_msg msg;
49e1f81b 4752 struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
c5c77ba1 4753
03b2d5e7 4754 PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
c5c77ba1 4755
a4ab1ade 4756 if (!hif_drv) {
24db713f
LK
4757 PRINT_ER("driver is null\n");
4758 return -EFAULT;
4759 }
c5c77ba1
JK
4760
4761 PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
4762
143eb95a 4763 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4764
a9f812a6 4765 msg.id = HOST_IF_MSG_POWER_MGMT;
a4ab1ade 4766 msg.drv = hif_drv;
c5c77ba1 4767
33c70c1b 4768 pstrPowerMgmtParam->enabled = bIsEnabled;
937918ff 4769 pstrPowerMgmtParam->timeout = u32Timeout;
c5c77ba1 4770
31390eec
LK
4771 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4772 if (result)
24db713f 4773 PRINT_ER("wilc_mq_send fail\n");
31390eec 4774 return result;
c5c77ba1
JK
4775}
4776
a4ab1ade
TC
4777s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
4778 bool bIsEnabled,
4779 u32 u32count)
c5c77ba1 4780{
31390eec 4781 s32 result = 0;
143eb95a 4782 struct host_if_msg msg;
a079cf4d 4783 struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
c5c77ba1
JK
4784
4785
a4ab1ade 4786 if (!hif_drv) {
24db713f
LK
4787 PRINT_ER("driver is null\n");
4788 return -EFAULT;
4789 }
c5c77ba1
JK
4790
4791 PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
4792
143eb95a 4793 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4794
a9f812a6 4795 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
a4ab1ade 4796 msg.drv = hif_drv;
c5c77ba1 4797
bae636eb 4798 pstrMulticastFilterParam->enabled = bIsEnabled;
adab2f71 4799 pstrMulticastFilterParam->cnt = u32count;
c5c77ba1 4800
31390eec
LK
4801 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4802 if (result)
24db713f 4803 PRINT_ER("wilc_mq_send fail\n");
31390eec 4804 return result;
c5c77ba1
JK
4805}
4806
c5c77ba1
JK
4807static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
4808{
e0a12217 4809 struct join_bss_param *pNewJoinBssParam = NULL;
63d03e47 4810 u8 *pu8IEs;
d85f5326
CL
4811 u16 u16IEsLen;
4812 u16 index = 0;
63d03e47
GKH
4813 u8 suppRatesNo = 0;
4814 u8 extSuppRatesNo;
d85f5326 4815 u16 jumpOffset;
63d03e47
GKH
4816 u8 pcipherCount;
4817 u8 authCount;
4818 u8 pcipherTotalCount = 0;
4819 u8 authTotalCount = 0;
4820 u8 i, j;
c5c77ba1
JK
4821
4822 pu8IEs = ptstrNetworkInfo->pu8IEs;
4823 u16IEsLen = ptstrNetworkInfo->u16IEsLen;
4824
b156f1ed 4825 pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
c5c77ba1 4826 if (pNewJoinBssParam != NULL) {
c5c77ba1
JK
4827 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
4828 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
4829 pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
d00d2ba3 4830 memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
d00d2ba3 4831 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
619d27b8 4832 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen;
2cc46837
CL
4833 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4834 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
c5c77ba1 4835
c5c77ba1 4836 while (index < u16IEsLen) {
c5c77ba1 4837 if (pu8IEs[index] == SUPP_RATES_IE) {
c5c77ba1
JK
4838 suppRatesNo = pu8IEs[index + 1];
4839 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
ae4dfa57 4840 index += 2;
c5c77ba1
JK
4841
4842 for (i = 0; i < suppRatesNo; i++) {
4843 pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
c5c77ba1
JK
4844 }
4845 index += suppRatesNo;
4846 continue;
ae4dfa57 4847 } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
c5c77ba1
JK
4848 extSuppRatesNo = pu8IEs[index + 1];
4849 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4850 pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4851 else
4852 pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4853 index += 2;
c5c77ba1
JK
4854 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++) {
4855 pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
c5c77ba1
JK
4856 }
4857 index += extSuppRatesNo;
4858 continue;
ae4dfa57 4859 } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
0be1eb74 4860 pNewJoinBssParam->ht_capable = true;
ae4dfa57 4861 index += pu8IEs[index + 1] + 2;
c5c77ba1 4862 continue;
ae4dfa57 4863 } else if ((pu8IEs[index] == WMM_IE) &&
c5c77ba1 4864 (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
ae4dfa57
LK
4865 (pu8IEs[index + 4] == 0xF2) &&
4866 (pu8IEs[index + 5] == 0x02) &&
4867 ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
c5c77ba1 4868 (pu8IEs[index + 7] == 0x01)) {
0be1eb74 4869 pNewJoinBssParam->wmm_cap = true;
c5c77ba1 4870
ffda203c 4871 if (pu8IEs[index + 8] & BIT(7))
0be1eb74 4872 pNewJoinBssParam->uapsd_cap = true;
c5c77ba1
JK
4873 index += pu8IEs[index + 1] + 2;
4874 continue;
ae4dfa57 4875 } else if ((pu8IEs[index] == P2P_IE) &&
c5c77ba1 4876 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
ae4dfa57
LK
4877 (pu8IEs[index + 4] == 0x9a) &&
4878 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
d85f5326 4879 u16 u16P2P_count;
78c87591 4880
c5c77ba1 4881 pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
7a8d51d7 4882 pNewJoinBssParam->noa_enabled = 1;
cc179008 4883 pNewJoinBssParam->idx = pu8IEs[index + 9];
c5c77ba1 4884
ffda203c 4885 if (pu8IEs[index + 10] & BIT(7)) {
d72b33ca 4886 pNewJoinBssParam->opp_enabled = 1;
99b66945 4887 pNewJoinBssParam->ct_window = pu8IEs[index + 10];
d72b33ca
LK
4888 } else {
4889 pNewJoinBssParam->opp_enabled = 0;
4890 }
ae4dfa57 4891
03b2d5e7 4892 PRINT_D(GENERIC_DBG, "P2P Dump\n");
c5c77ba1 4893 for (i = 0; i < pu8IEs[index + 7]; i++)
03b2d5e7 4894 PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
c5c77ba1 4895
c21047ed 4896 pNewJoinBssParam->cnt = pu8IEs[index + 11];
c5c77ba1
JK
4897 u16P2P_count = index + 12;
4898
109e6cab 4899 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4900 u16P2P_count += 4;
4901
1d8b76b3 4902 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4903 u16P2P_count += 4;
4904
d00d2ba3 4905 memcpy(pNewJoinBssParam->au8StartTime, pu8IEs + u16P2P_count, 4);
c5c77ba1
JK
4906
4907 index += pu8IEs[index + 1] + 2;
4908 continue;
4909
ae4dfa57 4910 } else if ((pu8IEs[index] == RSN_IE) ||
c5c77ba1
JK
4911 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4912 (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4913 (pu8IEs[index + 5] == 0x01))) {
d85f5326 4914 u16 rsnIndex = index;
ae4dfa57 4915
c5c77ba1
JK
4916 if (pu8IEs[rsnIndex] == RSN_IE) {
4917 pNewJoinBssParam->mode_802_11i = 2;
ae4dfa57 4918 } else {
c5c77ba1
JK
4919 if (pNewJoinBssParam->mode_802_11i == 0)
4920 pNewJoinBssParam->mode_802_11i = 1;
c5c77ba1
JK
4921 rsnIndex += 4;
4922 }
ae4dfa57
LK
4923
4924 rsnIndex += 7;
c5c77ba1
JK
4925 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4926 rsnIndex++;
ae4dfa57 4927 jumpOffset = pu8IEs[rsnIndex] * 4;
c5c77ba1 4928 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4929 rsnIndex += 2;
c5c77ba1 4930
c5c77ba1 4931 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++) {
c5c77ba1 4932 pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
c5c77ba1
JK
4933 }
4934 pcipherTotalCount += pcipherCount;
4935 rsnIndex += jumpOffset;
4936
4937 jumpOffset = pu8IEs[rsnIndex] * 4;
4938
c5c77ba1 4939 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
ae4dfa57 4940 rsnIndex += 2;
c5c77ba1
JK
4941
4942 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++) {
c5c77ba1
JK
4943 pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4944 }
4945 authTotalCount += authCount;
4946 rsnIndex += jumpOffset;
ae4dfa57 4947
c5c77ba1
JK
4948 if (pu8IEs[index] == RSN_IE) {
4949 pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4950 pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4951 rsnIndex += 2;
4952 }
f717c0eb 4953 pNewJoinBssParam->rsn_found = true;
ae4dfa57 4954 index += pu8IEs[index + 1] + 2;
c5c77ba1
JK
4955 continue;
4956 } else
ae4dfa57 4957 index += pu8IEs[index + 1] + 2;
c5c77ba1
JK
4958
4959 }
4960
4961
4962 }
4963
4964 return (void *)pNewJoinBssParam;
4965
4966}
4967
4968void host_int_freeJoinParams(void *pJoinParams)
4969{
e0a12217
LK
4970 if ((struct bss_param *)pJoinParams != NULL)
4971 kfree((struct bss_param *)pJoinParams);
c5c77ba1
JK
4972 else
4973 PRINT_ER("Unable to FREE null pointer\n");
4974}
c5c77ba1 4975
a4ab1ade 4976s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
c5c77ba1 4977{
31390eec 4978 s32 result = 0;
143eb95a 4979 struct host_if_msg msg;
c833b474 4980 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 4981
a4ab1ade 4982 if (!hif_drv) {
24db713f
LK
4983 PRINT_ER("driver is null\n");
4984 return -EFAULT;
4985 }
c5c77ba1 4986
143eb95a 4987 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 4988
a9f812a6 4989 msg.id = HOST_IF_MSG_DEL_BA_SESSION;
c5c77ba1
JK
4990
4991 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4992 pBASessionInfo->u8Ted = TID;
a4ab1ade 4993 msg.drv = hif_drv;
c5c77ba1 4994
31390eec
LK
4995 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4996 if (result)
24db713f 4997 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 4998
2d25af87 4999 down(&hif_sema_wait_response);
c5c77ba1 5000
31390eec 5001 return result;
c5c77ba1
JK
5002}
5003
a4ab1ade
TC
5004s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
5005 char *pBSSID,
5006 char TID)
c5c77ba1 5007{
31390eec 5008 s32 result = 0;
143eb95a 5009 struct host_if_msg msg;
c833b474 5010 struct ba_session_info *pBASessionInfo = &msg.body.session_info;
c5c77ba1 5011
a4ab1ade 5012 if (!hif_drv) {
24db713f
LK
5013 PRINT_ER("driver is null\n");
5014 return -EFAULT;
5015 }
c5c77ba1 5016
143eb95a 5017 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 5018
a9f812a6 5019 msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
c5c77ba1
JK
5020
5021 memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
5022 pBASessionInfo->u8Ted = TID;
a4ab1ade 5023 msg.drv = hif_drv;
c5c77ba1 5024
31390eec
LK
5025 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
5026 if (result)
24db713f 5027 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 5028
2d25af87 5029 down(&hif_sema_wait_response);
c5c77ba1 5030
31390eec 5031 return result;
c5c77ba1
JK
5032}
5033
a4ab1ade 5034s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 5035{
31390eec 5036 s32 result = 0;
143eb95a 5037 struct host_if_msg msg;
c5c77ba1 5038
c5c77ba1
JK
5039 return 0;
5040
a4ab1ade 5041 if (!hif_drv) {
24db713f
LK
5042 PRINT_ER("driver is null\n");
5043 return -EFAULT;
5044 }
c5c77ba1 5045
143eb95a 5046 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 5047
a9f812a6 5048 msg.id = HOST_IF_MSG_SET_IPADDRESS;
c5c77ba1 5049
78675be5 5050 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 5051 msg.drv = hif_drv;
fb2d65ed 5052 msg.body.ip_info.idx = idx;
c5c77ba1 5053
31390eec
LK
5054 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
5055 if (result)
24db713f 5056 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 5057
31390eec 5058 return result;
c5c77ba1
JK
5059}
5060
a4ab1ade 5061s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
c5c77ba1 5062{
31390eec 5063 s32 result = 0;
143eb95a 5064 struct host_if_msg msg;
c5c77ba1 5065
a4ab1ade 5066 if (!hif_drv) {
24db713f
LK
5067 PRINT_ER("driver is null\n");
5068 return -EFAULT;
5069 }
c5c77ba1 5070
143eb95a 5071 memset(&msg, 0, sizeof(struct host_if_msg));
c5c77ba1 5072
a9f812a6 5073 msg.id = HOST_IF_MSG_GET_IPADDRESS;
c5c77ba1 5074
78675be5 5075 msg.body.ip_info.ip_addr = u16ipadd;
a4ab1ade 5076 msg.drv = hif_drv;
fb2d65ed 5077 msg.body.ip_info.idx = idx;
c5c77ba1 5078
31390eec
LK
5079 result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
5080 if (result)
24db713f 5081 PRINT_ER("wilc_mq_send fail\n");
c5c77ba1 5082
31390eec 5083 return result;
c5c77ba1 5084}