staging: wilc1000: check for kmalloc allocation failures
[linux-2.6/btrfs-unstable.git] / drivers / staging / wilc1000 / host_interface.c
blob9b9b86654958ff7837593dbb5eb732b930a4293c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/slab.h>
3 #include <linux/time.h>
4 #include <linux/kthread.h>
5 #include <linux/delay.h>
6 #include <linux/completion.h>
7 #include <linux/list.h>
8 #include <linux/workqueue.h>
9 #include "host_interface.h"
10 #include <linux/spinlock.h>
11 #include <linux/errno.h>
12 #include "coreconfigurator.h"
13 #include "wilc_wlan.h"
14 #include "wilc_wlan_if.h"
15 #include <linux/etherdevice.h>
16 #include "wilc_wfi_netdevice.h"
18 #define HOST_IF_MSG_SCAN 0
19 #define HOST_IF_MSG_CONNECT 1
20 #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
21 #define HOST_IF_MSG_KEY 3
22 #define HOST_IF_MSG_RCVD_NTWRK_INFO 4
23 #define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
24 #define HOST_IF_MSG_CFG_PARAMS 6
25 #define HOST_IF_MSG_SET_CHANNEL 7
26 #define HOST_IF_MSG_DISCONNECT 8
27 #define HOST_IF_MSG_GET_RSSI 9
28 #define HOST_IF_MSG_ADD_BEACON 11
29 #define HOST_IF_MSG_DEL_BEACON 12
30 #define HOST_IF_MSG_ADD_STATION 13
31 #define HOST_IF_MSG_DEL_STATION 14
32 #define HOST_IF_MSG_EDIT_STATION 15
33 #define HOST_IF_MSG_SCAN_TIMER_FIRED 16
34 #define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
35 #define HOST_IF_MSG_POWER_MGMT 18
36 #define HOST_IF_MSG_GET_INACTIVETIME 19
37 #define HOST_IF_MSG_REMAIN_ON_CHAN 20
38 #define HOST_IF_MSG_REGISTER_FRAME 21
39 #define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
40 #define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
41 #define HOST_IF_MSG_GET_MAC_ADDRESS 26
42 #define HOST_IF_MSG_SET_OPERATION_MODE 27
43 #define HOST_IF_MSG_SET_IPADDRESS 28
44 #define HOST_IF_MSG_GET_IPADDRESS 29
45 #define HOST_IF_MSG_GET_STATISTICS 31
46 #define HOST_IF_MSG_SET_MULTICAST_FILTER 32
47 #define HOST_IF_MSG_DEL_BA_SESSION 34
48 #define HOST_IF_MSG_DEL_ALL_STA 36
49 #define HOST_IF_MSG_SET_TX_POWER 38
50 #define HOST_IF_MSG_GET_TX_POWER 39
51 #define HOST_IF_MSG_EXIT 100
53 #define HOST_IF_SCAN_TIMEOUT 4000
54 #define HOST_IF_CONNECT_TIMEOUT 9500
56 #define BA_SESSION_DEFAULT_BUFFER_SIZE 16
57 #define BA_SESSION_DEFAULT_TIMEOUT 1000
58 #define BLOCK_ACK_REQ_SIZE 0x14
59 #define FALSE_FRMWR_CHANNEL 100
61 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
62 #define DEFAULT_LINK_SPEED 72
64 struct host_if_wpa_attr {
65 u8 *key;
66 const u8 *mac_addr;
67 u8 *seq;
68 u8 seq_len;
69 u8 index;
70 u8 key_len;
71 u8 mode;
74 struct host_if_wep_attr {
75 u8 *key;
76 u8 key_len;
77 u8 index;
78 u8 mode;
79 enum AUTHTYPE auth_type;
82 union host_if_key_attr {
83 struct host_if_wep_attr wep;
84 struct host_if_wpa_attr wpa;
85 struct host_if_pmkid_attr pmkid;
88 struct key_attr {
89 enum KEY_TYPE type;
90 u8 action;
91 union host_if_key_attr attr;
94 struct scan_attr {
95 u8 src;
96 u8 type;
97 u8 *ch_freq_list;
98 u8 ch_list_len;
99 u8 *ies;
100 size_t ies_len;
101 wilc_scan_result result;
102 void *arg;
103 struct hidden_network hidden_network;
106 struct connect_attr {
107 u8 *bssid;
108 u8 *ssid;
109 size_t ssid_len;
110 u8 *ies;
111 size_t ies_len;
112 u8 security;
113 wilc_connect_result result;
114 void *arg;
115 enum AUTHTYPE auth_type;
116 u8 ch;
117 void *params;
120 struct rcvd_async_info {
121 u8 *buffer;
122 u32 len;
125 struct channel_attr {
126 u8 set_ch;
129 struct beacon_attr {
130 u32 interval;
131 u32 dtim_period;
132 u32 head_len;
133 u8 *head;
134 u32 tail_len;
135 u8 *tail;
138 struct set_multicast {
139 bool enabled;
140 u32 cnt;
143 struct del_all_sta {
144 u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
145 u8 assoc_sta;
148 struct del_sta {
149 u8 mac_addr[ETH_ALEN];
152 struct power_mgmt_param {
153 bool enabled;
154 u32 timeout;
157 struct set_ip_addr {
158 u8 *ip_addr;
159 u8 idx;
162 struct sta_inactive_t {
163 u8 mac[6];
166 struct tx_power {
167 u8 tx_pwr;
170 union message_body {
171 struct scan_attr scan_info;
172 struct connect_attr con_info;
173 struct rcvd_net_info net_info;
174 struct rcvd_async_info async_info;
175 struct key_attr key_info;
176 struct cfg_param_attr cfg_info;
177 struct channel_attr channel_info;
178 struct beacon_attr beacon_info;
179 struct add_sta_param add_sta_info;
180 struct del_sta del_sta_info;
181 struct add_sta_param edit_sta_info;
182 struct power_mgmt_param pwr_mgmt_info;
183 struct sta_inactive_t mac_info;
184 struct set_ip_addr ip_info;
185 struct drv_handler drv;
186 struct set_multicast multicast_info;
187 struct op_mode mode;
188 struct get_mac_addr get_mac_info;
189 struct ba_session_info session_info;
190 struct remain_ch remain_on_ch;
191 struct reg_frame reg_frame;
192 char *data;
193 struct del_all_sta del_all_sta_info;
194 struct tx_power tx_power;
197 struct host_if_msg {
198 u16 id;
199 union message_body body;
200 struct wilc_vif *vif;
201 struct work_struct work;
204 struct join_bss_param {
205 enum bss_types bss_type;
206 u8 dtim_period;
207 u16 beacon_period;
208 u16 cap_info;
209 u8 bssid[6];
210 char ssid[MAX_SSID_LEN];
211 u8 ssid_len;
212 u8 supp_rates[MAX_RATES_SUPPORTED + 1];
213 u8 ht_capable;
214 u8 wmm_cap;
215 u8 uapsd_cap;
216 bool rsn_found;
217 u8 rsn_grp_policy;
218 u8 mode_802_11i;
219 u8 rsn_pcip_policy[3];
220 u8 rsn_auth_policy[3];
221 u8 rsn_cap[2];
222 u32 tsf;
223 u8 noa_enabled;
224 u8 opp_enabled;
225 u8 ct_window;
226 u8 cnt;
227 u8 idx;
228 u8 duration[4];
229 u8 interval[4];
230 u8 start_time[4];
233 static struct host_if_drv *terminated_handle;
234 bool wilc_optaining_ip;
235 static u8 P2P_LISTEN_STATE;
236 static struct workqueue_struct *hif_workqueue;
237 static struct completion hif_thread_comp;
238 static struct completion hif_driver_comp;
239 static struct completion hif_wait_response;
240 static struct mutex hif_deinit_lock;
241 static struct timer_list periodic_rssi;
242 static struct wilc_vif *periodic_rssi_vif;
244 u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
246 static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
248 static bool scan_while_connected;
250 static s8 rssi;
251 static u8 set_ip[2][4];
252 static u8 get_ip[2][4];
253 static u32 inactive_time;
254 static u8 del_beacon;
255 static u32 clients_count;
257 static u8 *join_req;
258 static u8 *info_element;
259 static u8 mode_11i;
260 static u8 auth_type;
261 static u32 join_req_size;
262 static u32 info_element_size;
263 static struct wilc_vif *join_req_vif;
264 #define REAL_JOIN_REQ 0
265 #define FLUSHED_JOIN_REQ 1
266 #define FLUSHED_BYTE_POS 79
268 static void *host_int_parse_join_bss_param(struct network_info *info);
269 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
270 static s32 handle_scan_done(struct wilc_vif *vif, enum scan_event evt);
271 static void host_if_work(struct work_struct *work);
274 * @author syounan
275 * @date 1 Sep 2010
276 * @note copied from FLO glue implementatuion
277 * @version 1.0
279 static int wilc_enqueue_cmd(struct host_if_msg *msg)
281 struct host_if_msg *new_msg;
283 new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
284 if (!new_msg)
285 return -ENOMEM;
287 INIT_WORK(&new_msg->work, host_if_work);
288 queue_work(hif_workqueue, &new_msg->work);
289 return 0;
292 /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
293 * special purpose in wilc device, so we add 1 to the index to starts from 1.
294 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
296 int wilc_get_vif_idx(struct wilc_vif *vif)
298 return vif->idx + 1;
301 /* We need to minus 1 from idx which is from wilc device to get real index
302 * of wilc->vif[], because we add 1 when pass to wilc device in the function
303 * wilc_get_vif_idx.
304 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
306 static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
308 int index = idx - 1;
310 if (index < 0 || index >= NUM_CONCURRENT_IFC)
311 return NULL;
313 return wilc->vif[index];
316 static void handle_set_channel(struct wilc_vif *vif,
317 struct channel_attr *hif_set_ch)
319 int ret = 0;
320 struct wid wid;
322 wid.id = (u16)WID_CURRENT_CHANNEL;
323 wid.type = WID_CHAR;
324 wid.val = (char *)&hif_set_ch->set_ch;
325 wid.size = sizeof(char);
327 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
328 wilc_get_vif_idx(vif));
330 if (ret)
331 netdev_err(vif->ndev, "Failed to set channel\n");
334 static int handle_set_wfi_drv_handler(struct wilc_vif *vif,
335 struct drv_handler *hif_drv_handler)
337 int ret = 0;
338 struct wid wid;
339 u8 *currbyte, *buffer;
340 struct host_if_drv *hif_drv = NULL;
342 if (!vif->hif_drv)
343 return -EINVAL;
345 if (!hif_drv_handler)
346 return -EINVAL;
348 hif_drv = vif->hif_drv;
350 buffer = kzalloc(DRV_HANDLER_SIZE, GFP_KERNEL);
351 if (!buffer)
352 return -ENOMEM;
354 currbyte = buffer;
355 *currbyte = hif_drv->driver_handler_id & 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 = (u32)0 & DRV_HANDLER_MASK;
362 currbyte++;
363 *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
365 wid.id = (u16)WID_SET_DRV_HANDLER;
366 wid.type = WID_STR;
367 wid.val = (s8 *)buffer;
368 wid.size = DRV_HANDLER_SIZE;
370 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
371 hif_drv->driver_handler_id);
372 if (ret) {
373 netdev_err(vif->ndev, "Failed to set driver handler\n");
374 complete(&hif_driver_comp);
375 kfree(buffer);
376 return ret;
378 complete(&hif_driver_comp);
379 kfree(buffer);
380 return 0;
383 static void handle_set_operation_mode(struct wilc_vif *vif,
384 struct op_mode *hif_op_mode)
386 int ret = 0;
387 struct wid wid;
389 wid.id = (u16)WID_SET_OPERATION_MODE;
390 wid.type = WID_INT;
391 wid.val = (s8 *)&hif_op_mode->mode;
392 wid.size = sizeof(u32);
394 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
395 wilc_get_vif_idx(vif));
397 if (hif_op_mode->mode == IDLE_MODE)
398 complete(&hif_driver_comp);
400 if (ret)
401 netdev_err(vif->ndev, "Failed to set driver handler\n");
404 static void handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
406 int ret = 0;
407 struct wid wid;
408 char firmware_ip_addr[4] = {0};
410 if (ip_addr[0] < 192)
411 ip_addr[0] = 0;
413 memcpy(set_ip[idx], ip_addr, IP_ALEN);
415 wid.id = (u16)WID_IP_ADDRESS;
416 wid.type = WID_STR;
417 wid.val = ip_addr;
418 wid.size = IP_ALEN;
420 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
421 wilc_get_vif_idx(vif));
423 host_int_get_ipaddress(vif, firmware_ip_addr, idx);
425 if (ret)
426 netdev_err(vif->ndev, "Failed to set IP address\n");
429 static void handle_get_ip_address(struct wilc_vif *vif, u8 idx)
431 int ret = 0;
432 struct wid wid;
434 wid.id = (u16)WID_IP_ADDRESS;
435 wid.type = WID_STR;
436 wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
437 wid.size = IP_ALEN;
439 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
440 wilc_get_vif_idx(vif));
442 memcpy(get_ip[idx], wid.val, IP_ALEN);
444 kfree(wid.val);
446 if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
447 wilc_setup_ipaddress(vif, set_ip[idx], idx);
449 if (ret)
450 netdev_err(vif->ndev, "Failed to get IP address\n");
453 static void handle_get_mac_address(struct wilc_vif *vif,
454 struct get_mac_addr *get_mac_addr)
456 int ret = 0;
457 struct wid wid;
459 wid.id = (u16)WID_MAC_ADDR;
460 wid.type = WID_STR;
461 wid.val = get_mac_addr->mac_addr;
462 wid.size = ETH_ALEN;
464 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
465 wilc_get_vif_idx(vif));
467 if (ret)
468 netdev_err(vif->ndev, "Failed to get mac address\n");
469 complete(&hif_wait_response);
472 static void handle_cfg_param(struct wilc_vif *vif, struct cfg_param_attr *param)
474 int ret = 0;
475 struct wid wid_list[32];
476 struct host_if_drv *hif_drv = vif->hif_drv;
477 int i = 0;
479 mutex_lock(&hif_drv->cfg_values_lock);
481 if (param->flag & BSS_TYPE) {
482 u8 bss_type = param->bss_type;
484 if (bss_type < 6) {
485 wid_list[i].id = WID_BSS_TYPE;
486 wid_list[i].val = (s8 *)&param->bss_type;
487 wid_list[i].type = WID_CHAR;
488 wid_list[i].size = sizeof(char);
489 hif_drv->cfg_values.bss_type = bss_type;
490 } else {
491 netdev_err(vif->ndev, "check value 6 over\n");
492 goto unlock;
494 i++;
496 if (param->flag & AUTH_TYPE) {
497 u8 auth_type = param->auth_type;
499 if (auth_type == 1 || auth_type == 2 || auth_type == 5) {
500 wid_list[i].id = WID_AUTH_TYPE;
501 wid_list[i].val = (s8 *)&param->auth_type;
502 wid_list[i].type = WID_CHAR;
503 wid_list[i].size = sizeof(char);
504 hif_drv->cfg_values.auth_type = auth_type;
505 } else {
506 netdev_err(vif->ndev, "Impossible value\n");
507 goto unlock;
509 i++;
511 if (param->flag & AUTHEN_TIMEOUT) {
512 if (param->auth_timeout > 0) {
513 wid_list[i].id = WID_AUTH_TIMEOUT;
514 wid_list[i].val = (s8 *)&param->auth_timeout;
515 wid_list[i].type = WID_SHORT;
516 wid_list[i].size = sizeof(u16);
517 hif_drv->cfg_values.auth_timeout = param->auth_timeout;
518 } else {
519 netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
520 goto unlock;
522 i++;
524 if (param->flag & POWER_MANAGEMENT) {
525 u8 pm_mode = param->power_mgmt_mode;
527 if (pm_mode < 5) {
528 wid_list[i].id = WID_POWER_MANAGEMENT;
529 wid_list[i].val = (s8 *)&param->power_mgmt_mode;
530 wid_list[i].type = WID_CHAR;
531 wid_list[i].size = sizeof(char);
532 hif_drv->cfg_values.power_mgmt_mode = pm_mode;
533 } else {
534 netdev_err(vif->ndev, "Invalid power mode\n");
535 goto unlock;
537 i++;
539 if (param->flag & RETRY_SHORT) {
540 u16 retry_limit = param->short_retry_limit;
542 if (retry_limit > 0 && retry_limit < 256) {
543 wid_list[i].id = WID_SHORT_RETRY_LIMIT;
544 wid_list[i].val = (s8 *)&param->short_retry_limit;
545 wid_list[i].type = WID_SHORT;
546 wid_list[i].size = sizeof(u16);
547 hif_drv->cfg_values.short_retry_limit = retry_limit;
548 } else {
549 netdev_err(vif->ndev, "Range(1~256) over\n");
550 goto unlock;
552 i++;
554 if (param->flag & RETRY_LONG) {
555 u16 limit = param->long_retry_limit;
557 if (limit > 0 && limit < 256) {
558 wid_list[i].id = WID_LONG_RETRY_LIMIT;
559 wid_list[i].val = (s8 *)&param->long_retry_limit;
560 wid_list[i].type = WID_SHORT;
561 wid_list[i].size = sizeof(u16);
562 hif_drv->cfg_values.long_retry_limit = limit;
563 } else {
564 netdev_err(vif->ndev, "Range(1~256) over\n");
565 goto unlock;
567 i++;
569 if (param->flag & FRAG_THRESHOLD) {
570 u16 frag_th = param->frag_threshold;
572 if (frag_th > 255 && frag_th < 7937) {
573 wid_list[i].id = WID_FRAG_THRESHOLD;
574 wid_list[i].val = (s8 *)&param->frag_threshold;
575 wid_list[i].type = WID_SHORT;
576 wid_list[i].size = sizeof(u16);
577 hif_drv->cfg_values.frag_threshold = frag_th;
578 } else {
579 netdev_err(vif->ndev, "Threshold Range fail\n");
580 goto unlock;
582 i++;
584 if (param->flag & RTS_THRESHOLD) {
585 u16 rts_th = param->rts_threshold;
587 if (rts_th > 255) {
588 wid_list[i].id = WID_RTS_THRESHOLD;
589 wid_list[i].val = (s8 *)&param->rts_threshold;
590 wid_list[i].type = WID_SHORT;
591 wid_list[i].size = sizeof(u16);
592 hif_drv->cfg_values.rts_threshold = rts_th;
593 } else {
594 netdev_err(vif->ndev, "Threshold Range fail\n");
595 goto unlock;
597 i++;
599 if (param->flag & PREAMBLE) {
600 u16 preamble_type = param->preamble_type;
602 if (param->preamble_type < 3) {
603 wid_list[i].id = WID_PREAMBLE;
604 wid_list[i].val = (s8 *)&param->preamble_type;
605 wid_list[i].type = WID_CHAR;
606 wid_list[i].size = sizeof(char);
607 hif_drv->cfg_values.preamble_type = preamble_type;
608 } else {
609 netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
610 goto unlock;
612 i++;
614 if (param->flag & SHORT_SLOT_ALLOWED) {
615 u8 slot_allowed = param->short_slot_allowed;
617 if (slot_allowed < 2) {
618 wid_list[i].id = WID_SHORT_SLOT_ALLOWED;
619 wid_list[i].val = (s8 *)&param->short_slot_allowed;
620 wid_list[i].type = WID_CHAR;
621 wid_list[i].size = sizeof(char);
622 hif_drv->cfg_values.short_slot_allowed = slot_allowed;
623 } else {
624 netdev_err(vif->ndev, "Short slot(2) over\n");
625 goto unlock;
627 i++;
629 if (param->flag & TXOP_PROT_DISABLE) {
630 u8 prot_disabled = param->txop_prot_disabled;
632 if (param->txop_prot_disabled < 2) {
633 wid_list[i].id = WID_11N_TXOP_PROT_DISABLE;
634 wid_list[i].val = (s8 *)&param->txop_prot_disabled;
635 wid_list[i].type = WID_CHAR;
636 wid_list[i].size = sizeof(char);
637 hif_drv->cfg_values.txop_prot_disabled = prot_disabled;
638 } else {
639 netdev_err(vif->ndev, "TXOP prot disable\n");
640 goto unlock;
642 i++;
644 if (param->flag & BEACON_INTERVAL) {
645 u16 beacon_interval = param->beacon_interval;
647 if (beacon_interval > 0) {
648 wid_list[i].id = WID_BEACON_INTERVAL;
649 wid_list[i].val = (s8 *)&param->beacon_interval;
650 wid_list[i].type = WID_SHORT;
651 wid_list[i].size = sizeof(u16);
652 hif_drv->cfg_values.beacon_interval = beacon_interval;
653 } else {
654 netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
655 goto unlock;
657 i++;
659 if (param->flag & DTIM_PERIOD) {
660 if (param->dtim_period > 0 && param->dtim_period < 256) {
661 wid_list[i].id = WID_DTIM_PERIOD;
662 wid_list[i].val = (s8 *)&param->dtim_period;
663 wid_list[i].type = WID_CHAR;
664 wid_list[i].size = sizeof(char);
665 hif_drv->cfg_values.dtim_period = param->dtim_period;
666 } else {
667 netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
668 goto unlock;
670 i++;
672 if (param->flag & SITE_SURVEY) {
673 enum SITESURVEY enabled = param->site_survey_enabled;
675 if (enabled < 3) {
676 wid_list[i].id = WID_SITE_SURVEY;
677 wid_list[i].val = (s8 *)&param->site_survey_enabled;
678 wid_list[i].type = WID_CHAR;
679 wid_list[i].size = sizeof(char);
680 hif_drv->cfg_values.site_survey_enabled = enabled;
681 } else {
682 netdev_err(vif->ndev, "Site survey disable\n");
683 goto unlock;
685 i++;
687 if (param->flag & SITE_SURVEY_SCAN_TIME) {
688 u16 scan_time = param->site_survey_scan_time;
690 if (scan_time > 0) {
691 wid_list[i].id = WID_SITE_SURVEY_SCAN_TIME;
692 wid_list[i].val = (s8 *)&param->site_survey_scan_time;
693 wid_list[i].type = WID_SHORT;
694 wid_list[i].size = sizeof(u16);
695 hif_drv->cfg_values.site_survey_scan_time = scan_time;
696 } else {
697 netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
698 goto unlock;
700 i++;
702 if (param->flag & ACTIVE_SCANTIME) {
703 u16 active_scan_time = param->active_scan_time;
705 if (active_scan_time > 0) {
706 wid_list[i].id = WID_ACTIVE_SCAN_TIME;
707 wid_list[i].val = (s8 *)&param->active_scan_time;
708 wid_list[i].type = WID_SHORT;
709 wid_list[i].size = sizeof(u16);
710 hif_drv->cfg_values.active_scan_time = active_scan_time;
711 } else {
712 netdev_err(vif->ndev, "Active time(1~65535) over\n");
713 goto unlock;
715 i++;
717 if (param->flag & PASSIVE_SCANTIME) {
718 u16 time = param->passive_scan_time;
720 if (time > 0) {
721 wid_list[i].id = WID_PASSIVE_SCAN_TIME;
722 wid_list[i].val = (s8 *)&param->passive_scan_time;
723 wid_list[i].type = WID_SHORT;
724 wid_list[i].size = sizeof(u16);
725 hif_drv->cfg_values.passive_scan_time = time;
726 } else {
727 netdev_err(vif->ndev, "Passive time(1~65535) over\n");
728 goto unlock;
730 i++;
732 if (param->flag & CURRENT_TX_RATE) {
733 enum CURRENT_TXRATE curr_tx_rate = param->curr_tx_rate;
735 if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 ||
736 curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 ||
737 curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 ||
738 curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 ||
739 curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 ||
740 curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 ||
741 curr_tx_rate == MBPS_54) {
742 wid_list[i].id = WID_CURRENT_TX_RATE;
743 wid_list[i].val = (s8 *)&curr_tx_rate;
744 wid_list[i].type = WID_SHORT;
745 wid_list[i].size = sizeof(u16);
746 hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
747 } else {
748 netdev_err(vif->ndev, "out of TX rate\n");
749 goto unlock;
751 i++;
754 ret = wilc_send_config_pkt(vif, SET_CFG, wid_list,
755 i, wilc_get_vif_idx(vif));
757 if (ret)
758 netdev_err(vif->ndev, "Error in setting CFG params\n");
760 unlock:
761 mutex_unlock(&hif_drv->cfg_values_lock);
764 static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info)
766 s32 result = 0;
767 struct wid wid_list[5];
768 u32 index = 0;
769 u32 i;
770 u8 *buffer;
771 u8 valuesize = 0;
772 u8 *hdn_ntwk_wid_val = NULL;
773 struct host_if_drv *hif_drv = vif->hif_drv;
774 struct hidden_network *hidden_net = &scan_info->hidden_network;
776 hif_drv->usr_scan_req.scan_result = scan_info->result;
777 hif_drv->usr_scan_req.arg = scan_info->arg;
779 if (hif_drv->hif_state >= HOST_IF_SCANNING &&
780 hif_drv->hif_state < HOST_IF_CONNECTED) {
781 netdev_err(vif->ndev, "Already scan\n");
782 result = -EBUSY;
783 goto error;
786 if (wilc_optaining_ip || wilc_connecting) {
787 netdev_err(vif->ndev, "Don't do obss scan\n");
788 result = -EBUSY;
789 goto error;
792 hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
794 wid_list[index].id = (u16)WID_SSID_PROBE_REQ;
795 wid_list[index].type = WID_STR;
797 for (i = 0; i < hidden_net->n_ssids; i++)
798 valuesize += ((hidden_net->net_info[i].ssid_len) + 1);
799 hdn_ntwk_wid_val = kmalloc(valuesize + 1, GFP_KERNEL);
800 wid_list[index].val = hdn_ntwk_wid_val;
801 if (wid_list[index].val) {
802 buffer = wid_list[index].val;
804 *buffer++ = hidden_net->n_ssids;
806 for (i = 0; i < hidden_net->n_ssids; i++) {
807 *buffer++ = hidden_net->net_info[i].ssid_len;
808 memcpy(buffer, hidden_net->net_info[i].ssid,
809 hidden_net->net_info[i].ssid_len);
810 buffer += hidden_net->net_info[i].ssid_len;
813 wid_list[index].size = (s32)(valuesize + 1);
814 index++;
817 wid_list[index].id = WID_INFO_ELEMENT_PROBE;
818 wid_list[index].type = WID_BIN_DATA;
819 wid_list[index].val = scan_info->ies;
820 wid_list[index].size = scan_info->ies_len;
821 index++;
823 wid_list[index].id = WID_SCAN_TYPE;
824 wid_list[index].type = WID_CHAR;
825 wid_list[index].size = sizeof(char);
826 wid_list[index].val = (s8 *)&scan_info->type;
827 index++;
829 wid_list[index].id = WID_SCAN_CHANNEL_LIST;
830 wid_list[index].type = WID_BIN_DATA;
832 if (scan_info->ch_freq_list &&
833 scan_info->ch_list_len > 0) {
834 int i;
836 for (i = 0; i < scan_info->ch_list_len; i++) {
837 if (scan_info->ch_freq_list[i] > 0)
838 scan_info->ch_freq_list[i] -= 1;
842 wid_list[index].val = scan_info->ch_freq_list;
843 wid_list[index].size = scan_info->ch_list_len;
844 index++;
846 wid_list[index].id = WID_START_SCAN_REQ;
847 wid_list[index].type = WID_CHAR;
848 wid_list[index].size = sizeof(char);
849 wid_list[index].val = (s8 *)&scan_info->src;
850 index++;
852 if (hif_drv->hif_state == HOST_IF_CONNECTED)
853 scan_while_connected = true;
854 else if (hif_drv->hif_state == HOST_IF_IDLE)
855 scan_while_connected = false;
857 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
858 index,
859 wilc_get_vif_idx(vif));
861 if (result)
862 netdev_err(vif->ndev, "Failed to send scan parameters\n");
864 error:
865 if (result) {
866 del_timer(&hif_drv->scan_timer);
867 handle_scan_done(vif, SCAN_EVENT_ABORTED);
870 kfree(scan_info->ch_freq_list);
871 scan_info->ch_freq_list = NULL;
873 kfree(scan_info->ies);
874 scan_info->ies = NULL;
875 kfree(scan_info->hidden_network.net_info);
876 scan_info->hidden_network.net_info = NULL;
878 kfree(hdn_ntwk_wid_val);
880 return result;
883 static s32 handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
885 s32 result = 0;
886 u8 abort_running_scan;
887 struct wid wid;
888 struct host_if_drv *hif_drv = vif->hif_drv;
889 struct user_scan_req *scan_req;
891 if (evt == SCAN_EVENT_ABORTED) {
892 abort_running_scan = 1;
893 wid.id = (u16)WID_ABORT_RUNNING_SCAN;
894 wid.type = WID_CHAR;
895 wid.val = (s8 *)&abort_running_scan;
896 wid.size = sizeof(char);
898 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
899 wilc_get_vif_idx(vif));
901 if (result) {
902 netdev_err(vif->ndev, "Failed to set abort running\n");
903 result = -EFAULT;
907 if (!hif_drv) {
908 netdev_err(vif->ndev, "Driver handler is NULL\n");
909 return result;
912 scan_req = &hif_drv->usr_scan_req;
913 if (scan_req->scan_result) {
914 scan_req->scan_result(evt, NULL, scan_req->arg, NULL);
915 scan_req->scan_result = NULL;
918 return result;
921 u8 wilc_connected_ssid[6] = {0};
922 static s32 handle_connect(struct wilc_vif *vif,
923 struct connect_attr *conn_attr)
925 s32 result = 0;
926 struct wid wid_list[8];
927 u32 wid_cnt = 0, dummyval = 0;
928 u8 *cur_byte = NULL;
929 struct join_bss_param *bss_param;
930 struct host_if_drv *hif_drv = vif->hif_drv;
932 if (memcmp(conn_attr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
933 result = 0;
934 netdev_err(vif->ndev, "Discard connect request\n");
935 return result;
938 bss_param = conn_attr->params;
939 if (!bss_param) {
940 netdev_err(vif->ndev, "Required BSSID not found\n");
941 result = -ENOENT;
942 goto error;
945 if (conn_attr->bssid) {
946 hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
947 if (!hif_drv->usr_conn_req.bssid) {
948 result = -ENOMEM;
949 goto error;
951 memcpy(hif_drv->usr_conn_req.bssid, conn_attr->bssid, 6);
954 hif_drv->usr_conn_req.ssid_len = conn_attr->ssid_len;
955 if (conn_attr->ssid) {
956 hif_drv->usr_conn_req.ssid = kmalloc(conn_attr->ssid_len + 1,
957 GFP_KERNEL);
958 if (!hif_drv->usr_conn_req.ssid) {
959 result = -ENOMEM;
960 goto error;
962 memcpy(hif_drv->usr_conn_req.ssid,
963 conn_attr->ssid,
964 conn_attr->ssid_len);
965 hif_drv->usr_conn_req.ssid[conn_attr->ssid_len] = '\0';
968 hif_drv->usr_conn_req.ies_len = conn_attr->ies_len;
969 if (conn_attr->ies) {
970 hif_drv->usr_conn_req.ies = kmalloc(conn_attr->ies_len,
971 GFP_KERNEL);
972 if (!hif_drv->usr_conn_req.ies) {
973 result = -ENOMEM;
974 goto error;
976 memcpy(hif_drv->usr_conn_req.ies,
977 conn_attr->ies,
978 conn_attr->ies_len);
981 hif_drv->usr_conn_req.security = conn_attr->security;
982 hif_drv->usr_conn_req.auth_type = conn_attr->auth_type;
983 hif_drv->usr_conn_req.conn_result = conn_attr->result;
984 hif_drv->usr_conn_req.arg = conn_attr->arg;
986 wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
987 wid_list[wid_cnt].type = WID_INT;
988 wid_list[wid_cnt].size = sizeof(u32);
989 wid_list[wid_cnt].val = (s8 *)(&(dummyval));
990 wid_cnt++;
992 wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT;
993 wid_list[wid_cnt].type = WID_INT;
994 wid_list[wid_cnt].size = sizeof(u32);
995 wid_list[wid_cnt].val = (s8 *)(&(dummyval));
996 wid_cnt++;
998 wid_list[wid_cnt].id = WID_FAILED_COUNT;
999 wid_list[wid_cnt].type = WID_INT;
1000 wid_list[wid_cnt].size = sizeof(u32);
1001 wid_list[wid_cnt].val = (s8 *)(&(dummyval));
1002 wid_cnt++;
1004 wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE;
1005 wid_list[wid_cnt].type = WID_BIN_DATA;
1006 wid_list[wid_cnt].val = hif_drv->usr_conn_req.ies;
1007 wid_list[wid_cnt].size = hif_drv->usr_conn_req.ies_len;
1008 wid_cnt++;
1010 if (memcmp("DIRECT-", conn_attr->ssid, 7)) {
1011 info_element_size = hif_drv->usr_conn_req.ies_len;
1012 info_element = kmalloc(info_element_size, GFP_KERNEL);
1013 memcpy(info_element, hif_drv->usr_conn_req.ies,
1014 info_element_size);
1016 wid_list[wid_cnt].id = (u16)WID_11I_MODE;
1017 wid_list[wid_cnt].type = WID_CHAR;
1018 wid_list[wid_cnt].size = sizeof(char);
1019 wid_list[wid_cnt].val = (s8 *)&hif_drv->usr_conn_req.security;
1020 wid_cnt++;
1022 if (memcmp("DIRECT-", conn_attr->ssid, 7))
1023 mode_11i = hif_drv->usr_conn_req.security;
1025 wid_list[wid_cnt].id = (u16)WID_AUTH_TYPE;
1026 wid_list[wid_cnt].type = WID_CHAR;
1027 wid_list[wid_cnt].size = sizeof(char);
1028 wid_list[wid_cnt].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
1029 wid_cnt++;
1031 if (memcmp("DIRECT-", conn_attr->ssid, 7))
1032 auth_type = (u8)hif_drv->usr_conn_req.auth_type;
1034 wid_list[wid_cnt].id = (u16)WID_JOIN_REQ_EXTENDED;
1035 wid_list[wid_cnt].type = WID_STR;
1036 wid_list[wid_cnt].size = 112;
1037 wid_list[wid_cnt].val = kmalloc(wid_list[wid_cnt].size, GFP_KERNEL);
1039 if (memcmp("DIRECT-", conn_attr->ssid, 7)) {
1040 join_req_size = wid_list[wid_cnt].size;
1041 join_req = kmalloc(join_req_size, GFP_KERNEL);
1043 if (!wid_list[wid_cnt].val) {
1044 result = -EFAULT;
1045 goto error;
1048 cur_byte = wid_list[wid_cnt].val;
1050 if (conn_attr->ssid) {
1051 memcpy(cur_byte, conn_attr->ssid, conn_attr->ssid_len);
1052 cur_byte[conn_attr->ssid_len] = '\0';
1054 cur_byte += MAX_SSID_LEN;
1055 *(cur_byte++) = INFRASTRUCTURE;
1057 if (conn_attr->ch >= 1 && conn_attr->ch <= 14) {
1058 *(cur_byte++) = conn_attr->ch;
1059 } else {
1060 netdev_err(vif->ndev, "Channel out of range\n");
1061 *(cur_byte++) = 0xFF;
1063 *(cur_byte++) = (bss_param->cap_info) & 0xFF;
1064 *(cur_byte++) = ((bss_param->cap_info) >> 8) & 0xFF;
1066 if (conn_attr->bssid)
1067 memcpy(cur_byte, conn_attr->bssid, 6);
1068 cur_byte += 6;
1070 if (conn_attr->bssid)
1071 memcpy(cur_byte, conn_attr->bssid, 6);
1072 cur_byte += 6;
1074 *(cur_byte++) = (bss_param->beacon_period) & 0xFF;
1075 *(cur_byte++) = ((bss_param->beacon_period) >> 8) & 0xFF;
1076 *(cur_byte++) = bss_param->dtim_period;
1078 memcpy(cur_byte, bss_param->supp_rates, MAX_RATES_SUPPORTED + 1);
1079 cur_byte += (MAX_RATES_SUPPORTED + 1);
1081 *(cur_byte++) = bss_param->wmm_cap;
1082 *(cur_byte++) = bss_param->uapsd_cap;
1084 *(cur_byte++) = bss_param->ht_capable;
1085 hif_drv->usr_conn_req.ht_capable = bss_param->ht_capable;
1087 *(cur_byte++) = bss_param->rsn_found;
1088 *(cur_byte++) = bss_param->rsn_grp_policy;
1089 *(cur_byte++) = bss_param->mode_802_11i;
1091 memcpy(cur_byte, bss_param->rsn_pcip_policy,
1092 sizeof(bss_param->rsn_pcip_policy));
1093 cur_byte += sizeof(bss_param->rsn_pcip_policy);
1095 memcpy(cur_byte, bss_param->rsn_auth_policy,
1096 sizeof(bss_param->rsn_auth_policy));
1097 cur_byte += sizeof(bss_param->rsn_auth_policy);
1099 memcpy(cur_byte, bss_param->rsn_cap, sizeof(bss_param->rsn_cap));
1100 cur_byte += sizeof(bss_param->rsn_cap);
1102 *(cur_byte++) = REAL_JOIN_REQ;
1103 *(cur_byte++) = bss_param->noa_enabled;
1105 if (bss_param->noa_enabled) {
1106 *(cur_byte++) = (bss_param->tsf) & 0xFF;
1107 *(cur_byte++) = ((bss_param->tsf) >> 8) & 0xFF;
1108 *(cur_byte++) = ((bss_param->tsf) >> 16) & 0xFF;
1109 *(cur_byte++) = ((bss_param->tsf) >> 24) & 0xFF;
1111 *(cur_byte++) = bss_param->opp_enabled;
1112 *(cur_byte++) = bss_param->idx;
1114 if (bss_param->opp_enabled)
1115 *(cur_byte++) = bss_param->ct_window;
1117 *(cur_byte++) = bss_param->cnt;
1119 memcpy(cur_byte, bss_param->duration,
1120 sizeof(bss_param->duration));
1121 cur_byte += sizeof(bss_param->duration);
1123 memcpy(cur_byte, bss_param->interval,
1124 sizeof(bss_param->interval));
1125 cur_byte += sizeof(bss_param->interval);
1127 memcpy(cur_byte, bss_param->start_time,
1128 sizeof(bss_param->start_time));
1129 cur_byte += sizeof(bss_param->start_time);
1132 cur_byte = wid_list[wid_cnt].val;
1133 wid_cnt++;
1135 if (memcmp("DIRECT-", conn_attr->ssid, 7)) {
1136 memcpy(join_req, cur_byte, join_req_size);
1137 join_req_vif = vif;
1140 if (conn_attr->bssid)
1141 memcpy(wilc_connected_ssid,
1142 conn_attr->bssid, ETH_ALEN);
1144 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
1145 wid_cnt,
1146 wilc_get_vif_idx(vif));
1147 if (result) {
1148 netdev_err(vif->ndev, "failed to send config packet\n");
1149 result = -EFAULT;
1150 goto error;
1151 } else {
1152 hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
1155 error:
1156 if (result) {
1157 struct connect_info conn_info;
1159 del_timer(&hif_drv->connect_timer);
1161 memset(&conn_info, 0, sizeof(struct connect_info));
1163 if (conn_attr->result) {
1164 if (conn_attr->bssid)
1165 memcpy(conn_info.bssid, conn_attr->bssid, 6);
1167 if (conn_attr->ies) {
1168 conn_info.req_ies_len = conn_attr->ies_len;
1169 conn_info.req_ies = kmalloc(conn_attr->ies_len,
1170 GFP_KERNEL);
1171 memcpy(conn_info.req_ies,
1172 conn_attr->ies,
1173 conn_attr->ies_len);
1176 conn_attr->result(CONN_DISCONN_EVENT_CONN_RESP,
1177 &conn_info,
1178 MAC_DISCONNECTED,
1179 NULL,
1180 conn_attr->arg);
1181 hif_drv->hif_state = HOST_IF_IDLE;
1182 kfree(conn_info.req_ies);
1183 conn_info.req_ies = NULL;
1185 } else {
1186 netdev_err(vif->ndev, "Connect callback is NULL\n");
1190 kfree(conn_attr->bssid);
1191 conn_attr->bssid = NULL;
1193 kfree(conn_attr->ssid);
1194 conn_attr->ssid = NULL;
1196 kfree(conn_attr->ies);
1197 conn_attr->ies = NULL;
1199 kfree(cur_byte);
1200 return result;
1203 static s32 handle_connect_timeout(struct wilc_vif *vif)
1205 s32 result = 0;
1206 struct connect_info info;
1207 struct wid wid;
1208 u16 dummy_reason_code = 0;
1209 struct host_if_drv *hif_drv = vif->hif_drv;
1211 if (!hif_drv) {
1212 netdev_err(vif->ndev, "Driver handler is NULL\n");
1213 return result;
1216 hif_drv->hif_state = HOST_IF_IDLE;
1218 scan_while_connected = false;
1220 memset(&info, 0, sizeof(struct connect_info));
1222 if (hif_drv->usr_conn_req.conn_result) {
1223 if (hif_drv->usr_conn_req.bssid) {
1224 memcpy(info.bssid,
1225 hif_drv->usr_conn_req.bssid, 6);
1228 if (hif_drv->usr_conn_req.ies) {
1229 info.req_ies_len = hif_drv->usr_conn_req.ies_len;
1230 info.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1231 memcpy(info.req_ies,
1232 hif_drv->usr_conn_req.ies,
1233 hif_drv->usr_conn_req.ies_len);
1236 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1237 &info,
1238 MAC_DISCONNECTED,
1239 NULL,
1240 hif_drv->usr_conn_req.arg);
1242 kfree(info.req_ies);
1243 info.req_ies = NULL;
1244 } else {
1245 netdev_err(vif->ndev, "Connect callback is NULL\n");
1248 wid.id = (u16)WID_DISCONNECT;
1249 wid.type = WID_CHAR;
1250 wid.val = (s8 *)&dummy_reason_code;
1251 wid.size = sizeof(char);
1253 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1254 wilc_get_vif_idx(vif));
1255 if (result)
1256 netdev_err(vif->ndev, "Failed to send disconnect\n");
1258 hif_drv->usr_conn_req.ssid_len = 0;
1259 kfree(hif_drv->usr_conn_req.ssid);
1260 hif_drv->usr_conn_req.ssid = NULL;
1261 kfree(hif_drv->usr_conn_req.bssid);
1262 hif_drv->usr_conn_req.bssid = NULL;
1263 hif_drv->usr_conn_req.ies_len = 0;
1264 kfree(hif_drv->usr_conn_req.ies);
1265 hif_drv->usr_conn_req.ies = NULL;
1267 eth_zero_addr(wilc_connected_ssid);
1269 if (join_req && join_req_vif == vif) {
1270 kfree(join_req);
1271 join_req = NULL;
1274 if (info_element && join_req_vif == vif) {
1275 kfree(info_element);
1276 info_element = NULL;
1279 return result;
1282 static s32 handle_rcvd_ntwrk_info(struct wilc_vif *vif,
1283 struct rcvd_net_info *rcvd_info)
1285 u32 i;
1286 bool found;
1287 s32 result = 0;
1288 struct network_info *info = NULL;
1289 void *params = NULL;
1290 struct host_if_drv *hif_drv = vif->hif_drv;
1291 struct user_scan_req *scan_req = &hif_drv->usr_scan_req;
1293 found = true;
1295 if (!scan_req->scan_result)
1296 goto done;
1298 wilc_parse_network_info(rcvd_info->buffer, &info);
1299 if (!info || !scan_req->scan_result) {
1300 netdev_err(vif->ndev, "driver is null\n");
1301 result = -EINVAL;
1302 goto done;
1305 for (i = 0; i < scan_req->rcvd_ch_cnt; i++) {
1306 if (memcmp(scan_req->net_info[i].bssid, info->bssid, 6) == 0) {
1307 if (info->rssi <= scan_req->net_info[i].rssi) {
1308 goto done;
1309 } else {
1310 scan_req->net_info[i].rssi = info->rssi;
1311 found = false;
1312 break;
1317 if (found) {
1318 if (scan_req->rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
1319 scan_req->net_info[scan_req->rcvd_ch_cnt].rssi = info->rssi;
1321 memcpy(scan_req->net_info[scan_req->rcvd_ch_cnt].bssid,
1322 info->bssid, 6);
1324 scan_req->rcvd_ch_cnt++;
1326 info->new_network = true;
1327 params = host_int_parse_join_bss_param(info);
1329 scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info,
1330 scan_req->arg, params);
1332 } else {
1333 info->new_network = false;
1334 scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info,
1335 scan_req->arg, NULL);
1338 done:
1339 kfree(rcvd_info->buffer);
1340 rcvd_info->buffer = NULL;
1342 if (info) {
1343 kfree(info->ies);
1344 kfree(info);
1347 return result;
1350 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
1351 u8 *assoc_resp_info,
1352 u32 max_assoc_resp_info_len,
1353 u32 *rcvd_assoc_resp_info_len);
1355 static s32 handle_rcvd_gnrl_async_info(struct wilc_vif *vif,
1356 struct rcvd_async_info *rcvd_info)
1358 s32 result = 0;
1359 u8 msg_type = 0;
1360 u8 msg_id = 0;
1361 u16 msg_len = 0;
1362 u16 wid_id = (u16)WID_NIL;
1363 u8 wid_len = 0;
1364 u8 mac_status;
1365 u8 mac_status_reason_code;
1366 u8 mac_status_additional_info;
1367 struct connect_info conn_info;
1368 struct disconnect_info disconn_info;
1369 s32 err = 0;
1370 struct host_if_drv *hif_drv = vif->hif_drv;
1372 if (!hif_drv) {
1373 netdev_err(vif->ndev, "Driver handler is NULL\n");
1374 return -ENODEV;
1377 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP ||
1378 hif_drv->hif_state == HOST_IF_CONNECTED ||
1379 hif_drv->usr_scan_req.scan_result) {
1380 if (!rcvd_info->buffer ||
1381 !hif_drv->usr_conn_req.conn_result) {
1382 netdev_err(vif->ndev, "driver is null\n");
1383 return -EINVAL;
1386 msg_type = rcvd_info->buffer[0];
1388 if ('I' != msg_type) {
1389 netdev_err(vif->ndev, "Received Message incorrect.\n");
1390 return -EFAULT;
1393 msg_id = rcvd_info->buffer[1];
1394 msg_len = MAKE_WORD16(rcvd_info->buffer[2], rcvd_info->buffer[3]);
1395 wid_id = MAKE_WORD16(rcvd_info->buffer[4], rcvd_info->buffer[5]);
1396 wid_len = rcvd_info->buffer[6];
1397 mac_status = rcvd_info->buffer[7];
1398 mac_status_reason_code = rcvd_info->buffer[8];
1399 mac_status_additional_info = rcvd_info->buffer[9];
1400 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
1401 u32 rcvd_assoc_resp_info_len = 0;
1402 struct connect_resp_info *connect_resp_info = NULL;
1404 memset(&conn_info, 0, sizeof(struct connect_info));
1406 if (mac_status == MAC_CONNECTED) {
1407 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
1409 host_int_get_assoc_res_info(vif,
1410 rcv_assoc_resp,
1411 MAX_ASSOC_RESP_FRAME_SIZE,
1412 &rcvd_assoc_resp_info_len);
1414 if (rcvd_assoc_resp_info_len != 0) {
1415 err = wilc_parse_assoc_resp_info(rcv_assoc_resp, rcvd_assoc_resp_info_len,
1416 &connect_resp_info);
1417 if (err) {
1418 netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", err);
1419 } else {
1420 conn_info.status = connect_resp_info->status;
1422 if (conn_info.status == SUCCESSFUL_STATUSCODE && connect_resp_info->ies) {
1423 conn_info.resp_ies_len = connect_resp_info->ies_len;
1424 conn_info.resp_ies = kmalloc(connect_resp_info->ies_len, GFP_KERNEL);
1425 memcpy(conn_info.resp_ies, connect_resp_info->ies,
1426 connect_resp_info->ies_len);
1429 if (connect_resp_info) {
1430 kfree(connect_resp_info->ies);
1431 kfree(connect_resp_info);
1437 if (mac_status == MAC_CONNECTED &&
1438 conn_info.status != SUCCESSFUL_STATUSCODE) {
1439 netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1440 eth_zero_addr(wilc_connected_ssid);
1441 } else if (mac_status == MAC_DISCONNECTED) {
1442 netdev_err(vif->ndev, "Received MAC status is MAC_DISCONNECTED\n");
1443 eth_zero_addr(wilc_connected_ssid);
1446 if (hif_drv->usr_conn_req.bssid) {
1447 memcpy(conn_info.bssid, hif_drv->usr_conn_req.bssid, 6);
1449 if (mac_status == MAC_CONNECTED &&
1450 conn_info.status == SUCCESSFUL_STATUSCODE) {
1451 memcpy(hif_drv->assoc_bssid,
1452 hif_drv->usr_conn_req.bssid, ETH_ALEN);
1456 if (hif_drv->usr_conn_req.ies) {
1457 conn_info.req_ies_len = hif_drv->usr_conn_req.ies_len;
1458 conn_info.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1459 memcpy(conn_info.req_ies,
1460 hif_drv->usr_conn_req.ies,
1461 hif_drv->usr_conn_req.ies_len);
1464 del_timer(&hif_drv->connect_timer);
1465 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1466 &conn_info,
1467 mac_status,
1468 NULL,
1469 hif_drv->usr_conn_req.arg);
1471 if (mac_status == MAC_CONNECTED &&
1472 conn_info.status == SUCCESSFUL_STATUSCODE) {
1473 wilc_set_power_mgmt(vif, 0, 0);
1475 hif_drv->hif_state = HOST_IF_CONNECTED;
1477 wilc_optaining_ip = true;
1478 mod_timer(&wilc_during_ip_timer,
1479 jiffies + msecs_to_jiffies(10000));
1480 } else {
1481 hif_drv->hif_state = HOST_IF_IDLE;
1482 scan_while_connected = false;
1485 kfree(conn_info.resp_ies);
1486 conn_info.resp_ies = NULL;
1488 kfree(conn_info.req_ies);
1489 conn_info.req_ies = NULL;
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 } else if ((mac_status == MAC_DISCONNECTED) &&
1499 (hif_drv->hif_state == HOST_IF_CONNECTED)) {
1500 memset(&disconn_info, 0, sizeof(struct disconnect_info));
1502 if (hif_drv->usr_scan_req.scan_result) {
1503 del_timer(&hif_drv->scan_timer);
1504 handle_scan_done(vif, SCAN_EVENT_ABORTED);
1507 disconn_info.reason = 0;
1508 disconn_info.ie = NULL;
1509 disconn_info.ie_len = 0;
1511 if (hif_drv->usr_conn_req.conn_result) {
1512 wilc_optaining_ip = false;
1513 wilc_set_power_mgmt(vif, 0, 0);
1515 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1516 NULL,
1518 &disconn_info,
1519 hif_drv->usr_conn_req.arg);
1520 } else {
1521 netdev_err(vif->ndev, "Connect result NULL\n");
1524 eth_zero_addr(hif_drv->assoc_bssid);
1526 hif_drv->usr_conn_req.ssid_len = 0;
1527 kfree(hif_drv->usr_conn_req.ssid);
1528 hif_drv->usr_conn_req.ssid = NULL;
1529 kfree(hif_drv->usr_conn_req.bssid);
1530 hif_drv->usr_conn_req.bssid = NULL;
1531 hif_drv->usr_conn_req.ies_len = 0;
1532 kfree(hif_drv->usr_conn_req.ies);
1533 hif_drv->usr_conn_req.ies = NULL;
1535 if (join_req && join_req_vif == vif) {
1536 kfree(join_req);
1537 join_req = NULL;
1540 if (info_element && join_req_vif == vif) {
1541 kfree(info_element);
1542 info_element = NULL;
1545 hif_drv->hif_state = HOST_IF_IDLE;
1546 scan_while_connected = false;
1548 } else if ((mac_status == MAC_DISCONNECTED) &&
1549 (hif_drv->usr_scan_req.scan_result)) {
1550 del_timer(&hif_drv->scan_timer);
1551 if (hif_drv->usr_scan_req.scan_result)
1552 handle_scan_done(vif, SCAN_EVENT_ABORTED);
1556 kfree(rcvd_info->buffer);
1557 rcvd_info->buffer = NULL;
1559 return result;
1562 static int handle_key(struct wilc_vif *vif, struct key_attr *hif_key)
1564 s32 result = 0;
1565 struct wid wid;
1566 struct wid wid_list[5];
1567 u8 i;
1568 u8 *key_buf;
1569 s8 s8idxarray[1];
1570 s8 ret = 0;
1571 struct host_if_drv *hif_drv = vif->hif_drv;
1573 switch (hif_key->type) {
1574 case WEP:
1576 if (hif_key->action & ADDKEY_AP) {
1577 wid_list[0].id = (u16)WID_11I_MODE;
1578 wid_list[0].type = WID_CHAR;
1579 wid_list[0].size = sizeof(char);
1580 wid_list[0].val = (s8 *)&hif_key->attr.wep.mode;
1582 wid_list[1].id = WID_AUTH_TYPE;
1583 wid_list[1].type = WID_CHAR;
1584 wid_list[1].size = sizeof(char);
1585 wid_list[1].val = (s8 *)&hif_key->attr.wep.auth_type;
1587 key_buf = kmalloc(hif_key->attr.wep.key_len + 2,
1588 GFP_KERNEL);
1589 if (!key_buf)
1590 return -ENOMEM;
1592 key_buf[0] = hif_key->attr.wep.index;
1593 key_buf[1] = hif_key->attr.wep.key_len;
1595 memcpy(&key_buf[2], hif_key->attr.wep.key,
1596 hif_key->attr.wep.key_len);
1598 kfree(hif_key->attr.wep.key);
1600 wid_list[2].id = (u16)WID_WEP_KEY_VALUE;
1601 wid_list[2].type = WID_STR;
1602 wid_list[2].size = hif_key->attr.wep.key_len + 2;
1603 wid_list[2].val = (s8 *)key_buf;
1605 result = wilc_send_config_pkt(vif, SET_CFG,
1606 wid_list, 3,
1607 wilc_get_vif_idx(vif));
1608 kfree(key_buf);
1609 } else if (hif_key->action & ADDKEY) {
1610 key_buf = kmalloc(hif_key->attr.wep.key_len + 2, GFP_KERNEL);
1611 if (!key_buf)
1612 return -ENOMEM;
1613 key_buf[0] = hif_key->attr.wep.index;
1614 memcpy(key_buf + 1, &hif_key->attr.wep.key_len, 1);
1615 memcpy(key_buf + 2, hif_key->attr.wep.key,
1616 hif_key->attr.wep.key_len);
1617 kfree(hif_key->attr.wep.key);
1619 wid.id = (u16)WID_ADD_WEP_KEY;
1620 wid.type = WID_STR;
1621 wid.val = (s8 *)key_buf;
1622 wid.size = hif_key->attr.wep.key_len + 2;
1624 result = wilc_send_config_pkt(vif, SET_CFG,
1625 &wid, 1,
1626 wilc_get_vif_idx(vif));
1627 kfree(key_buf);
1628 } else if (hif_key->action & REMOVEKEY) {
1629 wid.id = (u16)WID_REMOVE_WEP_KEY;
1630 wid.type = WID_STR;
1632 s8idxarray[0] = (s8)hif_key->attr.wep.index;
1633 wid.val = s8idxarray;
1634 wid.size = 1;
1636 result = wilc_send_config_pkt(vif, SET_CFG,
1637 &wid, 1,
1638 wilc_get_vif_idx(vif));
1639 } else if (hif_key->action & DEFAULTKEY) {
1640 wid.id = (u16)WID_KEY_ID;
1641 wid.type = WID_CHAR;
1642 wid.val = (s8 *)&hif_key->attr.wep.index;
1643 wid.size = sizeof(char);
1645 result = wilc_send_config_pkt(vif, SET_CFG,
1646 &wid, 1,
1647 wilc_get_vif_idx(vif));
1649 complete(&hif_drv->comp_test_key_block);
1650 break;
1652 case WPA_RX_GTK:
1653 if (hif_key->action & ADDKEY_AP) {
1654 key_buf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1655 if (!key_buf) {
1656 ret = -ENOMEM;
1657 goto out_wpa_rx_gtk;
1660 if (hif_key->attr.wpa.seq)
1661 memcpy(key_buf + 6, hif_key->attr.wpa.seq, 8);
1663 memcpy(key_buf + 14, &hif_key->attr.wpa.index, 1);
1664 memcpy(key_buf + 15, &hif_key->attr.wpa.key_len, 1);
1665 memcpy(key_buf + 16, hif_key->attr.wpa.key,
1666 hif_key->attr.wpa.key_len);
1668 wid_list[0].id = (u16)WID_11I_MODE;
1669 wid_list[0].type = WID_CHAR;
1670 wid_list[0].size = sizeof(char);
1671 wid_list[0].val = (s8 *)&hif_key->attr.wpa.mode;
1673 wid_list[1].id = (u16)WID_ADD_RX_GTK;
1674 wid_list[1].type = WID_STR;
1675 wid_list[1].val = (s8 *)key_buf;
1676 wid_list[1].size = RX_MIC_KEY_MSG_LEN;
1678 result = wilc_send_config_pkt(vif, SET_CFG,
1679 wid_list, 2,
1680 wilc_get_vif_idx(vif));
1682 kfree(key_buf);
1683 complete(&hif_drv->comp_test_key_block);
1684 } else if (hif_key->action & ADDKEY) {
1685 key_buf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1686 if (!key_buf) {
1687 ret = -ENOMEM;
1688 goto out_wpa_rx_gtk;
1691 if (hif_drv->hif_state == HOST_IF_CONNECTED)
1692 memcpy(key_buf, hif_drv->assoc_bssid, ETH_ALEN);
1693 else
1694 netdev_err(vif->ndev, "Couldn't handle\n");
1696 memcpy(key_buf + 6, hif_key->attr.wpa.seq, 8);
1697 memcpy(key_buf + 14, &hif_key->attr.wpa.index, 1);
1698 memcpy(key_buf + 15, &hif_key->attr.wpa.key_len, 1);
1699 memcpy(key_buf + 16, hif_key->attr.wpa.key,
1700 hif_key->attr.wpa.key_len);
1702 wid.id = (u16)WID_ADD_RX_GTK;
1703 wid.type = WID_STR;
1704 wid.val = (s8 *)key_buf;
1705 wid.size = RX_MIC_KEY_MSG_LEN;
1707 result = wilc_send_config_pkt(vif, SET_CFG,
1708 &wid, 1,
1709 wilc_get_vif_idx(vif));
1711 kfree(key_buf);
1712 complete(&hif_drv->comp_test_key_block);
1714 out_wpa_rx_gtk:
1715 kfree(hif_key->attr.wpa.key);
1716 kfree(hif_key->attr.wpa.seq);
1717 if (ret)
1718 return ret;
1720 break;
1722 case WPA_PTK:
1723 if (hif_key->action & ADDKEY_AP) {
1724 key_buf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
1725 if (!key_buf) {
1726 ret = -ENOMEM;
1727 goto out_wpa_ptk;
1730 memcpy(key_buf, hif_key->attr.wpa.mac_addr, 6);
1731 memcpy(key_buf + 6, &hif_key->attr.wpa.index, 1);
1732 memcpy(key_buf + 7, &hif_key->attr.wpa.key_len, 1);
1733 memcpy(key_buf + 8, hif_key->attr.wpa.key,
1734 hif_key->attr.wpa.key_len);
1736 wid_list[0].id = (u16)WID_11I_MODE;
1737 wid_list[0].type = WID_CHAR;
1738 wid_list[0].size = sizeof(char);
1739 wid_list[0].val = (s8 *)&hif_key->attr.wpa.mode;
1741 wid_list[1].id = (u16)WID_ADD_PTK;
1742 wid_list[1].type = WID_STR;
1743 wid_list[1].val = (s8 *)key_buf;
1744 wid_list[1].size = PTK_KEY_MSG_LEN + 1;
1746 result = wilc_send_config_pkt(vif, SET_CFG,
1747 wid_list, 2,
1748 wilc_get_vif_idx(vif));
1749 kfree(key_buf);
1750 complete(&hif_drv->comp_test_key_block);
1751 } else if (hif_key->action & ADDKEY) {
1752 key_buf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
1753 if (!key_buf) {
1754 netdev_err(vif->ndev, "No buffer send PTK\n");
1755 ret = -ENOMEM;
1756 goto out_wpa_ptk;
1759 memcpy(key_buf, hif_key->attr.wpa.mac_addr, 6);
1760 memcpy(key_buf + 6, &hif_key->attr.wpa.key_len, 1);
1761 memcpy(key_buf + 7, hif_key->attr.wpa.key,
1762 hif_key->attr.wpa.key_len);
1764 wid.id = (u16)WID_ADD_PTK;
1765 wid.type = WID_STR;
1766 wid.val = (s8 *)key_buf;
1767 wid.size = PTK_KEY_MSG_LEN;
1769 result = wilc_send_config_pkt(vif, SET_CFG,
1770 &wid, 1,
1771 wilc_get_vif_idx(vif));
1772 kfree(key_buf);
1773 complete(&hif_drv->comp_test_key_block);
1776 out_wpa_ptk:
1777 kfree(hif_key->attr.wpa.key);
1778 if (ret)
1779 return ret;
1781 break;
1783 case PMKSA:
1784 key_buf = kmalloc((hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1785 if (!key_buf)
1786 return -ENOMEM;
1788 key_buf[0] = hif_key->attr.pmkid.numpmkid;
1790 for (i = 0; i < hif_key->attr.pmkid.numpmkid; i++) {
1791 memcpy(key_buf + ((PMKSA_KEY_LEN * i) + 1), hif_key->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1792 memcpy(key_buf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), hif_key->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
1795 wid.id = (u16)WID_PMKID_INFO;
1796 wid.type = WID_STR;
1797 wid.val = (s8 *)key_buf;
1798 wid.size = (hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1800 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1801 wilc_get_vif_idx(vif));
1803 kfree(key_buf);
1804 break;
1807 if (result)
1808 netdev_err(vif->ndev, "Failed to send key config packet\n");
1810 return result;
1813 static void handle_disconnect(struct wilc_vif *vif)
1815 struct wid wid;
1816 struct host_if_drv *hif_drv = vif->hif_drv;
1817 struct disconnect_info disconn_info;
1818 struct user_scan_req *scan_req;
1819 struct user_conn_req *conn_req;
1820 s32 result = 0;
1821 u16 dummy_reason_code = 0;
1823 wid.id = (u16)WID_DISCONNECT;
1824 wid.type = WID_CHAR;
1825 wid.val = (s8 *)&dummy_reason_code;
1826 wid.size = sizeof(char);
1828 wilc_optaining_ip = false;
1829 wilc_set_power_mgmt(vif, 0, 0);
1831 eth_zero_addr(wilc_connected_ssid);
1833 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1834 wilc_get_vif_idx(vif));
1836 if (result) {
1837 netdev_err(vif->ndev, "Failed to send dissconect\n");
1838 goto out;
1841 memset(&disconn_info, 0, sizeof(struct disconnect_info));
1843 disconn_info.reason = 0;
1844 disconn_info.ie = NULL;
1845 disconn_info.ie_len = 0;
1846 scan_req = &hif_drv->usr_scan_req;
1847 conn_req = &hif_drv->usr_conn_req;
1849 if (scan_req->scan_result) {
1850 del_timer(&hif_drv->scan_timer);
1851 scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg,
1852 NULL);
1853 scan_req->scan_result = NULL;
1856 if (conn_req->conn_result) {
1857 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
1858 del_timer(&hif_drv->connect_timer);
1860 conn_req->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
1861 0, &disconn_info, conn_req->arg);
1862 } else {
1863 netdev_err(vif->ndev, "conn_result = NULL\n");
1866 scan_while_connected = false;
1868 hif_drv->hif_state = HOST_IF_IDLE;
1870 eth_zero_addr(hif_drv->assoc_bssid);
1872 conn_req->ssid_len = 0;
1873 kfree(conn_req->ssid);
1874 conn_req->ssid = NULL;
1875 kfree(conn_req->bssid);
1876 conn_req->bssid = NULL;
1877 conn_req->ies_len = 0;
1878 kfree(conn_req->ies);
1879 conn_req->ies = NULL;
1881 if (join_req && join_req_vif == vif) {
1882 kfree(join_req);
1883 join_req = NULL;
1886 if (info_element && join_req_vif == vif) {
1887 kfree(info_element);
1888 info_element = NULL;
1891 out:
1893 complete(&hif_drv->comp_test_disconn_block);
1896 void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
1898 if (!vif->hif_drv)
1899 return;
1900 if (vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP ||
1901 vif->hif_drv->hif_state == HOST_IF_CONNECTING)
1902 wilc_disconnect(vif, 1);
1905 static void handle_get_rssi(struct wilc_vif *vif)
1907 s32 result = 0;
1908 struct wid wid;
1910 wid.id = (u16)WID_RSSI;
1911 wid.type = WID_CHAR;
1912 wid.val = &rssi;
1913 wid.size = sizeof(char);
1915 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1916 wilc_get_vif_idx(vif));
1917 if (result) {
1918 netdev_err(vif->ndev, "Failed to get RSSI value\n");
1919 result = -EFAULT;
1922 complete(&vif->hif_drv->comp_get_rssi);
1925 static s32 handle_get_statistics(struct wilc_vif *vif,
1926 struct rf_info *stats)
1928 struct wid wid_list[5];
1929 u32 wid_cnt = 0, result = 0;
1931 wid_list[wid_cnt].id = WID_LINKSPEED;
1932 wid_list[wid_cnt].type = WID_CHAR;
1933 wid_list[wid_cnt].size = sizeof(char);
1934 wid_list[wid_cnt].val = (s8 *)&stats->link_speed;
1935 wid_cnt++;
1937 wid_list[wid_cnt].id = WID_RSSI;
1938 wid_list[wid_cnt].type = WID_CHAR;
1939 wid_list[wid_cnt].size = sizeof(char);
1940 wid_list[wid_cnt].val = (s8 *)&stats->rssi;
1941 wid_cnt++;
1943 wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
1944 wid_list[wid_cnt].type = WID_INT;
1945 wid_list[wid_cnt].size = sizeof(u32);
1946 wid_list[wid_cnt].val = (s8 *)&stats->tx_cnt;
1947 wid_cnt++;
1949 wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT;
1950 wid_list[wid_cnt].type = WID_INT;
1951 wid_list[wid_cnt].size = sizeof(u32);
1952 wid_list[wid_cnt].val = (s8 *)&stats->rx_cnt;
1953 wid_cnt++;
1955 wid_list[wid_cnt].id = WID_FAILED_COUNT;
1956 wid_list[wid_cnt].type = WID_INT;
1957 wid_list[wid_cnt].size = sizeof(u32);
1958 wid_list[wid_cnt].val = (s8 *)&stats->tx_fail_cnt;
1959 wid_cnt++;
1961 result = wilc_send_config_pkt(vif, GET_CFG, wid_list,
1962 wid_cnt,
1963 wilc_get_vif_idx(vif));
1965 if (result)
1966 netdev_err(vif->ndev, "Failed to send scan parameters\n");
1968 if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
1969 stats->link_speed != DEFAULT_LINK_SPEED)
1970 wilc_enable_tcp_ack_filter(true);
1971 else if (stats->link_speed != DEFAULT_LINK_SPEED)
1972 wilc_enable_tcp_ack_filter(false);
1974 if (stats != &vif->wilc->dummy_statistics)
1975 complete(&hif_wait_response);
1976 return 0;
1979 static s32 handle_get_inactive_time(struct wilc_vif *vif,
1980 struct sta_inactive_t *hif_sta_inactive)
1982 s32 result = 0;
1983 u8 *stamac;
1984 struct wid wid;
1985 struct host_if_drv *hif_drv = vif->hif_drv;
1987 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
1988 wid.type = WID_STR;
1989 wid.size = ETH_ALEN;
1990 wid.val = kmalloc(wid.size, GFP_KERNEL);
1991 if (!wid.val)
1992 return -ENOMEM;
1994 stamac = wid.val;
1995 ether_addr_copy(stamac, hif_sta_inactive->mac);
1997 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1998 wilc_get_vif_idx(vif));
2000 if (result) {
2001 netdev_err(vif->ndev, "Failed to SET inactive time\n");
2002 return -EFAULT;
2005 wid.id = (u16)WID_GET_INACTIVE_TIME;
2006 wid.type = WID_INT;
2007 wid.val = (s8 *)&inactive_time;
2008 wid.size = sizeof(u32);
2010 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2011 wilc_get_vif_idx(vif));
2013 if (result) {
2014 netdev_err(vif->ndev, "Failed to get inactive time\n");
2015 return -EFAULT;
2018 complete(&hif_drv->comp_inactive_time);
2020 return result;
2023 static void handle_add_beacon(struct wilc_vif *vif, struct beacon_attr *param)
2025 s32 result = 0;
2026 struct wid wid;
2027 u8 *cur_byte;
2029 wid.id = (u16)WID_ADD_BEACON;
2030 wid.type = WID_BIN;
2031 wid.size = param->head_len + param->tail_len + 16;
2032 wid.val = kmalloc(wid.size, GFP_KERNEL);
2033 if (!wid.val)
2034 goto error;
2036 cur_byte = wid.val;
2037 *cur_byte++ = (param->interval & 0xFF);
2038 *cur_byte++ = ((param->interval >> 8) & 0xFF);
2039 *cur_byte++ = ((param->interval >> 16) & 0xFF);
2040 *cur_byte++ = ((param->interval >> 24) & 0xFF);
2042 *cur_byte++ = (param->dtim_period & 0xFF);
2043 *cur_byte++ = ((param->dtim_period >> 8) & 0xFF);
2044 *cur_byte++ = ((param->dtim_period >> 16) & 0xFF);
2045 *cur_byte++ = ((param->dtim_period >> 24) & 0xFF);
2047 *cur_byte++ = (param->head_len & 0xFF);
2048 *cur_byte++ = ((param->head_len >> 8) & 0xFF);
2049 *cur_byte++ = ((param->head_len >> 16) & 0xFF);
2050 *cur_byte++ = ((param->head_len >> 24) & 0xFF);
2052 memcpy(cur_byte, param->head, param->head_len);
2053 cur_byte += param->head_len;
2055 *cur_byte++ = (param->tail_len & 0xFF);
2056 *cur_byte++ = ((param->tail_len >> 8) & 0xFF);
2057 *cur_byte++ = ((param->tail_len >> 16) & 0xFF);
2058 *cur_byte++ = ((param->tail_len >> 24) & 0xFF);
2060 if (param->tail)
2061 memcpy(cur_byte, param->tail, param->tail_len);
2062 cur_byte += param->tail_len;
2064 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2065 wilc_get_vif_idx(vif));
2066 if (result)
2067 netdev_err(vif->ndev, "Failed to send add beacon\n");
2069 error:
2070 kfree(wid.val);
2071 kfree(param->head);
2072 kfree(param->tail);
2075 static void handle_del_beacon(struct wilc_vif *vif)
2077 s32 result = 0;
2078 struct wid wid;
2079 u8 *cur_byte;
2081 wid.id = (u16)WID_DEL_BEACON;
2082 wid.type = WID_CHAR;
2083 wid.size = sizeof(char);
2084 wid.val = &del_beacon;
2086 if (!wid.val)
2087 return;
2089 cur_byte = wid.val;
2091 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2092 wilc_get_vif_idx(vif));
2093 if (result)
2094 netdev_err(vif->ndev, "Failed to send delete beacon\n");
2097 static u32 wilc_hif_pack_sta_param(u8 *buff, struct add_sta_param *param)
2099 u8 *cur_byte;
2101 cur_byte = buff;
2103 memcpy(cur_byte, param->bssid, ETH_ALEN);
2104 cur_byte += ETH_ALEN;
2106 *cur_byte++ = param->aid & 0xFF;
2107 *cur_byte++ = (param->aid >> 8) & 0xFF;
2109 *cur_byte++ = param->rates_len;
2110 if (param->rates_len > 0)
2111 memcpy(cur_byte, param->rates, param->rates_len);
2112 cur_byte += param->rates_len;
2114 *cur_byte++ = param->ht_supported;
2115 memcpy(cur_byte, &param->ht_capa, sizeof(struct ieee80211_ht_cap));
2116 cur_byte += sizeof(struct ieee80211_ht_cap);
2118 *cur_byte++ = param->flags_mask & 0xFF;
2119 *cur_byte++ = (param->flags_mask >> 8) & 0xFF;
2121 *cur_byte++ = param->flags_set & 0xFF;
2122 *cur_byte++ = (param->flags_set >> 8) & 0xFF;
2124 return cur_byte - buff;
2127 static void handle_add_station(struct wilc_vif *vif,
2128 struct add_sta_param *param)
2130 s32 result = 0;
2131 struct wid wid;
2132 u8 *cur_byte;
2134 wid.id = (u16)WID_ADD_STA;
2135 wid.type = WID_BIN;
2136 wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
2138 wid.val = kmalloc(wid.size, GFP_KERNEL);
2139 if (!wid.val)
2140 goto error;
2142 cur_byte = wid.val;
2143 cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
2145 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2146 wilc_get_vif_idx(vif));
2147 if (result != 0)
2148 netdev_err(vif->ndev, "Failed to send add station\n");
2150 error:
2151 kfree(param->rates);
2152 kfree(wid.val);
2155 static void handle_del_all_sta(struct wilc_vif *vif,
2156 struct del_all_sta *param)
2158 s32 result = 0;
2159 struct wid wid;
2160 u8 *curr_byte;
2161 u8 i;
2162 u8 zero_buff[6] = {0};
2164 wid.id = (u16)WID_DEL_ALL_STA;
2165 wid.type = WID_STR;
2166 wid.size = (param->assoc_sta * ETH_ALEN) + 1;
2168 wid.val = kmalloc((param->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2169 if (!wid.val)
2170 goto error;
2172 curr_byte = wid.val;
2174 *(curr_byte++) = param->assoc_sta;
2176 for (i = 0; i < MAX_NUM_STA; i++) {
2177 if (memcmp(param->del_all_sta[i], zero_buff, ETH_ALEN))
2178 memcpy(curr_byte, param->del_all_sta[i], ETH_ALEN);
2179 else
2180 continue;
2182 curr_byte += ETH_ALEN;
2185 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2186 wilc_get_vif_idx(vif));
2187 if (result)
2188 netdev_err(vif->ndev, "Failed to send add station\n");
2190 error:
2191 kfree(wid.val);
2193 complete(&hif_wait_response);
2196 static void handle_del_station(struct wilc_vif *vif, struct del_sta *param)
2198 s32 result = 0;
2199 struct wid wid;
2200 u8 *cur_byte;
2202 wid.id = (u16)WID_REMOVE_STA;
2203 wid.type = WID_BIN;
2204 wid.size = ETH_ALEN;
2206 wid.val = kmalloc(wid.size, GFP_KERNEL);
2207 if (!wid.val)
2208 goto error;
2210 cur_byte = wid.val;
2212 ether_addr_copy(cur_byte, param->mac_addr);
2214 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2215 wilc_get_vif_idx(vif));
2216 if (result)
2217 netdev_err(vif->ndev, "Failed to send add station\n");
2219 error:
2220 kfree(wid.val);
2223 static void handle_edit_station(struct wilc_vif *vif,
2224 struct add_sta_param *param)
2226 s32 result = 0;
2227 struct wid wid;
2228 u8 *cur_byte;
2230 wid.id = (u16)WID_EDIT_STA;
2231 wid.type = WID_BIN;
2232 wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
2234 wid.val = kmalloc(wid.size, GFP_KERNEL);
2235 if (!wid.val)
2236 goto error;
2238 cur_byte = wid.val;
2239 cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
2241 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2242 wilc_get_vif_idx(vif));
2243 if (result)
2244 netdev_err(vif->ndev, "Failed to send edit station\n");
2246 error:
2247 kfree(param->rates);
2248 kfree(wid.val);
2251 static int handle_remain_on_chan(struct wilc_vif *vif,
2252 struct remain_ch *hif_remain_ch)
2254 s32 result = 0;
2255 u8 remain_on_chan_flag;
2256 struct wid wid;
2257 struct host_if_drv *hif_drv = vif->hif_drv;
2259 if (!hif_drv->remain_on_ch_pending) {
2260 hif_drv->remain_on_ch.arg = hif_remain_ch->arg;
2261 hif_drv->remain_on_ch.expired = hif_remain_ch->expired;
2262 hif_drv->remain_on_ch.ready = hif_remain_ch->ready;
2263 hif_drv->remain_on_ch.ch = hif_remain_ch->ch;
2264 hif_drv->remain_on_ch.id = hif_remain_ch->id;
2265 } else {
2266 hif_remain_ch->ch = hif_drv->remain_on_ch.ch;
2269 if (hif_drv->usr_scan_req.scan_result) {
2270 hif_drv->remain_on_ch_pending = 1;
2271 result = -EBUSY;
2272 goto error;
2274 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
2275 result = -EBUSY;
2276 goto error;
2279 if (wilc_optaining_ip || wilc_connecting) {
2280 result = -EBUSY;
2281 goto error;
2284 remain_on_chan_flag = true;
2285 wid.id = (u16)WID_REMAIN_ON_CHAN;
2286 wid.type = WID_STR;
2287 wid.size = 2;
2288 wid.val = kmalloc(wid.size, GFP_KERNEL);
2289 if (!wid.val) {
2290 result = -ENOMEM;
2291 goto error;
2294 wid.val[0] = remain_on_chan_flag;
2295 wid.val[1] = (s8)hif_remain_ch->ch;
2297 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2298 wilc_get_vif_idx(vif));
2299 if (result != 0)
2300 netdev_err(vif->ndev, "Failed to set remain on channel\n");
2302 error:
2304 P2P_LISTEN_STATE = 1;
2305 hif_drv->remain_on_ch_timer_vif = vif;
2306 mod_timer(&hif_drv->remain_on_ch_timer,
2307 jiffies +
2308 msecs_to_jiffies(hif_remain_ch->duration));
2310 if (hif_drv->remain_on_ch.ready)
2311 hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
2313 if (hif_drv->remain_on_ch_pending)
2314 hif_drv->remain_on_ch_pending = 0;
2317 return result;
2320 static int handle_register_frame(struct wilc_vif *vif,
2321 struct reg_frame *hif_reg_frame)
2323 s32 result = 0;
2324 struct wid wid;
2325 u8 *cur_byte;
2327 wid.id = (u16)WID_REGISTER_FRAME;
2328 wid.type = WID_STR;
2329 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2330 if (!wid.val)
2331 return -ENOMEM;
2333 cur_byte = wid.val;
2335 *cur_byte++ = hif_reg_frame->reg;
2336 *cur_byte++ = hif_reg_frame->reg_id;
2337 memcpy(cur_byte, &hif_reg_frame->frame_type, sizeof(u16));
2339 wid.size = sizeof(u16) + 2;
2341 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2342 wilc_get_vif_idx(vif));
2343 if (result) {
2344 netdev_err(vif->ndev, "Failed to frame register\n");
2345 result = -EINVAL;
2348 return result;
2351 static u32 handle_listen_state_expired(struct wilc_vif *vif,
2352 struct remain_ch *hif_remain_ch)
2354 u8 remain_on_chan_flag;
2355 struct wid wid;
2356 s32 result = 0;
2357 struct host_if_drv *hif_drv = vif->hif_drv;
2359 if (P2P_LISTEN_STATE) {
2360 remain_on_chan_flag = false;
2361 wid.id = (u16)WID_REMAIN_ON_CHAN;
2362 wid.type = WID_STR;
2363 wid.size = 2;
2364 wid.val = kmalloc(wid.size, GFP_KERNEL);
2366 if (!wid.val)
2367 return -ENOMEM;
2369 wid.val[0] = remain_on_chan_flag;
2370 wid.val[1] = FALSE_FRMWR_CHANNEL;
2372 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2373 wilc_get_vif_idx(vif));
2374 if (result != 0) {
2375 netdev_err(vif->ndev, "Failed to set remain channel\n");
2376 goto _done_;
2379 if (hif_drv->remain_on_ch.expired) {
2380 hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
2381 hif_remain_ch->id);
2383 P2P_LISTEN_STATE = 0;
2384 } else {
2385 netdev_dbg(vif->ndev, "Not in listen state\n");
2386 result = -EFAULT;
2389 _done_:
2390 return result;
2393 static void listen_timer_cb(struct timer_list *t)
2395 struct host_if_drv *hif_drv = from_timer(hif_drv, t,
2396 remain_on_ch_timer);
2397 struct wilc_vif *vif = hif_drv->remain_on_ch_timer_vif;
2398 s32 result = 0;
2399 struct host_if_msg msg;
2401 del_timer(&vif->hif_drv->remain_on_ch_timer);
2403 memset(&msg, 0, sizeof(struct host_if_msg));
2404 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2405 msg.vif = vif;
2406 msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
2408 result = wilc_enqueue_cmd(&msg);
2409 if (result)
2410 netdev_err(vif->ndev, "wilc_mq_send fail\n");
2413 static void handle_power_management(struct wilc_vif *vif,
2414 struct power_mgmt_param *pm_param)
2416 s32 result = 0;
2417 struct wid wid;
2418 s8 power_mode;
2420 wid.id = (u16)WID_POWER_MANAGEMENT;
2422 if (pm_param->enabled)
2423 power_mode = MIN_FAST_PS;
2424 else
2425 power_mode = NO_POWERSAVE;
2427 wid.val = &power_mode;
2428 wid.size = sizeof(char);
2430 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2431 wilc_get_vif_idx(vif));
2432 if (result)
2433 netdev_err(vif->ndev, "Failed to send power management\n");
2436 static void handle_set_mcast_filter(struct wilc_vif *vif,
2437 struct set_multicast *hif_set_mc)
2439 s32 result = 0;
2440 struct wid wid;
2441 u8 *cur_byte;
2443 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2444 wid.type = WID_BIN;
2445 wid.size = sizeof(struct set_multicast) + (hif_set_mc->cnt * ETH_ALEN);
2446 wid.val = kmalloc(wid.size, GFP_KERNEL);
2447 if (!wid.val)
2448 goto error;
2450 cur_byte = wid.val;
2451 *cur_byte++ = (hif_set_mc->enabled & 0xFF);
2452 *cur_byte++ = 0;
2453 *cur_byte++ = 0;
2454 *cur_byte++ = 0;
2456 *cur_byte++ = (hif_set_mc->cnt & 0xFF);
2457 *cur_byte++ = ((hif_set_mc->cnt >> 8) & 0xFF);
2458 *cur_byte++ = ((hif_set_mc->cnt >> 16) & 0xFF);
2459 *cur_byte++ = ((hif_set_mc->cnt >> 24) & 0xFF);
2461 if (hif_set_mc->cnt > 0)
2462 memcpy(cur_byte, wilc_multicast_mac_addr_list,
2463 ((hif_set_mc->cnt) * ETH_ALEN));
2465 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2466 wilc_get_vif_idx(vif));
2467 if (result)
2468 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2470 error:
2471 kfree(wid.val);
2474 static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
2476 int ret;
2477 struct wid wid;
2479 wid.id = (u16)WID_TX_POWER;
2480 wid.type = WID_CHAR;
2481 wid.val = &tx_pwr;
2482 wid.size = sizeof(char);
2484 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2485 wilc_get_vif_idx(vif));
2486 if (ret)
2487 netdev_err(vif->ndev, "Failed to set TX PWR\n");
2490 static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
2492 int ret = 0;
2493 struct wid wid;
2495 wid.id = (u16)WID_TX_POWER;
2496 wid.type = WID_CHAR;
2497 wid.val = (s8 *)tx_pwr;
2498 wid.size = sizeof(char);
2500 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2501 wilc_get_vif_idx(vif));
2502 if (ret)
2503 netdev_err(vif->ndev, "Failed to get TX PWR\n");
2505 complete(&hif_wait_response);
2508 static void host_if_work(struct work_struct *work)
2510 struct host_if_msg *msg;
2511 struct wilc *wilc;
2512 int ret = 0;
2514 msg = container_of(work, struct host_if_msg, work);
2515 wilc = msg->vif->wilc;
2517 if (msg->id == HOST_IF_MSG_CONNECT &&
2518 msg->vif->hif_drv->usr_scan_req.scan_result) {
2519 wilc_enqueue_cmd(msg);
2520 usleep_range(2 * 1000, 2 * 1000);
2521 goto free_msg;
2523 switch (msg->id) {
2524 case HOST_IF_MSG_SCAN:
2525 handle_scan(msg->vif, &msg->body.scan_info);
2526 break;
2528 case HOST_IF_MSG_CONNECT:
2529 handle_connect(msg->vif, &msg->body.con_info);
2530 break;
2532 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2533 handle_rcvd_ntwrk_info(msg->vif, &msg->body.net_info);
2534 break;
2536 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2537 handle_rcvd_gnrl_async_info(msg->vif,
2538 &msg->body.async_info);
2539 break;
2541 case HOST_IF_MSG_KEY:
2542 handle_key(msg->vif, &msg->body.key_info);
2543 break;
2545 case HOST_IF_MSG_CFG_PARAMS:
2546 handle_cfg_param(msg->vif, &msg->body.cfg_info);
2547 break;
2549 case HOST_IF_MSG_SET_CHANNEL:
2550 handle_set_channel(msg->vif, &msg->body.channel_info);
2551 break;
2553 case HOST_IF_MSG_DISCONNECT:
2554 handle_disconnect(msg->vif);
2555 break;
2557 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2558 del_timer(&msg->vif->hif_drv->scan_timer);
2560 if (!wilc_wlan_get_num_conn_ifcs(wilc))
2561 wilc_chip_sleep_manually(wilc);
2563 handle_scan_done(msg->vif, SCAN_EVENT_DONE);
2565 if (msg->vif->hif_drv->remain_on_ch_pending)
2566 handle_remain_on_chan(msg->vif,
2567 &msg->body.remain_on_ch);
2569 break;
2571 case HOST_IF_MSG_GET_RSSI:
2572 handle_get_rssi(msg->vif);
2573 break;
2575 case HOST_IF_MSG_GET_STATISTICS:
2576 handle_get_statistics(msg->vif,
2577 (struct rf_info *)msg->body.data);
2578 break;
2580 case HOST_IF_MSG_ADD_BEACON:
2581 handle_add_beacon(msg->vif, &msg->body.beacon_info);
2582 break;
2584 case HOST_IF_MSG_DEL_BEACON:
2585 handle_del_beacon(msg->vif);
2586 break;
2588 case HOST_IF_MSG_ADD_STATION:
2589 handle_add_station(msg->vif, &msg->body.add_sta_info);
2590 break;
2592 case HOST_IF_MSG_DEL_STATION:
2593 handle_del_station(msg->vif, &msg->body.del_sta_info);
2594 break;
2596 case HOST_IF_MSG_EDIT_STATION:
2597 handle_edit_station(msg->vif, &msg->body.edit_sta_info);
2598 break;
2600 case HOST_IF_MSG_GET_INACTIVETIME:
2601 handle_get_inactive_time(msg->vif, &msg->body.mac_info);
2602 break;
2604 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2605 handle_scan_done(msg->vif, SCAN_EVENT_ABORTED);
2606 break;
2608 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2609 handle_connect_timeout(msg->vif);
2610 break;
2612 case HOST_IF_MSG_POWER_MGMT:
2613 handle_power_management(msg->vif,
2614 &msg->body.pwr_mgmt_info);
2615 break;
2617 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2618 ret = handle_set_wfi_drv_handler(msg->vif, &msg->body.drv);
2619 break;
2621 case HOST_IF_MSG_SET_OPERATION_MODE:
2622 handle_set_operation_mode(msg->vif, &msg->body.mode);
2623 break;
2625 case HOST_IF_MSG_SET_IPADDRESS:
2626 handle_set_ip_address(msg->vif,
2627 msg->body.ip_info.ip_addr,
2628 msg->body.ip_info.idx);
2629 break;
2631 case HOST_IF_MSG_GET_IPADDRESS:
2632 handle_get_ip_address(msg->vif, msg->body.ip_info.idx);
2633 break;
2635 case HOST_IF_MSG_GET_MAC_ADDRESS:
2636 handle_get_mac_address(msg->vif,
2637 &msg->body.get_mac_info);
2638 break;
2640 case HOST_IF_MSG_REMAIN_ON_CHAN:
2641 handle_remain_on_chan(msg->vif, &msg->body.remain_on_ch);
2642 break;
2644 case HOST_IF_MSG_REGISTER_FRAME:
2645 handle_register_frame(msg->vif, &msg->body.reg_frame);
2646 break;
2648 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2649 handle_listen_state_expired(msg->vif, &msg->body.remain_on_ch);
2650 break;
2652 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2653 handle_set_mcast_filter(msg->vif, &msg->body.multicast_info);
2654 break;
2656 case HOST_IF_MSG_DEL_ALL_STA:
2657 handle_del_all_sta(msg->vif, &msg->body.del_all_sta_info);
2658 break;
2660 case HOST_IF_MSG_SET_TX_POWER:
2661 handle_set_tx_pwr(msg->vif, msg->body.tx_power.tx_pwr);
2662 break;
2664 case HOST_IF_MSG_GET_TX_POWER:
2665 handle_get_tx_pwr(msg->vif, &msg->body.tx_power.tx_pwr);
2666 break;
2667 default:
2668 netdev_err(msg->vif->ndev, "[Host Interface] undefined\n");
2669 break;
2671 free_msg:
2672 if (ret)
2673 netdev_err(msg->vif->ndev, "Host cmd %d failed\n", msg->id);
2674 kfree(msg);
2675 complete(&hif_thread_comp);
2678 static void timer_scan_cb(struct timer_list *t)
2680 struct host_if_drv *hif_drv = from_timer(hif_drv, t, scan_timer);
2681 struct wilc_vif *vif = hif_drv->scan_timer_vif;
2682 struct host_if_msg msg;
2684 memset(&msg, 0, sizeof(struct host_if_msg));
2685 msg.vif = vif;
2686 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
2688 wilc_enqueue_cmd(&msg);
2691 static void timer_connect_cb(struct timer_list *t)
2693 struct host_if_drv *hif_drv = from_timer(hif_drv, t,
2694 connect_timer);
2695 struct wilc_vif *vif = hif_drv->connect_timer_vif;
2696 struct host_if_msg msg;
2698 memset(&msg, 0, sizeof(struct host_if_msg));
2699 msg.vif = vif;
2700 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
2702 wilc_enqueue_cmd(&msg);
2705 s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *sta_addr)
2707 struct wid wid;
2709 wid.id = (u16)WID_REMOVE_KEY;
2710 wid.type = WID_STR;
2711 wid.val = (s8 *)sta_addr;
2712 wid.size = 6;
2714 return 0;
2717 int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
2719 int result = 0;
2720 struct host_if_msg msg;
2721 struct host_if_drv *hif_drv = vif->hif_drv;
2723 if (!hif_drv) {
2724 result = -EFAULT;
2725 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2726 return result;
2729 memset(&msg, 0, sizeof(struct host_if_msg));
2731 msg.id = HOST_IF_MSG_KEY;
2732 msg.body.key_info.type = WEP;
2733 msg.body.key_info.action = REMOVEKEY;
2734 msg.vif = vif;
2735 msg.body.key_info.attr.wep.index = index;
2737 result = wilc_enqueue_cmd(&msg);
2738 if (result)
2739 netdev_err(vif->ndev, "Request to remove WEP key\n");
2740 else
2741 wait_for_completion(&hif_drv->comp_test_key_block);
2743 return result;
2746 int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
2748 int result = 0;
2749 struct host_if_msg msg;
2750 struct host_if_drv *hif_drv = vif->hif_drv;
2752 if (!hif_drv) {
2753 result = -EFAULT;
2754 netdev_err(vif->ndev, "driver is null\n");
2755 return result;
2758 memset(&msg, 0, sizeof(struct host_if_msg));
2760 msg.id = HOST_IF_MSG_KEY;
2761 msg.body.key_info.type = WEP;
2762 msg.body.key_info.action = DEFAULTKEY;
2763 msg.vif = vif;
2764 msg.body.key_info.attr.wep.index = index;
2766 result = wilc_enqueue_cmd(&msg);
2767 if (result)
2768 netdev_err(vif->ndev, "Default key index\n");
2769 else
2770 wait_for_completion(&hif_drv->comp_test_key_block);
2772 return result;
2775 int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2776 u8 index)
2778 int result = 0;
2779 struct host_if_msg msg;
2780 struct host_if_drv *hif_drv = vif->hif_drv;
2782 if (!hif_drv) {
2783 netdev_err(vif->ndev, "driver is null\n");
2784 return -EFAULT;
2787 memset(&msg, 0, sizeof(struct host_if_msg));
2789 msg.id = HOST_IF_MSG_KEY;
2790 msg.body.key_info.type = WEP;
2791 msg.body.key_info.action = ADDKEY;
2792 msg.vif = vif;
2793 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2794 if (!msg.body.key_info.attr.wep.key)
2795 return -ENOMEM;
2797 msg.body.key_info.attr.wep.key_len = len;
2798 msg.body.key_info.attr.wep.index = index;
2800 result = wilc_enqueue_cmd(&msg);
2801 if (result)
2802 netdev_err(vif->ndev, "STA - WEP Key\n");
2803 wait_for_completion(&hif_drv->comp_test_key_block);
2805 return result;
2808 int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
2809 u8 index, u8 mode, enum AUTHTYPE auth_type)
2811 int result = 0;
2812 struct host_if_msg msg;
2813 struct host_if_drv *hif_drv = vif->hif_drv;
2815 if (!hif_drv) {
2816 netdev_err(vif->ndev, "driver is null\n");
2817 return -EFAULT;
2820 memset(&msg, 0, sizeof(struct host_if_msg));
2822 msg.id = HOST_IF_MSG_KEY;
2823 msg.body.key_info.type = WEP;
2824 msg.body.key_info.action = ADDKEY_AP;
2825 msg.vif = vif;
2826 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2827 if (!msg.body.key_info.attr.wep.key)
2828 return -ENOMEM;
2830 msg.body.key_info.attr.wep.key_len = len;
2831 msg.body.key_info.attr.wep.index = index;
2832 msg.body.key_info.attr.wep.mode = mode;
2833 msg.body.key_info.attr.wep.auth_type = auth_type;
2835 result = wilc_enqueue_cmd(&msg);
2837 if (result)
2838 netdev_err(vif->ndev, "AP - WEP Key\n");
2839 else
2840 wait_for_completion(&hif_drv->comp_test_key_block);
2842 return result;
2845 int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
2846 const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
2847 u8 mode, u8 cipher_mode, u8 index)
2849 int result = 0;
2850 struct host_if_msg msg;
2851 struct host_if_drv *hif_drv = vif->hif_drv;
2852 u8 key_len = ptk_key_len;
2854 if (!hif_drv) {
2855 netdev_err(vif->ndev, "driver is null\n");
2856 return -EFAULT;
2859 if (rx_mic)
2860 key_len += RX_MIC_KEY_LEN;
2862 if (tx_mic)
2863 key_len += TX_MIC_KEY_LEN;
2865 memset(&msg, 0, sizeof(struct host_if_msg));
2867 msg.id = HOST_IF_MSG_KEY;
2868 msg.body.key_info.type = WPA_PTK;
2869 if (mode == AP_MODE) {
2870 msg.body.key_info.action = ADDKEY_AP;
2871 msg.body.key_info.attr.wpa.index = index;
2873 if (mode == STATION_MODE)
2874 msg.body.key_info.action = ADDKEY;
2876 msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
2877 if (!msg.body.key_info.attr.wpa.key)
2878 return -ENOMEM;
2880 if (rx_mic)
2881 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2882 RX_MIC_KEY_LEN);
2884 if (tx_mic)
2885 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
2886 TX_MIC_KEY_LEN);
2888 msg.body.key_info.attr.wpa.key_len = key_len;
2889 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
2890 msg.body.key_info.attr.wpa.mode = cipher_mode;
2891 msg.vif = vif;
2893 result = wilc_enqueue_cmd(&msg);
2895 if (result)
2896 netdev_err(vif->ndev, "PTK Key\n");
2897 else
2898 wait_for_completion(&hif_drv->comp_test_key_block);
2900 return result;
2903 int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
2904 u8 index, u32 key_rsc_len, const u8 *key_rsc,
2905 const u8 *rx_mic, const u8 *tx_mic, u8 mode,
2906 u8 cipher_mode)
2908 int result = 0;
2909 struct host_if_msg msg;
2910 struct host_if_drv *hif_drv = vif->hif_drv;
2911 u8 key_len = gtk_key_len;
2913 if (!hif_drv) {
2914 netdev_err(vif->ndev, "driver is null\n");
2915 return -EFAULT;
2917 memset(&msg, 0, sizeof(struct host_if_msg));
2919 if (rx_mic)
2920 key_len += RX_MIC_KEY_LEN;
2922 if (tx_mic)
2923 key_len += TX_MIC_KEY_LEN;
2925 if (key_rsc) {
2926 msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
2927 key_rsc_len,
2928 GFP_KERNEL);
2929 if (!msg.body.key_info.attr.wpa.seq)
2930 return -ENOMEM;
2933 msg.id = HOST_IF_MSG_KEY;
2934 msg.body.key_info.type = WPA_RX_GTK;
2935 msg.vif = vif;
2937 if (mode == AP_MODE) {
2938 msg.body.key_info.action = ADDKEY_AP;
2939 msg.body.key_info.attr.wpa.mode = cipher_mode;
2941 if (mode == STATION_MODE)
2942 msg.body.key_info.action = ADDKEY;
2944 msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
2945 key_len,
2946 GFP_KERNEL);
2947 if (!msg.body.key_info.attr.wpa.key)
2948 return -ENOMEM;
2950 if (rx_mic)
2951 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2952 RX_MIC_KEY_LEN);
2954 if (tx_mic)
2955 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
2956 TX_MIC_KEY_LEN);
2958 msg.body.key_info.attr.wpa.index = index;
2959 msg.body.key_info.attr.wpa.key_len = key_len;
2960 msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
2962 result = wilc_enqueue_cmd(&msg);
2963 if (result)
2964 netdev_err(vif->ndev, "RX GTK\n");
2965 else
2966 wait_for_completion(&hif_drv->comp_test_key_block);
2968 return result;
2971 int wilc_set_pmkid_info(struct wilc_vif *vif,
2972 struct host_if_pmkid_attr *pmkid)
2974 int result = 0;
2975 struct host_if_msg msg;
2976 int i;
2978 memset(&msg, 0, sizeof(struct host_if_msg));
2980 msg.id = HOST_IF_MSG_KEY;
2981 msg.body.key_info.type = PMKSA;
2982 msg.body.key_info.action = ADDKEY;
2983 msg.vif = vif;
2985 for (i = 0; i < pmkid->numpmkid; i++) {
2986 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
2987 &pmkid->pmkidlist[i].bssid, ETH_ALEN);
2988 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
2989 &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
2992 result = wilc_enqueue_cmd(&msg);
2993 if (result)
2994 netdev_err(vif->ndev, "PMKID Info\n");
2996 return result;
2999 int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
3001 int result = 0;
3002 struct host_if_msg msg;
3004 memset(&msg, 0, sizeof(struct host_if_msg));
3006 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
3007 msg.body.get_mac_info.mac_addr = mac_addr;
3008 msg.vif = vif;
3010 result = wilc_enqueue_cmd(&msg);
3011 if (result) {
3012 netdev_err(vif->ndev, "Failed to send get mac address\n");
3013 return -EFAULT;
3016 wait_for_completion(&hif_wait_response);
3017 return result;
3020 int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
3021 size_t ssid_len, const u8 *ies, size_t ies_len,
3022 wilc_connect_result connect_result, void *user_arg,
3023 u8 security, enum AUTHTYPE auth_type,
3024 u8 channel, void *join_params)
3026 int result = 0;
3027 struct host_if_msg msg;
3028 struct host_if_drv *hif_drv = vif->hif_drv;
3030 if (!hif_drv || !connect_result) {
3031 netdev_err(vif->ndev, "Driver is null\n");
3032 return -EFAULT;
3035 if (!join_params) {
3036 netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
3037 return -EFAULT;
3040 memset(&msg, 0, sizeof(struct host_if_msg));
3042 msg.id = HOST_IF_MSG_CONNECT;
3044 msg.body.con_info.security = security;
3045 msg.body.con_info.auth_type = auth_type;
3046 msg.body.con_info.ch = channel;
3047 msg.body.con_info.result = connect_result;
3048 msg.body.con_info.arg = user_arg;
3049 msg.body.con_info.params = join_params;
3050 msg.vif = vif;
3052 if (bssid) {
3053 msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3054 if (!msg.body.con_info.bssid)
3055 return -ENOMEM;
3058 if (ssid) {
3059 msg.body.con_info.ssid_len = ssid_len;
3060 msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
3061 if (!msg.body.con_info.ssid)
3062 return -ENOMEM;
3065 if (ies) {
3066 msg.body.con_info.ies_len = ies_len;
3067 msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
3068 if (!msg.body.con_info.ies)
3069 return -ENOMEM;
3071 if (hif_drv->hif_state < HOST_IF_CONNECTING)
3072 hif_drv->hif_state = HOST_IF_CONNECTING;
3074 result = wilc_enqueue_cmd(&msg);
3075 if (result) {
3076 netdev_err(vif->ndev, "send message: Set join request\n");
3077 return -EFAULT;
3080 hif_drv->connect_timer_vif = vif;
3081 mod_timer(&hif_drv->connect_timer,
3082 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3084 return result;
3087 int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
3089 int result = 0;
3090 struct host_if_msg msg;
3091 struct host_if_drv *hif_drv = vif->hif_drv;
3093 if (!hif_drv) {
3094 netdev_err(vif->ndev, "Driver is null\n");
3095 return -EFAULT;
3098 memset(&msg, 0, sizeof(struct host_if_msg));
3100 msg.id = HOST_IF_MSG_DISCONNECT;
3101 msg.vif = vif;
3103 result = wilc_enqueue_cmd(&msg);
3104 if (result)
3105 netdev_err(vif->ndev, "Failed to send message: disconnect\n");
3106 else
3107 wait_for_completion(&hif_drv->comp_test_disconn_block);
3109 return result;
3112 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
3113 u8 *assoc_resp_info,
3114 u32 max_assoc_resp_info_len,
3115 u32 *rcvd_assoc_resp_info_len)
3117 s32 result = 0;
3118 struct wid wid;
3120 wid.id = (u16)WID_ASSOC_RES_INFO;
3121 wid.type = WID_STR;
3122 wid.val = assoc_resp_info;
3123 wid.size = max_assoc_resp_info_len;
3125 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
3126 wilc_get_vif_idx(vif));
3127 if (result) {
3128 *rcvd_assoc_resp_info_len = 0;
3129 netdev_err(vif->ndev, "Failed to send association response\n");
3130 return -EINVAL;
3133 *rcvd_assoc_resp_info_len = wid.size;
3134 return result;
3137 int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
3139 int result;
3140 struct host_if_msg msg;
3142 memset(&msg, 0, sizeof(struct host_if_msg));
3143 msg.id = HOST_IF_MSG_SET_CHANNEL;
3144 msg.body.channel_info.set_ch = channel;
3145 msg.vif = vif;
3147 result = wilc_enqueue_cmd(&msg);
3148 if (result) {
3149 netdev_err(vif->ndev, "wilc mq send fail\n");
3150 return -EINVAL;
3153 return 0;
3156 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
3157 u8 ifc_id)
3159 int result = 0;
3160 struct host_if_msg msg;
3162 memset(&msg, 0, sizeof(struct host_if_msg));
3163 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3164 msg.body.drv.handler = index;
3165 msg.body.drv.mode = mode;
3166 msg.body.drv.name = ifc_id;
3167 msg.vif = vif;
3169 result = wilc_enqueue_cmd(&msg);
3170 if (result) {
3171 netdev_err(vif->ndev, "wilc mq send fail\n");
3172 result = -EINVAL;
3175 return result;
3178 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
3180 int result = 0;
3181 struct host_if_msg msg;
3183 memset(&msg, 0, sizeof(struct host_if_msg));
3184 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3185 msg.body.mode.mode = mode;
3186 msg.vif = vif;
3188 result = wilc_enqueue_cmd(&msg);
3189 if (result) {
3190 netdev_err(vif->ndev, "wilc mq send fail\n");
3191 result = -EINVAL;
3194 return result;
3197 s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3198 u32 *out_val)
3200 s32 result = 0;
3201 struct host_if_msg msg;
3202 struct host_if_drv *hif_drv = vif->hif_drv;
3204 if (!hif_drv) {
3205 netdev_err(vif->ndev, "driver is null\n");
3206 return -EFAULT;
3209 memset(&msg, 0, sizeof(struct host_if_msg));
3210 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3212 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3213 msg.vif = vif;
3215 result = wilc_enqueue_cmd(&msg);
3216 if (result)
3217 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3218 else
3219 wait_for_completion(&hif_drv->comp_inactive_time);
3221 *out_val = inactive_time;
3223 return result;
3226 int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
3228 int result = 0;
3229 struct host_if_msg msg;
3230 struct host_if_drv *hif_drv = vif->hif_drv;
3232 memset(&msg, 0, sizeof(struct host_if_msg));
3233 msg.id = HOST_IF_MSG_GET_RSSI;
3234 msg.vif = vif;
3236 result = wilc_enqueue_cmd(&msg);
3237 if (result) {
3238 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3239 return -EFAULT;
3242 wait_for_completion(&hif_drv->comp_get_rssi);
3244 if (!rssi_level) {
3245 netdev_err(vif->ndev, "RSS pointer value is null\n");
3246 return -EFAULT;
3249 *rssi_level = rssi;
3251 return result;
3254 int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
3256 int result = 0;
3257 struct host_if_msg msg;
3259 memset(&msg, 0, sizeof(struct host_if_msg));
3260 msg.id = HOST_IF_MSG_GET_STATISTICS;
3261 msg.body.data = (char *)stats;
3262 msg.vif = vif;
3264 result = wilc_enqueue_cmd(&msg);
3265 if (result) {
3266 netdev_err(vif->ndev, "Failed to send get host channel\n");
3267 return -EFAULT;
3270 if (stats != &vif->wilc->dummy_statistics)
3271 wait_for_completion(&hif_wait_response);
3272 return result;
3275 int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
3276 u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
3277 size_t ies_len, wilc_scan_result scan_result, void *user_arg,
3278 struct hidden_network *hidden_network)
3280 int result = 0;
3281 struct host_if_msg msg;
3282 struct scan_attr *scan_info = &msg.body.scan_info;
3283 struct host_if_drv *hif_drv = vif->hif_drv;
3285 if (!hif_drv || !scan_result) {
3286 netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
3287 return -EFAULT;
3290 memset(&msg, 0, sizeof(struct host_if_msg));
3292 msg.id = HOST_IF_MSG_SCAN;
3294 if (hidden_network) {
3295 scan_info->hidden_network.net_info = hidden_network->net_info;
3296 scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
3299 msg.vif = vif;
3300 scan_info->src = scan_source;
3301 scan_info->type = scan_type;
3302 scan_info->result = scan_result;
3303 scan_info->arg = user_arg;
3305 scan_info->ch_list_len = ch_list_len;
3306 scan_info->ch_freq_list = kmemdup(ch_freq_list,
3307 ch_list_len,
3308 GFP_KERNEL);
3309 if (!scan_info->ch_freq_list)
3310 return -ENOMEM;
3312 scan_info->ies_len = ies_len;
3313 scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3314 if (!scan_info->ies)
3315 return -ENOMEM;
3317 result = wilc_enqueue_cmd(&msg);
3318 if (result) {
3319 netdev_err(vif->ndev, "Error in sending message queue\n");
3320 return -EINVAL;
3323 hif_drv->scan_timer_vif = vif;
3324 mod_timer(&hif_drv->scan_timer,
3325 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3327 return result;
3330 int wilc_hif_set_cfg(struct wilc_vif *vif,
3331 struct cfg_param_attr *cfg_param)
3333 struct host_if_msg msg;
3334 struct host_if_drv *hif_drv = vif->hif_drv;
3336 if (!hif_drv) {
3337 netdev_err(vif->ndev, "hif_drv NULL\n");
3338 return -EFAULT;
3341 memset(&msg, 0, sizeof(struct host_if_msg));
3342 msg.id = HOST_IF_MSG_CFG_PARAMS;
3343 msg.body.cfg_info = *cfg_param;
3344 msg.vif = vif;
3346 return wilc_enqueue_cmd(&msg);
3349 static void get_periodic_rssi(struct timer_list *unused)
3351 struct wilc_vif *vif = periodic_rssi_vif;
3353 if (!vif->hif_drv) {
3354 netdev_err(vif->ndev, "Driver handler is NULL\n");
3355 return;
3358 if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3359 wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
3361 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3364 int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
3366 int result = 0;
3367 struct host_if_drv *hif_drv;
3368 struct wilc_vif *vif;
3369 struct wilc *wilc;
3370 int i;
3372 vif = netdev_priv(dev);
3373 wilc = vif->wilc;
3375 scan_while_connected = false;
3377 init_completion(&hif_wait_response);
3379 hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
3380 if (!hif_drv) {
3381 result = -ENOMEM;
3382 goto _fail_;
3384 *hif_drv_handler = hif_drv;
3385 for (i = 0; i < wilc->vif_num; i++)
3386 if (dev == wilc->vif[i]->ndev) {
3387 wilc->vif[i]->hif_drv = hif_drv;
3388 hif_drv->driver_handler_id = i + 1;
3389 break;
3392 wilc_optaining_ip = false;
3394 if (clients_count == 0) {
3395 init_completion(&hif_thread_comp);
3396 init_completion(&hif_driver_comp);
3397 mutex_init(&hif_deinit_lock);
3400 init_completion(&hif_drv->comp_test_key_block);
3401 init_completion(&hif_drv->comp_test_disconn_block);
3402 init_completion(&hif_drv->comp_get_rssi);
3403 init_completion(&hif_drv->comp_inactive_time);
3405 if (clients_count == 0) {
3406 hif_workqueue = create_singlethread_workqueue("WILC_wq");
3407 if (!hif_workqueue) {
3408 netdev_err(vif->ndev, "Failed to create workqueue\n");
3409 result = -ENOMEM;
3410 goto _fail_;
3413 periodic_rssi_vif = vif;
3414 timer_setup(&periodic_rssi, get_periodic_rssi, 0);
3415 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3418 timer_setup(&hif_drv->scan_timer, timer_scan_cb, 0);
3419 timer_setup(&hif_drv->connect_timer, timer_connect_cb, 0);
3420 timer_setup(&hif_drv->remain_on_ch_timer, listen_timer_cb, 0);
3422 mutex_init(&hif_drv->cfg_values_lock);
3423 mutex_lock(&hif_drv->cfg_values_lock);
3425 hif_drv->hif_state = HOST_IF_IDLE;
3426 hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
3427 hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
3428 hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
3429 hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
3430 hif_drv->cfg_values.curr_tx_rate = AUTORATE;
3432 hif_drv->p2p_timeout = 0;
3434 mutex_unlock(&hif_drv->cfg_values_lock);
3436 clients_count++;
3438 _fail_:
3439 return result;
3442 int wilc_deinit(struct wilc_vif *vif)
3444 int result = 0;
3445 struct host_if_msg msg;
3446 struct host_if_drv *hif_drv = vif->hif_drv;
3448 if (!hif_drv) {
3449 netdev_err(vif->ndev, "hif_drv = NULL\n");
3450 return -EFAULT;
3453 mutex_lock(&hif_deinit_lock);
3455 terminated_handle = hif_drv;
3457 del_timer_sync(&hif_drv->scan_timer);
3458 del_timer_sync(&hif_drv->connect_timer);
3459 del_timer_sync(&periodic_rssi);
3460 del_timer_sync(&hif_drv->remain_on_ch_timer);
3462 wilc_set_wfi_drv_handler(vif, 0, 0, 0);
3463 wait_for_completion(&hif_driver_comp);
3465 if (hif_drv->usr_scan_req.scan_result) {
3466 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
3467 hif_drv->usr_scan_req.arg,
3468 NULL);
3469 hif_drv->usr_scan_req.scan_result = NULL;
3472 hif_drv->hif_state = HOST_IF_IDLE;
3474 scan_while_connected = false;
3476 memset(&msg, 0, sizeof(struct host_if_msg));
3478 if (clients_count == 1) {
3479 msg.id = HOST_IF_MSG_EXIT;
3480 msg.vif = vif;
3482 result = wilc_enqueue_cmd(&msg);
3483 if (result != 0)
3484 netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
3485 else
3486 wait_for_completion(&hif_thread_comp);
3488 destroy_workqueue(hif_workqueue);
3491 kfree(hif_drv);
3493 clients_count--;
3494 terminated_handle = NULL;
3495 mutex_unlock(&hif_deinit_lock);
3496 return result;
3499 void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3501 s32 result = 0;
3502 struct host_if_msg msg;
3503 int id;
3504 struct host_if_drv *hif_drv = NULL;
3505 struct wilc_vif *vif;
3507 id = buffer[length - 4];
3508 id |= (buffer[length - 3] << 8);
3509 id |= (buffer[length - 2] << 16);
3510 id |= (buffer[length - 1] << 24);
3511 vif = wilc_get_vif_from_idx(wilc, id);
3512 if (!vif)
3513 return;
3514 hif_drv = vif->hif_drv;
3516 if (!hif_drv || hif_drv == terminated_handle) {
3517 netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
3518 return;
3521 memset(&msg, 0, sizeof(struct host_if_msg));
3523 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
3524 msg.vif = vif;
3526 msg.body.net_info.len = length;
3527 msg.body.net_info.buffer = kmalloc(length, GFP_KERNEL);
3528 memcpy(msg.body.net_info.buffer, buffer, length);
3530 result = wilc_enqueue_cmd(&msg);
3531 if (result)
3532 netdev_err(vif->ndev, "message parameters (%d)\n", result);
3535 void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3537 s32 result = 0;
3538 struct host_if_msg msg;
3539 int id;
3540 struct host_if_drv *hif_drv = NULL;
3541 struct wilc_vif *vif;
3543 mutex_lock(&hif_deinit_lock);
3545 id = buffer[length - 4];
3546 id |= (buffer[length - 3] << 8);
3547 id |= (buffer[length - 2] << 16);
3548 id |= (buffer[length - 1] << 24);
3549 vif = wilc_get_vif_from_idx(wilc, id);
3550 if (!vif) {
3551 mutex_unlock(&hif_deinit_lock);
3552 return;
3555 hif_drv = vif->hif_drv;
3557 if (!hif_drv || hif_drv == terminated_handle) {
3558 mutex_unlock(&hif_deinit_lock);
3559 return;
3562 if (!hif_drv->usr_conn_req.conn_result) {
3563 netdev_err(vif->ndev, "there is no current Connect Request\n");
3564 mutex_unlock(&hif_deinit_lock);
3565 return;
3568 memset(&msg, 0, sizeof(struct host_if_msg));
3570 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
3571 msg.vif = vif;
3573 msg.body.async_info.len = length;
3574 msg.body.async_info.buffer = kmalloc(length, GFP_KERNEL);
3575 memcpy(msg.body.async_info.buffer, buffer, length);
3577 result = wilc_enqueue_cmd(&msg);
3578 if (result)
3579 netdev_err(vif->ndev, "synchronous info (%d)\n", result);
3581 mutex_unlock(&hif_deinit_lock);
3584 void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
3586 s32 result = 0;
3587 struct host_if_msg msg;
3588 int id;
3589 struct host_if_drv *hif_drv = NULL;
3590 struct wilc_vif *vif;
3592 id = buffer[length - 4];
3593 id |= buffer[length - 3] << 8;
3594 id |= buffer[length - 2] << 16;
3595 id |= buffer[length - 1] << 24;
3596 vif = wilc_get_vif_from_idx(wilc, id);
3597 if (!vif)
3598 return;
3599 hif_drv = vif->hif_drv;
3601 if (!hif_drv || hif_drv == terminated_handle)
3602 return;
3604 if (hif_drv->usr_scan_req.scan_result) {
3605 memset(&msg, 0, sizeof(struct host_if_msg));
3607 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
3608 msg.vif = vif;
3610 result = wilc_enqueue_cmd(&msg);
3611 if (result)
3612 netdev_err(vif->ndev, "complete param (%d)\n", result);
3616 int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
3617 u32 duration, u16 chan,
3618 wilc_remain_on_chan_expired expired,
3619 wilc_remain_on_chan_ready ready,
3620 void *user_arg)
3622 int result = 0;
3623 struct host_if_msg msg;
3625 memset(&msg, 0, sizeof(struct host_if_msg));
3627 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
3628 msg.body.remain_on_ch.ch = chan;
3629 msg.body.remain_on_ch.expired = expired;
3630 msg.body.remain_on_ch.ready = ready;
3631 msg.body.remain_on_ch.arg = user_arg;
3632 msg.body.remain_on_ch.duration = duration;
3633 msg.body.remain_on_ch.id = session_id;
3634 msg.vif = vif;
3636 result = wilc_enqueue_cmd(&msg);
3637 if (result)
3638 netdev_err(vif->ndev, "wilc mq send fail\n");
3640 return result;
3643 int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
3645 int result = 0;
3646 struct host_if_msg msg;
3647 struct host_if_drv *hif_drv = vif->hif_drv;
3649 if (!hif_drv) {
3650 netdev_err(vif->ndev, "driver is null\n");
3651 return -EFAULT;
3654 del_timer(&hif_drv->remain_on_ch_timer);
3656 memset(&msg, 0, sizeof(struct host_if_msg));
3657 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3658 msg.vif = vif;
3659 msg.body.remain_on_ch.id = session_id;
3661 result = wilc_enqueue_cmd(&msg);
3662 if (result)
3663 netdev_err(vif->ndev, "wilc mq send fail\n");
3665 return result;
3668 int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
3670 int result = 0;
3671 struct host_if_msg msg;
3673 memset(&msg, 0, sizeof(struct host_if_msg));
3675 msg.id = HOST_IF_MSG_REGISTER_FRAME;
3676 switch (frame_type) {
3677 case ACTION:
3678 msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
3679 break;
3681 case PROBE_REQ:
3682 msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
3683 break;
3685 default:
3686 break;
3688 msg.body.reg_frame.frame_type = frame_type;
3689 msg.body.reg_frame.reg = reg;
3690 msg.vif = vif;
3692 result = wilc_enqueue_cmd(&msg);
3693 if (result)
3694 netdev_err(vif->ndev, "wilc mq send fail\n");
3696 return result;
3699 int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
3700 u32 head_len, u8 *head, u32 tail_len, u8 *tail)
3702 int result = 0;
3703 struct host_if_msg msg;
3704 struct beacon_attr *beacon_info = &msg.body.beacon_info;
3706 memset(&msg, 0, sizeof(struct host_if_msg));
3708 msg.id = HOST_IF_MSG_ADD_BEACON;
3709 msg.vif = vif;
3710 beacon_info->interval = interval;
3711 beacon_info->dtim_period = dtim_period;
3712 beacon_info->head_len = head_len;
3713 beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
3714 if (!beacon_info->head) {
3715 result = -ENOMEM;
3716 goto error;
3718 beacon_info->tail_len = tail_len;
3720 if (tail_len > 0) {
3721 beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3722 if (!beacon_info->tail) {
3723 result = -ENOMEM;
3724 goto error;
3726 } else {
3727 beacon_info->tail = NULL;
3730 result = wilc_enqueue_cmd(&msg);
3731 if (result)
3732 netdev_err(vif->ndev, "wilc mq send fail\n");
3734 error:
3735 if (result) {
3736 kfree(beacon_info->head);
3738 kfree(beacon_info->tail);
3741 return result;
3744 int wilc_del_beacon(struct wilc_vif *vif)
3746 int result = 0;
3747 struct host_if_msg msg;
3749 msg.id = HOST_IF_MSG_DEL_BEACON;
3750 msg.vif = vif;
3752 result = wilc_enqueue_cmd(&msg);
3753 if (result)
3754 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3756 return result;
3759 int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
3761 int result = 0;
3762 struct host_if_msg msg;
3763 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3765 memset(&msg, 0, sizeof(struct host_if_msg));
3767 msg.id = HOST_IF_MSG_ADD_STATION;
3768 msg.vif = vif;
3770 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3771 if (add_sta_info->rates_len > 0) {
3772 add_sta_info->rates = kmemdup(sta_param->rates,
3773 add_sta_info->rates_len,
3774 GFP_KERNEL);
3775 if (!add_sta_info->rates)
3776 return -ENOMEM;
3779 result = wilc_enqueue_cmd(&msg);
3780 if (result)
3781 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3782 return result;
3785 int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
3787 int result = 0;
3788 struct host_if_msg msg;
3789 struct del_sta *del_sta_info = &msg.body.del_sta_info;
3791 memset(&msg, 0, sizeof(struct host_if_msg));
3793 msg.id = HOST_IF_MSG_DEL_STATION;
3794 msg.vif = vif;
3796 if (!mac_addr)
3797 eth_broadcast_addr(del_sta_info->mac_addr);
3798 else
3799 memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
3801 result = wilc_enqueue_cmd(&msg);
3802 if (result)
3803 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3804 return result;
3807 int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
3809 int result = 0;
3810 struct host_if_msg msg;
3811 struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
3812 u8 zero_addr[ETH_ALEN] = {0};
3813 int i;
3814 u8 assoc_sta = 0;
3816 memset(&msg, 0, sizeof(struct host_if_msg));
3818 msg.id = HOST_IF_MSG_DEL_ALL_STA;
3819 msg.vif = vif;
3821 for (i = 0; i < MAX_NUM_STA; i++) {
3822 if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
3823 memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i],
3824 ETH_ALEN);
3825 assoc_sta++;
3828 if (!assoc_sta)
3829 return result;
3831 del_all_sta_info->assoc_sta = assoc_sta;
3832 result = wilc_enqueue_cmd(&msg);
3834 if (result)
3835 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3836 else
3837 wait_for_completion(&hif_wait_response);
3839 return result;
3842 int wilc_edit_station(struct wilc_vif *vif,
3843 struct add_sta_param *sta_param)
3845 int result = 0;
3846 struct host_if_msg msg;
3847 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3849 memset(&msg, 0, sizeof(struct host_if_msg));
3851 msg.id = HOST_IF_MSG_EDIT_STATION;
3852 msg.vif = vif;
3854 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3855 if (add_sta_info->rates_len > 0) {
3856 add_sta_info->rates = kmemdup(sta_param->rates,
3857 add_sta_info->rates_len,
3858 GFP_KERNEL);
3859 if (!add_sta_info->rates)
3860 return -ENOMEM;
3863 result = wilc_enqueue_cmd(&msg);
3864 if (result)
3865 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3867 return result;
3870 int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
3872 int result = 0;
3873 struct host_if_msg msg;
3874 struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
3876 if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
3877 return 0;
3879 memset(&msg, 0, sizeof(struct host_if_msg));
3881 msg.id = HOST_IF_MSG_POWER_MGMT;
3882 msg.vif = vif;
3884 pwr_mgmt_info->enabled = enabled;
3885 pwr_mgmt_info->timeout = timeout;
3887 result = wilc_enqueue_cmd(&msg);
3888 if (result)
3889 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3890 return result;
3893 int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
3894 u32 count)
3896 int result = 0;
3897 struct host_if_msg msg;
3898 struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
3900 memset(&msg, 0, sizeof(struct host_if_msg));
3902 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
3903 msg.vif = vif;
3905 multicast_filter_param->enabled = enabled;
3906 multicast_filter_param->cnt = count;
3908 result = wilc_enqueue_cmd(&msg);
3909 if (result)
3910 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3911 return result;
3914 static void *host_int_parse_join_bss_param(struct network_info *info)
3916 struct join_bss_param *param = NULL;
3917 u8 *ies;
3918 u16 ies_len;
3919 u16 index = 0;
3920 u8 rates_no = 0;
3921 u8 ext_rates_no;
3922 u16 offset;
3923 u8 pcipher_cnt;
3924 u8 auth_cnt;
3925 u8 pcipher_total_cnt = 0;
3926 u8 auth_total_cnt = 0;
3927 u8 i, j;
3929 ies = info->ies;
3930 ies_len = info->ies_len;
3932 param = kzalloc(sizeof(*param), GFP_KERNEL);
3933 if (!param)
3934 return NULL;
3936 param->dtim_period = info->dtim_period;
3937 param->beacon_period = info->beacon_period;
3938 param->cap_info = info->cap_info;
3939 memcpy(param->bssid, info->bssid, 6);
3940 memcpy((u8 *)param->ssid, info->ssid, info->ssid_len + 1);
3941 param->ssid_len = info->ssid_len;
3942 memset(param->rsn_pcip_policy, 0xFF, 3);
3943 memset(param->rsn_auth_policy, 0xFF, 3);
3945 while (index < ies_len) {
3946 if (ies[index] == SUPP_RATES_IE) {
3947 rates_no = ies[index + 1];
3948 param->supp_rates[0] = rates_no;
3949 index += 2;
3951 for (i = 0; i < rates_no; i++)
3952 param->supp_rates[i + 1] = ies[index + i];
3954 index += rates_no;
3955 } else if (ies[index] == EXT_SUPP_RATES_IE) {
3956 ext_rates_no = ies[index + 1];
3957 if (ext_rates_no > (MAX_RATES_SUPPORTED - rates_no))
3958 param->supp_rates[0] = MAX_RATES_SUPPORTED;
3959 else
3960 param->supp_rates[0] += ext_rates_no;
3961 index += 2;
3962 for (i = 0; i < (param->supp_rates[0] - rates_no); i++)
3963 param->supp_rates[rates_no + i + 1] = ies[index + i];
3965 index += ext_rates_no;
3966 } else if (ies[index] == HT_CAPABILITY_IE) {
3967 param->ht_capable = true;
3968 index += ies[index + 1] + 2;
3969 } else if ((ies[index] == WMM_IE) &&
3970 (ies[index + 2] == 0x00) && (ies[index + 3] == 0x50) &&
3971 (ies[index + 4] == 0xF2) &&
3972 (ies[index + 5] == 0x02) &&
3973 ((ies[index + 6] == 0x00) || (ies[index + 6] == 0x01)) &&
3974 (ies[index + 7] == 0x01)) {
3975 param->wmm_cap = true;
3977 if (ies[index + 8] & BIT(7))
3978 param->uapsd_cap = true;
3979 index += ies[index + 1] + 2;
3980 } else if ((ies[index] == P2P_IE) &&
3981 (ies[index + 2] == 0x50) && (ies[index + 3] == 0x6f) &&
3982 (ies[index + 4] == 0x9a) &&
3983 (ies[index + 5] == 0x09) && (ies[index + 6] == 0x0c)) {
3984 u16 p2p_cnt;
3986 param->tsf = info->tsf_lo;
3987 param->noa_enabled = 1;
3988 param->idx = ies[index + 9];
3990 if (ies[index + 10] & BIT(7)) {
3991 param->opp_enabled = 1;
3992 param->ct_window = ies[index + 10];
3993 } else {
3994 param->opp_enabled = 0;
3997 param->cnt = ies[index + 11];
3998 p2p_cnt = index + 12;
4000 memcpy(param->duration, ies + p2p_cnt, 4);
4001 p2p_cnt += 4;
4003 memcpy(param->interval, ies + p2p_cnt, 4);
4004 p2p_cnt += 4;
4006 memcpy(param->start_time, ies + p2p_cnt, 4);
4008 index += ies[index + 1] + 2;
4009 } else if ((ies[index] == RSN_IE) ||
4010 ((ies[index] == WPA_IE) && (ies[index + 2] == 0x00) &&
4011 (ies[index + 3] == 0x50) && (ies[index + 4] == 0xF2) &&
4012 (ies[index + 5] == 0x01))) {
4013 u16 rsn_idx = index;
4015 if (ies[rsn_idx] == RSN_IE) {
4016 param->mode_802_11i = 2;
4017 } else {
4018 if (param->mode_802_11i == 0)
4019 param->mode_802_11i = 1;
4020 rsn_idx += 4;
4023 rsn_idx += 7;
4024 param->rsn_grp_policy = ies[rsn_idx];
4025 rsn_idx++;
4026 offset = ies[rsn_idx] * 4;
4027 pcipher_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx];
4028 rsn_idx += 2;
4030 for (i = pcipher_total_cnt, j = 0; i < pcipher_cnt + pcipher_total_cnt && i < 3; i++, j++)
4031 param->rsn_pcip_policy[i] = ies[rsn_idx + ((j + 1) * 4) - 1];
4033 pcipher_total_cnt += pcipher_cnt;
4034 rsn_idx += offset;
4036 offset = ies[rsn_idx] * 4;
4038 auth_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx];
4039 rsn_idx += 2;
4041 for (i = auth_total_cnt, j = 0; i < auth_total_cnt + auth_cnt; i++, j++)
4042 param->rsn_auth_policy[i] = ies[rsn_idx + ((j + 1) * 4) - 1];
4044 auth_total_cnt += auth_cnt;
4045 rsn_idx += offset;
4047 if (ies[index] == RSN_IE) {
4048 param->rsn_cap[0] = ies[rsn_idx];
4049 param->rsn_cap[1] = ies[rsn_idx + 1];
4050 rsn_idx += 2;
4052 param->rsn_found = true;
4053 index += ies[index + 1] + 2;
4054 } else {
4055 index += ies[index + 1] + 2;
4059 return (void *)param;
4062 int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4064 int result = 0;
4065 struct host_if_msg msg;
4067 memset(&msg, 0, sizeof(struct host_if_msg));
4069 msg.id = HOST_IF_MSG_SET_IPADDRESS;
4071 msg.body.ip_info.ip_addr = ip_addr;
4072 msg.vif = vif;
4073 msg.body.ip_info.idx = idx;
4075 result = wilc_enqueue_cmd(&msg);
4076 if (result)
4077 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4079 return result;
4082 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4084 int result = 0;
4085 struct host_if_msg msg;
4087 memset(&msg, 0, sizeof(struct host_if_msg));
4089 msg.id = HOST_IF_MSG_GET_IPADDRESS;
4091 msg.body.ip_info.ip_addr = ip_addr;
4092 msg.vif = vif;
4093 msg.body.ip_info.idx = idx;
4095 result = wilc_enqueue_cmd(&msg);
4096 if (result)
4097 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4099 return result;
4102 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4104 int ret = 0;
4105 struct host_if_msg msg;
4107 memset(&msg, 0, sizeof(struct host_if_msg));
4109 msg.id = HOST_IF_MSG_SET_TX_POWER;
4110 msg.body.tx_power.tx_pwr = tx_power;
4111 msg.vif = vif;
4113 ret = wilc_enqueue_cmd(&msg);
4114 if (ret)
4115 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4117 return ret;
4120 int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4122 int ret = 0;
4123 struct host_if_msg msg;
4125 memset(&msg, 0, sizeof(struct host_if_msg));
4127 msg.id = HOST_IF_MSG_GET_TX_POWER;
4128 msg.vif = vif;
4130 ret = wilc_enqueue_cmd(&msg);
4131 if (ret)
4132 netdev_err(vif->ndev, "Failed to get TX PWR\n");
4134 wait_for_completion(&hif_wait_response);
4135 *tx_power = msg.body.tx_power.tx_pwr;
4137 return ret;