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