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