staging: wilc1000: fix line over 80 char issue in handle_scan_done()
[linux-2.6/btrfs-unstable.git] / drivers / staging / wilc1000 / host_interface.c
blob5082ede720f0f75292e72b51da90145c17fa773f
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 memcpy(hif_drv->usr_conn_req.bssid, conn_attr->bssid, 6);
950 hif_drv->usr_conn_req.ssid_len = conn_attr->ssid_len;
951 if (conn_attr->ssid) {
952 hif_drv->usr_conn_req.ssid = kmalloc(conn_attr->ssid_len + 1,
953 GFP_KERNEL);
954 memcpy(hif_drv->usr_conn_req.ssid,
955 conn_attr->ssid,
956 conn_attr->ssid_len);
957 hif_drv->usr_conn_req.ssid[conn_attr->ssid_len] = '\0';
960 hif_drv->usr_conn_req.ies_len = conn_attr->ies_len;
961 if (conn_attr->ies) {
962 hif_drv->usr_conn_req.ies = kmalloc(conn_attr->ies_len,
963 GFP_KERNEL);
964 memcpy(hif_drv->usr_conn_req.ies,
965 conn_attr->ies,
966 conn_attr->ies_len);
969 hif_drv->usr_conn_req.security = conn_attr->security;
970 hif_drv->usr_conn_req.auth_type = conn_attr->auth_type;
971 hif_drv->usr_conn_req.conn_result = conn_attr->result;
972 hif_drv->usr_conn_req.arg = conn_attr->arg;
974 wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
975 wid_list[wid_cnt].type = WID_INT;
976 wid_list[wid_cnt].size = sizeof(u32);
977 wid_list[wid_cnt].val = (s8 *)(&(dummyval));
978 wid_cnt++;
980 wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT;
981 wid_list[wid_cnt].type = WID_INT;
982 wid_list[wid_cnt].size = sizeof(u32);
983 wid_list[wid_cnt].val = (s8 *)(&(dummyval));
984 wid_cnt++;
986 wid_list[wid_cnt].id = WID_FAILED_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_INFO_ELEMENT_ASSOCIATE;
993 wid_list[wid_cnt].type = WID_BIN_DATA;
994 wid_list[wid_cnt].val = hif_drv->usr_conn_req.ies;
995 wid_list[wid_cnt].size = hif_drv->usr_conn_req.ies_len;
996 wid_cnt++;
998 if (memcmp("DIRECT-", conn_attr->ssid, 7)) {
999 info_element_size = hif_drv->usr_conn_req.ies_len;
1000 info_element = kmalloc(info_element_size, GFP_KERNEL);
1001 memcpy(info_element, hif_drv->usr_conn_req.ies,
1002 info_element_size);
1004 wid_list[wid_cnt].id = (u16)WID_11I_MODE;
1005 wid_list[wid_cnt].type = WID_CHAR;
1006 wid_list[wid_cnt].size = sizeof(char);
1007 wid_list[wid_cnt].val = (s8 *)&hif_drv->usr_conn_req.security;
1008 wid_cnt++;
1010 if (memcmp("DIRECT-", conn_attr->ssid, 7))
1011 mode_11i = hif_drv->usr_conn_req.security;
1013 wid_list[wid_cnt].id = (u16)WID_AUTH_TYPE;
1014 wid_list[wid_cnt].type = WID_CHAR;
1015 wid_list[wid_cnt].size = sizeof(char);
1016 wid_list[wid_cnt].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
1017 wid_cnt++;
1019 if (memcmp("DIRECT-", conn_attr->ssid, 7))
1020 auth_type = (u8)hif_drv->usr_conn_req.auth_type;
1022 wid_list[wid_cnt].id = (u16)WID_JOIN_REQ_EXTENDED;
1023 wid_list[wid_cnt].type = WID_STR;
1024 wid_list[wid_cnt].size = 112;
1025 wid_list[wid_cnt].val = kmalloc(wid_list[wid_cnt].size, GFP_KERNEL);
1027 if (memcmp("DIRECT-", conn_attr->ssid, 7)) {
1028 join_req_size = wid_list[wid_cnt].size;
1029 join_req = kmalloc(join_req_size, GFP_KERNEL);
1031 if (!wid_list[wid_cnt].val) {
1032 result = -EFAULT;
1033 goto error;
1036 cur_byte = wid_list[wid_cnt].val;
1038 if (conn_attr->ssid) {
1039 memcpy(cur_byte, conn_attr->ssid, conn_attr->ssid_len);
1040 cur_byte[conn_attr->ssid_len] = '\0';
1042 cur_byte += MAX_SSID_LEN;
1043 *(cur_byte++) = INFRASTRUCTURE;
1045 if (conn_attr->ch >= 1 && conn_attr->ch <= 14) {
1046 *(cur_byte++) = conn_attr->ch;
1047 } else {
1048 netdev_err(vif->ndev, "Channel out of range\n");
1049 *(cur_byte++) = 0xFF;
1051 *(cur_byte++) = (bss_param->cap_info) & 0xFF;
1052 *(cur_byte++) = ((bss_param->cap_info) >> 8) & 0xFF;
1054 if (conn_attr->bssid)
1055 memcpy(cur_byte, conn_attr->bssid, 6);
1056 cur_byte += 6;
1058 if (conn_attr->bssid)
1059 memcpy(cur_byte, conn_attr->bssid, 6);
1060 cur_byte += 6;
1062 *(cur_byte++) = (bss_param->beacon_period) & 0xFF;
1063 *(cur_byte++) = ((bss_param->beacon_period) >> 8) & 0xFF;
1064 *(cur_byte++) = bss_param->dtim_period;
1066 memcpy(cur_byte, bss_param->supp_rates, MAX_RATES_SUPPORTED + 1);
1067 cur_byte += (MAX_RATES_SUPPORTED + 1);
1069 *(cur_byte++) = bss_param->wmm_cap;
1070 *(cur_byte++) = bss_param->uapsd_cap;
1072 *(cur_byte++) = bss_param->ht_capable;
1073 hif_drv->usr_conn_req.ht_capable = bss_param->ht_capable;
1075 *(cur_byte++) = bss_param->rsn_found;
1076 *(cur_byte++) = bss_param->rsn_grp_policy;
1077 *(cur_byte++) = bss_param->mode_802_11i;
1079 memcpy(cur_byte, bss_param->rsn_pcip_policy,
1080 sizeof(bss_param->rsn_pcip_policy));
1081 cur_byte += sizeof(bss_param->rsn_pcip_policy);
1083 memcpy(cur_byte, bss_param->rsn_auth_policy,
1084 sizeof(bss_param->rsn_auth_policy));
1085 cur_byte += sizeof(bss_param->rsn_auth_policy);
1087 memcpy(cur_byte, bss_param->rsn_cap, sizeof(bss_param->rsn_cap));
1088 cur_byte += sizeof(bss_param->rsn_cap);
1090 *(cur_byte++) = REAL_JOIN_REQ;
1091 *(cur_byte++) = bss_param->noa_enabled;
1093 if (bss_param->noa_enabled) {
1094 *(cur_byte++) = (bss_param->tsf) & 0xFF;
1095 *(cur_byte++) = ((bss_param->tsf) >> 8) & 0xFF;
1096 *(cur_byte++) = ((bss_param->tsf) >> 16) & 0xFF;
1097 *(cur_byte++) = ((bss_param->tsf) >> 24) & 0xFF;
1099 *(cur_byte++) = bss_param->opp_enabled;
1100 *(cur_byte++) = bss_param->idx;
1102 if (bss_param->opp_enabled)
1103 *(cur_byte++) = bss_param->ct_window;
1105 *(cur_byte++) = bss_param->cnt;
1107 memcpy(cur_byte, bss_param->duration,
1108 sizeof(bss_param->duration));
1109 cur_byte += sizeof(bss_param->duration);
1111 memcpy(cur_byte, bss_param->interval,
1112 sizeof(bss_param->interval));
1113 cur_byte += sizeof(bss_param->interval);
1115 memcpy(cur_byte, bss_param->start_time,
1116 sizeof(bss_param->start_time));
1117 cur_byte += sizeof(bss_param->start_time);
1120 cur_byte = wid_list[wid_cnt].val;
1121 wid_cnt++;
1123 if (memcmp("DIRECT-", conn_attr->ssid, 7)) {
1124 memcpy(join_req, cur_byte, join_req_size);
1125 join_req_vif = vif;
1128 if (conn_attr->bssid)
1129 memcpy(wilc_connected_ssid,
1130 conn_attr->bssid, ETH_ALEN);
1132 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
1133 wid_cnt,
1134 wilc_get_vif_idx(vif));
1135 if (result) {
1136 netdev_err(vif->ndev, "failed to send config packet\n");
1137 result = -EFAULT;
1138 goto error;
1139 } else {
1140 hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
1143 error:
1144 if (result) {
1145 struct connect_info conn_info;
1147 del_timer(&hif_drv->connect_timer);
1149 memset(&conn_info, 0, sizeof(struct connect_info));
1151 if (conn_attr->result) {
1152 if (conn_attr->bssid)
1153 memcpy(conn_info.bssid, conn_attr->bssid, 6);
1155 if (conn_attr->ies) {
1156 conn_info.req_ies_len = conn_attr->ies_len;
1157 conn_info.req_ies = kmalloc(conn_attr->ies_len,
1158 GFP_KERNEL);
1159 memcpy(conn_info.req_ies,
1160 conn_attr->ies,
1161 conn_attr->ies_len);
1164 conn_attr->result(CONN_DISCONN_EVENT_CONN_RESP,
1165 &conn_info,
1166 MAC_DISCONNECTED,
1167 NULL,
1168 conn_attr->arg);
1169 hif_drv->hif_state = HOST_IF_IDLE;
1170 kfree(conn_info.req_ies);
1171 conn_info.req_ies = NULL;
1173 } else {
1174 netdev_err(vif->ndev, "Connect callback is NULL\n");
1178 kfree(conn_attr->bssid);
1179 conn_attr->bssid = NULL;
1181 kfree(conn_attr->ssid);
1182 conn_attr->ssid = NULL;
1184 kfree(conn_attr->ies);
1185 conn_attr->ies = NULL;
1187 kfree(cur_byte);
1188 return result;
1191 static s32 handle_connect_timeout(struct wilc_vif *vif)
1193 s32 result = 0;
1194 struct connect_info info;
1195 struct wid wid;
1196 u16 dummy_reason_code = 0;
1197 struct host_if_drv *hif_drv = vif->hif_drv;
1199 if (!hif_drv) {
1200 netdev_err(vif->ndev, "Driver handler is NULL\n");
1201 return result;
1204 hif_drv->hif_state = HOST_IF_IDLE;
1206 scan_while_connected = false;
1208 memset(&info, 0, sizeof(struct connect_info));
1210 if (hif_drv->usr_conn_req.conn_result) {
1211 if (hif_drv->usr_conn_req.bssid) {
1212 memcpy(info.bssid,
1213 hif_drv->usr_conn_req.bssid, 6);
1216 if (hif_drv->usr_conn_req.ies) {
1217 info.req_ies_len = hif_drv->usr_conn_req.ies_len;
1218 info.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1219 memcpy(info.req_ies,
1220 hif_drv->usr_conn_req.ies,
1221 hif_drv->usr_conn_req.ies_len);
1224 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1225 &info,
1226 MAC_DISCONNECTED,
1227 NULL,
1228 hif_drv->usr_conn_req.arg);
1230 kfree(info.req_ies);
1231 info.req_ies = NULL;
1232 } else {
1233 netdev_err(vif->ndev, "Connect callback is NULL\n");
1236 wid.id = (u16)WID_DISCONNECT;
1237 wid.type = WID_CHAR;
1238 wid.val = (s8 *)&dummy_reason_code;
1239 wid.size = sizeof(char);
1241 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1242 wilc_get_vif_idx(vif));
1243 if (result)
1244 netdev_err(vif->ndev, "Failed to send disconnect\n");
1246 hif_drv->usr_conn_req.ssid_len = 0;
1247 kfree(hif_drv->usr_conn_req.ssid);
1248 hif_drv->usr_conn_req.ssid = NULL;
1249 kfree(hif_drv->usr_conn_req.bssid);
1250 hif_drv->usr_conn_req.bssid = NULL;
1251 hif_drv->usr_conn_req.ies_len = 0;
1252 kfree(hif_drv->usr_conn_req.ies);
1253 hif_drv->usr_conn_req.ies = NULL;
1255 eth_zero_addr(wilc_connected_ssid);
1257 if (join_req && join_req_vif == vif) {
1258 kfree(join_req);
1259 join_req = NULL;
1262 if (info_element && join_req_vif == vif) {
1263 kfree(info_element);
1264 info_element = NULL;
1267 return result;
1270 static s32 handle_rcvd_ntwrk_info(struct wilc_vif *vif,
1271 struct rcvd_net_info *rcvd_info)
1273 u32 i;
1274 bool found;
1275 s32 result = 0;
1276 struct network_info *info = NULL;
1277 void *params = NULL;
1278 struct host_if_drv *hif_drv = vif->hif_drv;
1279 struct user_scan_req *scan_req = &hif_drv->usr_scan_req;
1281 found = true;
1283 if (!scan_req->scan_result)
1284 goto done;
1286 wilc_parse_network_info(rcvd_info->buffer, &info);
1287 if (!info || !scan_req->scan_result) {
1288 netdev_err(vif->ndev, "driver is null\n");
1289 result = -EINVAL;
1290 goto done;
1293 for (i = 0; i < scan_req->rcvd_ch_cnt; i++) {
1294 if (memcmp(scan_req->net_info[i].bssid, info->bssid, 6) == 0) {
1295 if (info->rssi <= scan_req->net_info[i].rssi) {
1296 goto done;
1297 } else {
1298 scan_req->net_info[i].rssi = info->rssi;
1299 found = false;
1300 break;
1305 if (found) {
1306 if (scan_req->rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
1307 scan_req->net_info[scan_req->rcvd_ch_cnt].rssi = info->rssi;
1309 memcpy(scan_req->net_info[scan_req->rcvd_ch_cnt].bssid,
1310 info->bssid, 6);
1312 scan_req->rcvd_ch_cnt++;
1314 info->new_network = true;
1315 params = host_int_parse_join_bss_param(info);
1317 scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info,
1318 scan_req->arg, params);
1320 } else {
1321 info->new_network = false;
1322 scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info,
1323 scan_req->arg, NULL);
1326 done:
1327 kfree(rcvd_info->buffer);
1328 rcvd_info->buffer = NULL;
1330 if (info) {
1331 kfree(info->ies);
1332 kfree(info);
1335 return result;
1338 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
1339 u8 *assoc_resp_info,
1340 u32 max_assoc_resp_info_len,
1341 u32 *rcvd_assoc_resp_info_len);
1343 static s32 handle_rcvd_gnrl_async_info(struct wilc_vif *vif,
1344 struct rcvd_async_info *rcvd_info)
1346 s32 result = 0;
1347 u8 msg_type = 0;
1348 u8 msg_id = 0;
1349 u16 msg_len = 0;
1350 u16 wid_id = (u16)WID_NIL;
1351 u8 wid_len = 0;
1352 u8 mac_status;
1353 u8 mac_status_reason_code;
1354 u8 mac_status_additional_info;
1355 struct connect_info conn_info;
1356 struct disconnect_info disconn_info;
1357 s32 err = 0;
1358 struct host_if_drv *hif_drv = vif->hif_drv;
1360 if (!hif_drv) {
1361 netdev_err(vif->ndev, "Driver handler is NULL\n");
1362 return -ENODEV;
1365 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP ||
1366 hif_drv->hif_state == HOST_IF_CONNECTED ||
1367 hif_drv->usr_scan_req.scan_result) {
1368 if (!rcvd_info->buffer ||
1369 !hif_drv->usr_conn_req.conn_result) {
1370 netdev_err(vif->ndev, "driver is null\n");
1371 return -EINVAL;
1374 msg_type = rcvd_info->buffer[0];
1376 if ('I' != msg_type) {
1377 netdev_err(vif->ndev, "Received Message incorrect.\n");
1378 return -EFAULT;
1381 msg_id = rcvd_info->buffer[1];
1382 msg_len = MAKE_WORD16(rcvd_info->buffer[2], rcvd_info->buffer[3]);
1383 wid_id = MAKE_WORD16(rcvd_info->buffer[4], rcvd_info->buffer[5]);
1384 wid_len = rcvd_info->buffer[6];
1385 mac_status = rcvd_info->buffer[7];
1386 mac_status_reason_code = rcvd_info->buffer[8];
1387 mac_status_additional_info = rcvd_info->buffer[9];
1388 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
1389 u32 rcvd_assoc_resp_info_len = 0;
1390 struct connect_resp_info *connect_resp_info = NULL;
1392 memset(&conn_info, 0, sizeof(struct connect_info));
1394 if (mac_status == MAC_CONNECTED) {
1395 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
1397 host_int_get_assoc_res_info(vif,
1398 rcv_assoc_resp,
1399 MAX_ASSOC_RESP_FRAME_SIZE,
1400 &rcvd_assoc_resp_info_len);
1402 if (rcvd_assoc_resp_info_len != 0) {
1403 err = wilc_parse_assoc_resp_info(rcv_assoc_resp, rcvd_assoc_resp_info_len,
1404 &connect_resp_info);
1405 if (err) {
1406 netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", err);
1407 } else {
1408 conn_info.status = connect_resp_info->status;
1410 if (conn_info.status == SUCCESSFUL_STATUSCODE && connect_resp_info->ies) {
1411 conn_info.resp_ies_len = connect_resp_info->ies_len;
1412 conn_info.resp_ies = kmalloc(connect_resp_info->ies_len, GFP_KERNEL);
1413 memcpy(conn_info.resp_ies, connect_resp_info->ies,
1414 connect_resp_info->ies_len);
1417 if (connect_resp_info) {
1418 kfree(connect_resp_info->ies);
1419 kfree(connect_resp_info);
1425 if (mac_status == MAC_CONNECTED &&
1426 conn_info.status != SUCCESSFUL_STATUSCODE) {
1427 netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1428 eth_zero_addr(wilc_connected_ssid);
1429 } else if (mac_status == MAC_DISCONNECTED) {
1430 netdev_err(vif->ndev, "Received MAC status is MAC_DISCONNECTED\n");
1431 eth_zero_addr(wilc_connected_ssid);
1434 if (hif_drv->usr_conn_req.bssid) {
1435 memcpy(conn_info.bssid, hif_drv->usr_conn_req.bssid, 6);
1437 if (mac_status == MAC_CONNECTED &&
1438 conn_info.status == SUCCESSFUL_STATUSCODE) {
1439 memcpy(hif_drv->assoc_bssid,
1440 hif_drv->usr_conn_req.bssid, ETH_ALEN);
1444 if (hif_drv->usr_conn_req.ies) {
1445 conn_info.req_ies_len = hif_drv->usr_conn_req.ies_len;
1446 conn_info.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1447 memcpy(conn_info.req_ies,
1448 hif_drv->usr_conn_req.ies,
1449 hif_drv->usr_conn_req.ies_len);
1452 del_timer(&hif_drv->connect_timer);
1453 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1454 &conn_info,
1455 mac_status,
1456 NULL,
1457 hif_drv->usr_conn_req.arg);
1459 if (mac_status == MAC_CONNECTED &&
1460 conn_info.status == SUCCESSFUL_STATUSCODE) {
1461 wilc_set_power_mgmt(vif, 0, 0);
1463 hif_drv->hif_state = HOST_IF_CONNECTED;
1465 wilc_optaining_ip = true;
1466 mod_timer(&wilc_during_ip_timer,
1467 jiffies + msecs_to_jiffies(10000));
1468 } else {
1469 hif_drv->hif_state = HOST_IF_IDLE;
1470 scan_while_connected = false;
1473 kfree(conn_info.resp_ies);
1474 conn_info.resp_ies = NULL;
1476 kfree(conn_info.req_ies);
1477 conn_info.req_ies = NULL;
1478 hif_drv->usr_conn_req.ssid_len = 0;
1479 kfree(hif_drv->usr_conn_req.ssid);
1480 hif_drv->usr_conn_req.ssid = NULL;
1481 kfree(hif_drv->usr_conn_req.bssid);
1482 hif_drv->usr_conn_req.bssid = NULL;
1483 hif_drv->usr_conn_req.ies_len = 0;
1484 kfree(hif_drv->usr_conn_req.ies);
1485 hif_drv->usr_conn_req.ies = NULL;
1486 } else if ((mac_status == MAC_DISCONNECTED) &&
1487 (hif_drv->hif_state == HOST_IF_CONNECTED)) {
1488 memset(&disconn_info, 0, sizeof(struct disconnect_info));
1490 if (hif_drv->usr_scan_req.scan_result) {
1491 del_timer(&hif_drv->scan_timer);
1492 handle_scan_done(vif, SCAN_EVENT_ABORTED);
1495 disconn_info.reason = 0;
1496 disconn_info.ie = NULL;
1497 disconn_info.ie_len = 0;
1499 if (hif_drv->usr_conn_req.conn_result) {
1500 wilc_optaining_ip = false;
1501 wilc_set_power_mgmt(vif, 0, 0);
1503 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1504 NULL,
1506 &disconn_info,
1507 hif_drv->usr_conn_req.arg);
1508 } else {
1509 netdev_err(vif->ndev, "Connect result NULL\n");
1512 eth_zero_addr(hif_drv->assoc_bssid);
1514 hif_drv->usr_conn_req.ssid_len = 0;
1515 kfree(hif_drv->usr_conn_req.ssid);
1516 hif_drv->usr_conn_req.ssid = NULL;
1517 kfree(hif_drv->usr_conn_req.bssid);
1518 hif_drv->usr_conn_req.bssid = NULL;
1519 hif_drv->usr_conn_req.ies_len = 0;
1520 kfree(hif_drv->usr_conn_req.ies);
1521 hif_drv->usr_conn_req.ies = NULL;
1523 if (join_req && join_req_vif == vif) {
1524 kfree(join_req);
1525 join_req = NULL;
1528 if (info_element && join_req_vif == vif) {
1529 kfree(info_element);
1530 info_element = NULL;
1533 hif_drv->hif_state = HOST_IF_IDLE;
1534 scan_while_connected = false;
1536 } else if ((mac_status == MAC_DISCONNECTED) &&
1537 (hif_drv->usr_scan_req.scan_result)) {
1538 del_timer(&hif_drv->scan_timer);
1539 if (hif_drv->usr_scan_req.scan_result)
1540 handle_scan_done(vif, SCAN_EVENT_ABORTED);
1544 kfree(rcvd_info->buffer);
1545 rcvd_info->buffer = NULL;
1547 return result;
1550 static int handle_key(struct wilc_vif *vif, struct key_attr *hif_key)
1552 s32 result = 0;
1553 struct wid wid;
1554 struct wid wid_list[5];
1555 u8 i;
1556 u8 *key_buf;
1557 s8 s8idxarray[1];
1558 s8 ret = 0;
1559 struct host_if_drv *hif_drv = vif->hif_drv;
1561 switch (hif_key->type) {
1562 case WEP:
1564 if (hif_key->action & ADDKEY_AP) {
1565 wid_list[0].id = (u16)WID_11I_MODE;
1566 wid_list[0].type = WID_CHAR;
1567 wid_list[0].size = sizeof(char);
1568 wid_list[0].val = (s8 *)&hif_key->attr.wep.mode;
1570 wid_list[1].id = WID_AUTH_TYPE;
1571 wid_list[1].type = WID_CHAR;
1572 wid_list[1].size = sizeof(char);
1573 wid_list[1].val = (s8 *)&hif_key->attr.wep.auth_type;
1575 key_buf = kmalloc(hif_key->attr.wep.key_len + 2,
1576 GFP_KERNEL);
1577 if (!key_buf)
1578 return -ENOMEM;
1580 key_buf[0] = hif_key->attr.wep.index;
1581 key_buf[1] = hif_key->attr.wep.key_len;
1583 memcpy(&key_buf[2], hif_key->attr.wep.key,
1584 hif_key->attr.wep.key_len);
1586 kfree(hif_key->attr.wep.key);
1588 wid_list[2].id = (u16)WID_WEP_KEY_VALUE;
1589 wid_list[2].type = WID_STR;
1590 wid_list[2].size = hif_key->attr.wep.key_len + 2;
1591 wid_list[2].val = (s8 *)key_buf;
1593 result = wilc_send_config_pkt(vif, SET_CFG,
1594 wid_list, 3,
1595 wilc_get_vif_idx(vif));
1596 kfree(key_buf);
1597 } else if (hif_key->action & ADDKEY) {
1598 key_buf = kmalloc(hif_key->attr.wep.key_len + 2, GFP_KERNEL);
1599 if (!key_buf)
1600 return -ENOMEM;
1601 key_buf[0] = hif_key->attr.wep.index;
1602 memcpy(key_buf + 1, &hif_key->attr.wep.key_len, 1);
1603 memcpy(key_buf + 2, hif_key->attr.wep.key,
1604 hif_key->attr.wep.key_len);
1605 kfree(hif_key->attr.wep.key);
1607 wid.id = (u16)WID_ADD_WEP_KEY;
1608 wid.type = WID_STR;
1609 wid.val = (s8 *)key_buf;
1610 wid.size = hif_key->attr.wep.key_len + 2;
1612 result = wilc_send_config_pkt(vif, SET_CFG,
1613 &wid, 1,
1614 wilc_get_vif_idx(vif));
1615 kfree(key_buf);
1616 } else if (hif_key->action & REMOVEKEY) {
1617 wid.id = (u16)WID_REMOVE_WEP_KEY;
1618 wid.type = WID_STR;
1620 s8idxarray[0] = (s8)hif_key->attr.wep.index;
1621 wid.val = s8idxarray;
1622 wid.size = 1;
1624 result = wilc_send_config_pkt(vif, SET_CFG,
1625 &wid, 1,
1626 wilc_get_vif_idx(vif));
1627 } else if (hif_key->action & DEFAULTKEY) {
1628 wid.id = (u16)WID_KEY_ID;
1629 wid.type = WID_CHAR;
1630 wid.val = (s8 *)&hif_key->attr.wep.index;
1631 wid.size = sizeof(char);
1633 result = wilc_send_config_pkt(vif, SET_CFG,
1634 &wid, 1,
1635 wilc_get_vif_idx(vif));
1637 complete(&hif_drv->comp_test_key_block);
1638 break;
1640 case WPA_RX_GTK:
1641 if (hif_key->action & ADDKEY_AP) {
1642 key_buf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1643 if (!key_buf) {
1644 ret = -ENOMEM;
1645 goto out_wpa_rx_gtk;
1648 if (hif_key->attr.wpa.seq)
1649 memcpy(key_buf + 6, hif_key->attr.wpa.seq, 8);
1651 memcpy(key_buf + 14, &hif_key->attr.wpa.index, 1);
1652 memcpy(key_buf + 15, &hif_key->attr.wpa.key_len, 1);
1653 memcpy(key_buf + 16, hif_key->attr.wpa.key,
1654 hif_key->attr.wpa.key_len);
1656 wid_list[0].id = (u16)WID_11I_MODE;
1657 wid_list[0].type = WID_CHAR;
1658 wid_list[0].size = sizeof(char);
1659 wid_list[0].val = (s8 *)&hif_key->attr.wpa.mode;
1661 wid_list[1].id = (u16)WID_ADD_RX_GTK;
1662 wid_list[1].type = WID_STR;
1663 wid_list[1].val = (s8 *)key_buf;
1664 wid_list[1].size = RX_MIC_KEY_MSG_LEN;
1666 result = wilc_send_config_pkt(vif, SET_CFG,
1667 wid_list, 2,
1668 wilc_get_vif_idx(vif));
1670 kfree(key_buf);
1671 complete(&hif_drv->comp_test_key_block);
1672 } else if (hif_key->action & ADDKEY) {
1673 key_buf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1674 if (!key_buf) {
1675 ret = -ENOMEM;
1676 goto out_wpa_rx_gtk;
1679 if (hif_drv->hif_state == HOST_IF_CONNECTED)
1680 memcpy(key_buf, hif_drv->assoc_bssid, ETH_ALEN);
1681 else
1682 netdev_err(vif->ndev, "Couldn't handle\n");
1684 memcpy(key_buf + 6, hif_key->attr.wpa.seq, 8);
1685 memcpy(key_buf + 14, &hif_key->attr.wpa.index, 1);
1686 memcpy(key_buf + 15, &hif_key->attr.wpa.key_len, 1);
1687 memcpy(key_buf + 16, hif_key->attr.wpa.key,
1688 hif_key->attr.wpa.key_len);
1690 wid.id = (u16)WID_ADD_RX_GTK;
1691 wid.type = WID_STR;
1692 wid.val = (s8 *)key_buf;
1693 wid.size = RX_MIC_KEY_MSG_LEN;
1695 result = wilc_send_config_pkt(vif, SET_CFG,
1696 &wid, 1,
1697 wilc_get_vif_idx(vif));
1699 kfree(key_buf);
1700 complete(&hif_drv->comp_test_key_block);
1702 out_wpa_rx_gtk:
1703 kfree(hif_key->attr.wpa.key);
1704 kfree(hif_key->attr.wpa.seq);
1705 if (ret)
1706 return ret;
1708 break;
1710 case WPA_PTK:
1711 if (hif_key->action & ADDKEY_AP) {
1712 key_buf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
1713 if (!key_buf) {
1714 ret = -ENOMEM;
1715 goto out_wpa_ptk;
1718 memcpy(key_buf, hif_key->attr.wpa.mac_addr, 6);
1719 memcpy(key_buf + 6, &hif_key->attr.wpa.index, 1);
1720 memcpy(key_buf + 7, &hif_key->attr.wpa.key_len, 1);
1721 memcpy(key_buf + 8, hif_key->attr.wpa.key,
1722 hif_key->attr.wpa.key_len);
1724 wid_list[0].id = (u16)WID_11I_MODE;
1725 wid_list[0].type = WID_CHAR;
1726 wid_list[0].size = sizeof(char);
1727 wid_list[0].val = (s8 *)&hif_key->attr.wpa.mode;
1729 wid_list[1].id = (u16)WID_ADD_PTK;
1730 wid_list[1].type = WID_STR;
1731 wid_list[1].val = (s8 *)key_buf;
1732 wid_list[1].size = PTK_KEY_MSG_LEN + 1;
1734 result = wilc_send_config_pkt(vif, SET_CFG,
1735 wid_list, 2,
1736 wilc_get_vif_idx(vif));
1737 kfree(key_buf);
1738 complete(&hif_drv->comp_test_key_block);
1739 } else if (hif_key->action & ADDKEY) {
1740 key_buf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
1741 if (!key_buf) {
1742 netdev_err(vif->ndev, "No buffer send PTK\n");
1743 ret = -ENOMEM;
1744 goto out_wpa_ptk;
1747 memcpy(key_buf, hif_key->attr.wpa.mac_addr, 6);
1748 memcpy(key_buf + 6, &hif_key->attr.wpa.key_len, 1);
1749 memcpy(key_buf + 7, hif_key->attr.wpa.key,
1750 hif_key->attr.wpa.key_len);
1752 wid.id = (u16)WID_ADD_PTK;
1753 wid.type = WID_STR;
1754 wid.val = (s8 *)key_buf;
1755 wid.size = PTK_KEY_MSG_LEN;
1757 result = wilc_send_config_pkt(vif, SET_CFG,
1758 &wid, 1,
1759 wilc_get_vif_idx(vif));
1760 kfree(key_buf);
1761 complete(&hif_drv->comp_test_key_block);
1764 out_wpa_ptk:
1765 kfree(hif_key->attr.wpa.key);
1766 if (ret)
1767 return ret;
1769 break;
1771 case PMKSA:
1772 key_buf = kmalloc((hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1773 if (!key_buf)
1774 return -ENOMEM;
1776 key_buf[0] = hif_key->attr.pmkid.numpmkid;
1778 for (i = 0; i < hif_key->attr.pmkid.numpmkid; i++) {
1779 memcpy(key_buf + ((PMKSA_KEY_LEN * i) + 1), hif_key->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1780 memcpy(key_buf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), hif_key->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
1783 wid.id = (u16)WID_PMKID_INFO;
1784 wid.type = WID_STR;
1785 wid.val = (s8 *)key_buf;
1786 wid.size = (hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1788 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1789 wilc_get_vif_idx(vif));
1791 kfree(key_buf);
1792 break;
1795 if (result)
1796 netdev_err(vif->ndev, "Failed to send key config packet\n");
1798 return result;
1801 static void handle_disconnect(struct wilc_vif *vif)
1803 struct wid wid;
1804 struct host_if_drv *hif_drv = vif->hif_drv;
1805 struct disconnect_info disconn_info;
1806 struct user_scan_req *scan_req;
1807 struct user_conn_req *conn_req;
1808 s32 result = 0;
1809 u16 dummy_reason_code = 0;
1811 wid.id = (u16)WID_DISCONNECT;
1812 wid.type = WID_CHAR;
1813 wid.val = (s8 *)&dummy_reason_code;
1814 wid.size = sizeof(char);
1816 wilc_optaining_ip = false;
1817 wilc_set_power_mgmt(vif, 0, 0);
1819 eth_zero_addr(wilc_connected_ssid);
1821 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1822 wilc_get_vif_idx(vif));
1824 if (result) {
1825 netdev_err(vif->ndev, "Failed to send dissconect\n");
1826 goto out;
1829 memset(&disconn_info, 0, sizeof(struct disconnect_info));
1831 disconn_info.reason = 0;
1832 disconn_info.ie = NULL;
1833 disconn_info.ie_len = 0;
1834 scan_req = &hif_drv->usr_scan_req;
1835 conn_req = &hif_drv->usr_conn_req;
1837 if (scan_req->scan_result) {
1838 del_timer(&hif_drv->scan_timer);
1839 scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg,
1840 NULL);
1841 scan_req->scan_result = NULL;
1844 if (conn_req->conn_result) {
1845 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
1846 del_timer(&hif_drv->connect_timer);
1848 conn_req->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
1849 0, &disconn_info, conn_req->arg);
1850 } else {
1851 netdev_err(vif->ndev, "conn_result = NULL\n");
1854 scan_while_connected = false;
1856 hif_drv->hif_state = HOST_IF_IDLE;
1858 eth_zero_addr(hif_drv->assoc_bssid);
1860 conn_req->ssid_len = 0;
1861 kfree(conn_req->ssid);
1862 conn_req->ssid = NULL;
1863 kfree(conn_req->bssid);
1864 conn_req->bssid = NULL;
1865 conn_req->ies_len = 0;
1866 kfree(conn_req->ies);
1867 conn_req->ies = NULL;
1869 if (join_req && join_req_vif == vif) {
1870 kfree(join_req);
1871 join_req = NULL;
1874 if (info_element && join_req_vif == vif) {
1875 kfree(info_element);
1876 info_element = NULL;
1879 out:
1881 complete(&hif_drv->comp_test_disconn_block);
1884 void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
1886 if (!vif->hif_drv)
1887 return;
1888 if (vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP ||
1889 vif->hif_drv->hif_state == HOST_IF_CONNECTING)
1890 wilc_disconnect(vif, 1);
1893 static void handle_get_rssi(struct wilc_vif *vif)
1895 s32 result = 0;
1896 struct wid wid;
1898 wid.id = (u16)WID_RSSI;
1899 wid.type = WID_CHAR;
1900 wid.val = &rssi;
1901 wid.size = sizeof(char);
1903 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1904 wilc_get_vif_idx(vif));
1905 if (result) {
1906 netdev_err(vif->ndev, "Failed to get RSSI value\n");
1907 result = -EFAULT;
1910 complete(&vif->hif_drv->comp_get_rssi);
1913 static s32 handle_get_statistics(struct wilc_vif *vif,
1914 struct rf_info *stats)
1916 struct wid wid_list[5];
1917 u32 wid_cnt = 0, result = 0;
1919 wid_list[wid_cnt].id = WID_LINKSPEED;
1920 wid_list[wid_cnt].type = WID_CHAR;
1921 wid_list[wid_cnt].size = sizeof(char);
1922 wid_list[wid_cnt].val = (s8 *)&stats->link_speed;
1923 wid_cnt++;
1925 wid_list[wid_cnt].id = WID_RSSI;
1926 wid_list[wid_cnt].type = WID_CHAR;
1927 wid_list[wid_cnt].size = sizeof(char);
1928 wid_list[wid_cnt].val = (s8 *)&stats->rssi;
1929 wid_cnt++;
1931 wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
1932 wid_list[wid_cnt].type = WID_INT;
1933 wid_list[wid_cnt].size = sizeof(u32);
1934 wid_list[wid_cnt].val = (s8 *)&stats->tx_cnt;
1935 wid_cnt++;
1937 wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT;
1938 wid_list[wid_cnt].type = WID_INT;
1939 wid_list[wid_cnt].size = sizeof(u32);
1940 wid_list[wid_cnt].val = (s8 *)&stats->rx_cnt;
1941 wid_cnt++;
1943 wid_list[wid_cnt].id = WID_FAILED_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_fail_cnt;
1947 wid_cnt++;
1949 result = wilc_send_config_pkt(vif, GET_CFG, wid_list,
1950 wid_cnt,
1951 wilc_get_vif_idx(vif));
1953 if (result)
1954 netdev_err(vif->ndev, "Failed to send scan parameters\n");
1956 if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
1957 stats->link_speed != DEFAULT_LINK_SPEED)
1958 wilc_enable_tcp_ack_filter(true);
1959 else if (stats->link_speed != DEFAULT_LINK_SPEED)
1960 wilc_enable_tcp_ack_filter(false);
1962 if (stats != &vif->wilc->dummy_statistics)
1963 complete(&hif_wait_response);
1964 return 0;
1967 static s32 handle_get_inactive_time(struct wilc_vif *vif,
1968 struct sta_inactive_t *hif_sta_inactive)
1970 s32 result = 0;
1971 u8 *stamac;
1972 struct wid wid;
1973 struct host_if_drv *hif_drv = vif->hif_drv;
1975 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
1976 wid.type = WID_STR;
1977 wid.size = ETH_ALEN;
1978 wid.val = kmalloc(wid.size, GFP_KERNEL);
1979 if (!wid.val)
1980 return -ENOMEM;
1982 stamac = wid.val;
1983 ether_addr_copy(stamac, hif_sta_inactive->mac);
1985 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1986 wilc_get_vif_idx(vif));
1988 if (result) {
1989 netdev_err(vif->ndev, "Failed to SET inactive time\n");
1990 return -EFAULT;
1993 wid.id = (u16)WID_GET_INACTIVE_TIME;
1994 wid.type = WID_INT;
1995 wid.val = (s8 *)&inactive_time;
1996 wid.size = sizeof(u32);
1998 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1999 wilc_get_vif_idx(vif));
2001 if (result) {
2002 netdev_err(vif->ndev, "Failed to get inactive time\n");
2003 return -EFAULT;
2006 complete(&hif_drv->comp_inactive_time);
2008 return result;
2011 static void handle_add_beacon(struct wilc_vif *vif, struct beacon_attr *param)
2013 s32 result = 0;
2014 struct wid wid;
2015 u8 *cur_byte;
2017 wid.id = (u16)WID_ADD_BEACON;
2018 wid.type = WID_BIN;
2019 wid.size = param->head_len + param->tail_len + 16;
2020 wid.val = kmalloc(wid.size, GFP_KERNEL);
2021 if (!wid.val)
2022 goto error;
2024 cur_byte = wid.val;
2025 *cur_byte++ = (param->interval & 0xFF);
2026 *cur_byte++ = ((param->interval >> 8) & 0xFF);
2027 *cur_byte++ = ((param->interval >> 16) & 0xFF);
2028 *cur_byte++ = ((param->interval >> 24) & 0xFF);
2030 *cur_byte++ = (param->dtim_period & 0xFF);
2031 *cur_byte++ = ((param->dtim_period >> 8) & 0xFF);
2032 *cur_byte++ = ((param->dtim_period >> 16) & 0xFF);
2033 *cur_byte++ = ((param->dtim_period >> 24) & 0xFF);
2035 *cur_byte++ = (param->head_len & 0xFF);
2036 *cur_byte++ = ((param->head_len >> 8) & 0xFF);
2037 *cur_byte++ = ((param->head_len >> 16) & 0xFF);
2038 *cur_byte++ = ((param->head_len >> 24) & 0xFF);
2040 memcpy(cur_byte, param->head, param->head_len);
2041 cur_byte += param->head_len;
2043 *cur_byte++ = (param->tail_len & 0xFF);
2044 *cur_byte++ = ((param->tail_len >> 8) & 0xFF);
2045 *cur_byte++ = ((param->tail_len >> 16) & 0xFF);
2046 *cur_byte++ = ((param->tail_len >> 24) & 0xFF);
2048 if (param->tail)
2049 memcpy(cur_byte, param->tail, param->tail_len);
2050 cur_byte += param->tail_len;
2052 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2053 wilc_get_vif_idx(vif));
2054 if (result)
2055 netdev_err(vif->ndev, "Failed to send add beacon\n");
2057 error:
2058 kfree(wid.val);
2059 kfree(param->head);
2060 kfree(param->tail);
2063 static void handle_del_beacon(struct wilc_vif *vif)
2065 s32 result = 0;
2066 struct wid wid;
2067 u8 *cur_byte;
2069 wid.id = (u16)WID_DEL_BEACON;
2070 wid.type = WID_CHAR;
2071 wid.size = sizeof(char);
2072 wid.val = &del_beacon;
2074 if (!wid.val)
2075 return;
2077 cur_byte = wid.val;
2079 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2080 wilc_get_vif_idx(vif));
2081 if (result)
2082 netdev_err(vif->ndev, "Failed to send delete beacon\n");
2085 static u32 wilc_hif_pack_sta_param(u8 *buff, struct add_sta_param *param)
2087 u8 *cur_byte;
2089 cur_byte = buff;
2091 memcpy(cur_byte, param->bssid, ETH_ALEN);
2092 cur_byte += ETH_ALEN;
2094 *cur_byte++ = param->aid & 0xFF;
2095 *cur_byte++ = (param->aid >> 8) & 0xFF;
2097 *cur_byte++ = param->rates_len;
2098 if (param->rates_len > 0)
2099 memcpy(cur_byte, param->rates, param->rates_len);
2100 cur_byte += param->rates_len;
2102 *cur_byte++ = param->ht_supported;
2103 memcpy(cur_byte, &param->ht_capa, sizeof(struct ieee80211_ht_cap));
2104 cur_byte += sizeof(struct ieee80211_ht_cap);
2106 *cur_byte++ = param->flags_mask & 0xFF;
2107 *cur_byte++ = (param->flags_mask >> 8) & 0xFF;
2109 *cur_byte++ = param->flags_set & 0xFF;
2110 *cur_byte++ = (param->flags_set >> 8) & 0xFF;
2112 return cur_byte - buff;
2115 static void handle_add_station(struct wilc_vif *vif,
2116 struct add_sta_param *param)
2118 s32 result = 0;
2119 struct wid wid;
2120 u8 *cur_byte;
2122 wid.id = (u16)WID_ADD_STA;
2123 wid.type = WID_BIN;
2124 wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
2126 wid.val = kmalloc(wid.size, GFP_KERNEL);
2127 if (!wid.val)
2128 goto error;
2130 cur_byte = wid.val;
2131 cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
2133 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2134 wilc_get_vif_idx(vif));
2135 if (result != 0)
2136 netdev_err(vif->ndev, "Failed to send add station\n");
2138 error:
2139 kfree(param->rates);
2140 kfree(wid.val);
2143 static void handle_del_all_sta(struct wilc_vif *vif,
2144 struct del_all_sta *param)
2146 s32 result = 0;
2147 struct wid wid;
2148 u8 *curr_byte;
2149 u8 i;
2150 u8 zero_buff[6] = {0};
2152 wid.id = (u16)WID_DEL_ALL_STA;
2153 wid.type = WID_STR;
2154 wid.size = (param->assoc_sta * ETH_ALEN) + 1;
2156 wid.val = kmalloc((param->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2157 if (!wid.val)
2158 goto error;
2160 curr_byte = wid.val;
2162 *(curr_byte++) = param->assoc_sta;
2164 for (i = 0; i < MAX_NUM_STA; i++) {
2165 if (memcmp(param->del_all_sta[i], zero_buff, ETH_ALEN))
2166 memcpy(curr_byte, param->del_all_sta[i], ETH_ALEN);
2167 else
2168 continue;
2170 curr_byte += ETH_ALEN;
2173 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2174 wilc_get_vif_idx(vif));
2175 if (result)
2176 netdev_err(vif->ndev, "Failed to send add station\n");
2178 error:
2179 kfree(wid.val);
2181 complete(&hif_wait_response);
2184 static void handle_del_station(struct wilc_vif *vif, struct del_sta *param)
2186 s32 result = 0;
2187 struct wid wid;
2188 u8 *cur_byte;
2190 wid.id = (u16)WID_REMOVE_STA;
2191 wid.type = WID_BIN;
2192 wid.size = ETH_ALEN;
2194 wid.val = kmalloc(wid.size, GFP_KERNEL);
2195 if (!wid.val)
2196 goto error;
2198 cur_byte = wid.val;
2200 ether_addr_copy(cur_byte, param->mac_addr);
2202 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2203 wilc_get_vif_idx(vif));
2204 if (result)
2205 netdev_err(vif->ndev, "Failed to send add station\n");
2207 error:
2208 kfree(wid.val);
2211 static void handle_edit_station(struct wilc_vif *vif,
2212 struct add_sta_param *param)
2214 s32 result = 0;
2215 struct wid wid;
2216 u8 *cur_byte;
2218 wid.id = (u16)WID_EDIT_STA;
2219 wid.type = WID_BIN;
2220 wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
2222 wid.val = kmalloc(wid.size, GFP_KERNEL);
2223 if (!wid.val)
2224 goto error;
2226 cur_byte = wid.val;
2227 cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
2229 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2230 wilc_get_vif_idx(vif));
2231 if (result)
2232 netdev_err(vif->ndev, "Failed to send edit station\n");
2234 error:
2235 kfree(param->rates);
2236 kfree(wid.val);
2239 static int handle_remain_on_chan(struct wilc_vif *vif,
2240 struct remain_ch *hif_remain_ch)
2242 s32 result = 0;
2243 u8 remain_on_chan_flag;
2244 struct wid wid;
2245 struct host_if_drv *hif_drv = vif->hif_drv;
2247 if (!hif_drv->remain_on_ch_pending) {
2248 hif_drv->remain_on_ch.arg = hif_remain_ch->arg;
2249 hif_drv->remain_on_ch.expired = hif_remain_ch->expired;
2250 hif_drv->remain_on_ch.ready = hif_remain_ch->ready;
2251 hif_drv->remain_on_ch.ch = hif_remain_ch->ch;
2252 hif_drv->remain_on_ch.id = hif_remain_ch->id;
2253 } else {
2254 hif_remain_ch->ch = hif_drv->remain_on_ch.ch;
2257 if (hif_drv->usr_scan_req.scan_result) {
2258 hif_drv->remain_on_ch_pending = 1;
2259 result = -EBUSY;
2260 goto error;
2262 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
2263 result = -EBUSY;
2264 goto error;
2267 if (wilc_optaining_ip || wilc_connecting) {
2268 result = -EBUSY;
2269 goto error;
2272 remain_on_chan_flag = true;
2273 wid.id = (u16)WID_REMAIN_ON_CHAN;
2274 wid.type = WID_STR;
2275 wid.size = 2;
2276 wid.val = kmalloc(wid.size, GFP_KERNEL);
2277 if (!wid.val) {
2278 result = -ENOMEM;
2279 goto error;
2282 wid.val[0] = remain_on_chan_flag;
2283 wid.val[1] = (s8)hif_remain_ch->ch;
2285 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2286 wilc_get_vif_idx(vif));
2287 if (result != 0)
2288 netdev_err(vif->ndev, "Failed to set remain on channel\n");
2290 error:
2292 P2P_LISTEN_STATE = 1;
2293 hif_drv->remain_on_ch_timer_vif = vif;
2294 mod_timer(&hif_drv->remain_on_ch_timer,
2295 jiffies +
2296 msecs_to_jiffies(hif_remain_ch->duration));
2298 if (hif_drv->remain_on_ch.ready)
2299 hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
2301 if (hif_drv->remain_on_ch_pending)
2302 hif_drv->remain_on_ch_pending = 0;
2305 return result;
2308 static int handle_register_frame(struct wilc_vif *vif,
2309 struct reg_frame *hif_reg_frame)
2311 s32 result = 0;
2312 struct wid wid;
2313 u8 *cur_byte;
2315 wid.id = (u16)WID_REGISTER_FRAME;
2316 wid.type = WID_STR;
2317 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2318 if (!wid.val)
2319 return -ENOMEM;
2321 cur_byte = wid.val;
2323 *cur_byte++ = hif_reg_frame->reg;
2324 *cur_byte++ = hif_reg_frame->reg_id;
2325 memcpy(cur_byte, &hif_reg_frame->frame_type, sizeof(u16));
2327 wid.size = sizeof(u16) + 2;
2329 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2330 wilc_get_vif_idx(vif));
2331 if (result) {
2332 netdev_err(vif->ndev, "Failed to frame register\n");
2333 result = -EINVAL;
2336 return result;
2339 static u32 handle_listen_state_expired(struct wilc_vif *vif,
2340 struct remain_ch *hif_remain_ch)
2342 u8 remain_on_chan_flag;
2343 struct wid wid;
2344 s32 result = 0;
2345 struct host_if_drv *hif_drv = vif->hif_drv;
2347 if (P2P_LISTEN_STATE) {
2348 remain_on_chan_flag = false;
2349 wid.id = (u16)WID_REMAIN_ON_CHAN;
2350 wid.type = WID_STR;
2351 wid.size = 2;
2352 wid.val = kmalloc(wid.size, GFP_KERNEL);
2354 if (!wid.val)
2355 return -ENOMEM;
2357 wid.val[0] = remain_on_chan_flag;
2358 wid.val[1] = FALSE_FRMWR_CHANNEL;
2360 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2361 wilc_get_vif_idx(vif));
2362 if (result != 0) {
2363 netdev_err(vif->ndev, "Failed to set remain channel\n");
2364 goto _done_;
2367 if (hif_drv->remain_on_ch.expired) {
2368 hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
2369 hif_remain_ch->id);
2371 P2P_LISTEN_STATE = 0;
2372 } else {
2373 netdev_dbg(vif->ndev, "Not in listen state\n");
2374 result = -EFAULT;
2377 _done_:
2378 return result;
2381 static void listen_timer_cb(struct timer_list *t)
2383 struct host_if_drv *hif_drv = from_timer(hif_drv, t,
2384 remain_on_ch_timer);
2385 struct wilc_vif *vif = hif_drv->remain_on_ch_timer_vif;
2386 s32 result = 0;
2387 struct host_if_msg msg;
2389 del_timer(&vif->hif_drv->remain_on_ch_timer);
2391 memset(&msg, 0, sizeof(struct host_if_msg));
2392 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2393 msg.vif = vif;
2394 msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
2396 result = wilc_enqueue_cmd(&msg);
2397 if (result)
2398 netdev_err(vif->ndev, "wilc_mq_send fail\n");
2401 static void handle_power_management(struct wilc_vif *vif,
2402 struct power_mgmt_param *pm_param)
2404 s32 result = 0;
2405 struct wid wid;
2406 s8 power_mode;
2408 wid.id = (u16)WID_POWER_MANAGEMENT;
2410 if (pm_param->enabled)
2411 power_mode = MIN_FAST_PS;
2412 else
2413 power_mode = NO_POWERSAVE;
2415 wid.val = &power_mode;
2416 wid.size = sizeof(char);
2418 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2419 wilc_get_vif_idx(vif));
2420 if (result)
2421 netdev_err(vif->ndev, "Failed to send power management\n");
2424 static void handle_set_mcast_filter(struct wilc_vif *vif,
2425 struct set_multicast *hif_set_mc)
2427 s32 result = 0;
2428 struct wid wid;
2429 u8 *cur_byte;
2431 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2432 wid.type = WID_BIN;
2433 wid.size = sizeof(struct set_multicast) + (hif_set_mc->cnt * ETH_ALEN);
2434 wid.val = kmalloc(wid.size, GFP_KERNEL);
2435 if (!wid.val)
2436 goto error;
2438 cur_byte = wid.val;
2439 *cur_byte++ = (hif_set_mc->enabled & 0xFF);
2440 *cur_byte++ = 0;
2441 *cur_byte++ = 0;
2442 *cur_byte++ = 0;
2444 *cur_byte++ = (hif_set_mc->cnt & 0xFF);
2445 *cur_byte++ = ((hif_set_mc->cnt >> 8) & 0xFF);
2446 *cur_byte++ = ((hif_set_mc->cnt >> 16) & 0xFF);
2447 *cur_byte++ = ((hif_set_mc->cnt >> 24) & 0xFF);
2449 if (hif_set_mc->cnt > 0)
2450 memcpy(cur_byte, wilc_multicast_mac_addr_list,
2451 ((hif_set_mc->cnt) * ETH_ALEN));
2453 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2454 wilc_get_vif_idx(vif));
2455 if (result)
2456 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2458 error:
2459 kfree(wid.val);
2462 static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
2464 int ret;
2465 struct wid wid;
2467 wid.id = (u16)WID_TX_POWER;
2468 wid.type = WID_CHAR;
2469 wid.val = &tx_pwr;
2470 wid.size = sizeof(char);
2472 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2473 wilc_get_vif_idx(vif));
2474 if (ret)
2475 netdev_err(vif->ndev, "Failed to set TX PWR\n");
2478 static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
2480 int ret = 0;
2481 struct wid wid;
2483 wid.id = (u16)WID_TX_POWER;
2484 wid.type = WID_CHAR;
2485 wid.val = (s8 *)tx_pwr;
2486 wid.size = sizeof(char);
2488 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2489 wilc_get_vif_idx(vif));
2490 if (ret)
2491 netdev_err(vif->ndev, "Failed to get TX PWR\n");
2493 complete(&hif_wait_response);
2496 static void host_if_work(struct work_struct *work)
2498 struct host_if_msg *msg;
2499 struct wilc *wilc;
2500 int ret = 0;
2502 msg = container_of(work, struct host_if_msg, work);
2503 wilc = msg->vif->wilc;
2505 if (msg->id == HOST_IF_MSG_CONNECT &&
2506 msg->vif->hif_drv->usr_scan_req.scan_result) {
2507 wilc_enqueue_cmd(msg);
2508 usleep_range(2 * 1000, 2 * 1000);
2509 goto free_msg;
2511 switch (msg->id) {
2512 case HOST_IF_MSG_SCAN:
2513 handle_scan(msg->vif, &msg->body.scan_info);
2514 break;
2516 case HOST_IF_MSG_CONNECT:
2517 handle_connect(msg->vif, &msg->body.con_info);
2518 break;
2520 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2521 handle_rcvd_ntwrk_info(msg->vif, &msg->body.net_info);
2522 break;
2524 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2525 handle_rcvd_gnrl_async_info(msg->vif,
2526 &msg->body.async_info);
2527 break;
2529 case HOST_IF_MSG_KEY:
2530 handle_key(msg->vif, &msg->body.key_info);
2531 break;
2533 case HOST_IF_MSG_CFG_PARAMS:
2534 handle_cfg_param(msg->vif, &msg->body.cfg_info);
2535 break;
2537 case HOST_IF_MSG_SET_CHANNEL:
2538 handle_set_channel(msg->vif, &msg->body.channel_info);
2539 break;
2541 case HOST_IF_MSG_DISCONNECT:
2542 handle_disconnect(msg->vif);
2543 break;
2545 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2546 del_timer(&msg->vif->hif_drv->scan_timer);
2548 if (!wilc_wlan_get_num_conn_ifcs(wilc))
2549 wilc_chip_sleep_manually(wilc);
2551 handle_scan_done(msg->vif, SCAN_EVENT_DONE);
2553 if (msg->vif->hif_drv->remain_on_ch_pending)
2554 handle_remain_on_chan(msg->vif,
2555 &msg->body.remain_on_ch);
2557 break;
2559 case HOST_IF_MSG_GET_RSSI:
2560 handle_get_rssi(msg->vif);
2561 break;
2563 case HOST_IF_MSG_GET_STATISTICS:
2564 handle_get_statistics(msg->vif,
2565 (struct rf_info *)msg->body.data);
2566 break;
2568 case HOST_IF_MSG_ADD_BEACON:
2569 handle_add_beacon(msg->vif, &msg->body.beacon_info);
2570 break;
2572 case HOST_IF_MSG_DEL_BEACON:
2573 handle_del_beacon(msg->vif);
2574 break;
2576 case HOST_IF_MSG_ADD_STATION:
2577 handle_add_station(msg->vif, &msg->body.add_sta_info);
2578 break;
2580 case HOST_IF_MSG_DEL_STATION:
2581 handle_del_station(msg->vif, &msg->body.del_sta_info);
2582 break;
2584 case HOST_IF_MSG_EDIT_STATION:
2585 handle_edit_station(msg->vif, &msg->body.edit_sta_info);
2586 break;
2588 case HOST_IF_MSG_GET_INACTIVETIME:
2589 handle_get_inactive_time(msg->vif, &msg->body.mac_info);
2590 break;
2592 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2593 handle_scan_done(msg->vif, SCAN_EVENT_ABORTED);
2594 break;
2596 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2597 handle_connect_timeout(msg->vif);
2598 break;
2600 case HOST_IF_MSG_POWER_MGMT:
2601 handle_power_management(msg->vif,
2602 &msg->body.pwr_mgmt_info);
2603 break;
2605 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2606 ret = handle_set_wfi_drv_handler(msg->vif, &msg->body.drv);
2607 break;
2609 case HOST_IF_MSG_SET_OPERATION_MODE:
2610 handle_set_operation_mode(msg->vif, &msg->body.mode);
2611 break;
2613 case HOST_IF_MSG_SET_IPADDRESS:
2614 handle_set_ip_address(msg->vif,
2615 msg->body.ip_info.ip_addr,
2616 msg->body.ip_info.idx);
2617 break;
2619 case HOST_IF_MSG_GET_IPADDRESS:
2620 handle_get_ip_address(msg->vif, msg->body.ip_info.idx);
2621 break;
2623 case HOST_IF_MSG_GET_MAC_ADDRESS:
2624 handle_get_mac_address(msg->vif,
2625 &msg->body.get_mac_info);
2626 break;
2628 case HOST_IF_MSG_REMAIN_ON_CHAN:
2629 handle_remain_on_chan(msg->vif, &msg->body.remain_on_ch);
2630 break;
2632 case HOST_IF_MSG_REGISTER_FRAME:
2633 handle_register_frame(msg->vif, &msg->body.reg_frame);
2634 break;
2636 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2637 handle_listen_state_expired(msg->vif, &msg->body.remain_on_ch);
2638 break;
2640 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2641 handle_set_mcast_filter(msg->vif, &msg->body.multicast_info);
2642 break;
2644 case HOST_IF_MSG_DEL_ALL_STA:
2645 handle_del_all_sta(msg->vif, &msg->body.del_all_sta_info);
2646 break;
2648 case HOST_IF_MSG_SET_TX_POWER:
2649 handle_set_tx_pwr(msg->vif, msg->body.tx_power.tx_pwr);
2650 break;
2652 case HOST_IF_MSG_GET_TX_POWER:
2653 handle_get_tx_pwr(msg->vif, &msg->body.tx_power.tx_pwr);
2654 break;
2655 default:
2656 netdev_err(msg->vif->ndev, "[Host Interface] undefined\n");
2657 break;
2659 free_msg:
2660 if (ret)
2661 netdev_err(msg->vif->ndev, "Host cmd %d failed\n", msg->id);
2662 kfree(msg);
2663 complete(&hif_thread_comp);
2666 static void timer_scan_cb(struct timer_list *t)
2668 struct host_if_drv *hif_drv = from_timer(hif_drv, t, scan_timer);
2669 struct wilc_vif *vif = hif_drv->scan_timer_vif;
2670 struct host_if_msg msg;
2672 memset(&msg, 0, sizeof(struct host_if_msg));
2673 msg.vif = vif;
2674 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
2676 wilc_enqueue_cmd(&msg);
2679 static void timer_connect_cb(struct timer_list *t)
2681 struct host_if_drv *hif_drv = from_timer(hif_drv, t,
2682 connect_timer);
2683 struct wilc_vif *vif = hif_drv->connect_timer_vif;
2684 struct host_if_msg msg;
2686 memset(&msg, 0, sizeof(struct host_if_msg));
2687 msg.vif = vif;
2688 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
2690 wilc_enqueue_cmd(&msg);
2693 s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *sta_addr)
2695 struct wid wid;
2697 wid.id = (u16)WID_REMOVE_KEY;
2698 wid.type = WID_STR;
2699 wid.val = (s8 *)sta_addr;
2700 wid.size = 6;
2702 return 0;
2705 int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
2707 int result = 0;
2708 struct host_if_msg msg;
2709 struct host_if_drv *hif_drv = vif->hif_drv;
2711 if (!hif_drv) {
2712 result = -EFAULT;
2713 netdev_err(vif->ndev, "Failed to send setup multicast\n");
2714 return result;
2717 memset(&msg, 0, sizeof(struct host_if_msg));
2719 msg.id = HOST_IF_MSG_KEY;
2720 msg.body.key_info.type = WEP;
2721 msg.body.key_info.action = REMOVEKEY;
2722 msg.vif = vif;
2723 msg.body.key_info.attr.wep.index = index;
2725 result = wilc_enqueue_cmd(&msg);
2726 if (result)
2727 netdev_err(vif->ndev, "Request to remove WEP key\n");
2728 else
2729 wait_for_completion(&hif_drv->comp_test_key_block);
2731 return result;
2734 int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
2736 int result = 0;
2737 struct host_if_msg msg;
2738 struct host_if_drv *hif_drv = vif->hif_drv;
2740 if (!hif_drv) {
2741 result = -EFAULT;
2742 netdev_err(vif->ndev, "driver is null\n");
2743 return result;
2746 memset(&msg, 0, sizeof(struct host_if_msg));
2748 msg.id = HOST_IF_MSG_KEY;
2749 msg.body.key_info.type = WEP;
2750 msg.body.key_info.action = DEFAULTKEY;
2751 msg.vif = vif;
2752 msg.body.key_info.attr.wep.index = index;
2754 result = wilc_enqueue_cmd(&msg);
2755 if (result)
2756 netdev_err(vif->ndev, "Default key index\n");
2757 else
2758 wait_for_completion(&hif_drv->comp_test_key_block);
2760 return result;
2763 int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2764 u8 index)
2766 int result = 0;
2767 struct host_if_msg msg;
2768 struct host_if_drv *hif_drv = vif->hif_drv;
2770 if (!hif_drv) {
2771 netdev_err(vif->ndev, "driver is null\n");
2772 return -EFAULT;
2775 memset(&msg, 0, sizeof(struct host_if_msg));
2777 msg.id = HOST_IF_MSG_KEY;
2778 msg.body.key_info.type = WEP;
2779 msg.body.key_info.action = ADDKEY;
2780 msg.vif = vif;
2781 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2782 if (!msg.body.key_info.attr.wep.key)
2783 return -ENOMEM;
2785 msg.body.key_info.attr.wep.key_len = len;
2786 msg.body.key_info.attr.wep.index = index;
2788 result = wilc_enqueue_cmd(&msg);
2789 if (result)
2790 netdev_err(vif->ndev, "STA - WEP Key\n");
2791 wait_for_completion(&hif_drv->comp_test_key_block);
2793 return result;
2796 int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
2797 u8 index, u8 mode, enum AUTHTYPE auth_type)
2799 int result = 0;
2800 struct host_if_msg msg;
2801 struct host_if_drv *hif_drv = vif->hif_drv;
2803 if (!hif_drv) {
2804 netdev_err(vif->ndev, "driver is null\n");
2805 return -EFAULT;
2808 memset(&msg, 0, sizeof(struct host_if_msg));
2810 msg.id = HOST_IF_MSG_KEY;
2811 msg.body.key_info.type = WEP;
2812 msg.body.key_info.action = ADDKEY_AP;
2813 msg.vif = vif;
2814 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2815 if (!msg.body.key_info.attr.wep.key)
2816 return -ENOMEM;
2818 msg.body.key_info.attr.wep.key_len = len;
2819 msg.body.key_info.attr.wep.index = index;
2820 msg.body.key_info.attr.wep.mode = mode;
2821 msg.body.key_info.attr.wep.auth_type = auth_type;
2823 result = wilc_enqueue_cmd(&msg);
2825 if (result)
2826 netdev_err(vif->ndev, "AP - WEP Key\n");
2827 else
2828 wait_for_completion(&hif_drv->comp_test_key_block);
2830 return result;
2833 int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
2834 const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
2835 u8 mode, u8 cipher_mode, u8 index)
2837 int result = 0;
2838 struct host_if_msg msg;
2839 struct host_if_drv *hif_drv = vif->hif_drv;
2840 u8 key_len = ptk_key_len;
2842 if (!hif_drv) {
2843 netdev_err(vif->ndev, "driver is null\n");
2844 return -EFAULT;
2847 if (rx_mic)
2848 key_len += RX_MIC_KEY_LEN;
2850 if (tx_mic)
2851 key_len += TX_MIC_KEY_LEN;
2853 memset(&msg, 0, sizeof(struct host_if_msg));
2855 msg.id = HOST_IF_MSG_KEY;
2856 msg.body.key_info.type = WPA_PTK;
2857 if (mode == AP_MODE) {
2858 msg.body.key_info.action = ADDKEY_AP;
2859 msg.body.key_info.attr.wpa.index = index;
2861 if (mode == STATION_MODE)
2862 msg.body.key_info.action = ADDKEY;
2864 msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
2865 if (!msg.body.key_info.attr.wpa.key)
2866 return -ENOMEM;
2868 if (rx_mic)
2869 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2870 RX_MIC_KEY_LEN);
2872 if (tx_mic)
2873 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
2874 TX_MIC_KEY_LEN);
2876 msg.body.key_info.attr.wpa.key_len = key_len;
2877 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
2878 msg.body.key_info.attr.wpa.mode = cipher_mode;
2879 msg.vif = vif;
2881 result = wilc_enqueue_cmd(&msg);
2883 if (result)
2884 netdev_err(vif->ndev, "PTK Key\n");
2885 else
2886 wait_for_completion(&hif_drv->comp_test_key_block);
2888 return result;
2891 int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
2892 u8 index, u32 key_rsc_len, const u8 *key_rsc,
2893 const u8 *rx_mic, const u8 *tx_mic, u8 mode,
2894 u8 cipher_mode)
2896 int result = 0;
2897 struct host_if_msg msg;
2898 struct host_if_drv *hif_drv = vif->hif_drv;
2899 u8 key_len = gtk_key_len;
2901 if (!hif_drv) {
2902 netdev_err(vif->ndev, "driver is null\n");
2903 return -EFAULT;
2905 memset(&msg, 0, sizeof(struct host_if_msg));
2907 if (rx_mic)
2908 key_len += RX_MIC_KEY_LEN;
2910 if (tx_mic)
2911 key_len += TX_MIC_KEY_LEN;
2913 if (key_rsc) {
2914 msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
2915 key_rsc_len,
2916 GFP_KERNEL);
2917 if (!msg.body.key_info.attr.wpa.seq)
2918 return -ENOMEM;
2921 msg.id = HOST_IF_MSG_KEY;
2922 msg.body.key_info.type = WPA_RX_GTK;
2923 msg.vif = vif;
2925 if (mode == AP_MODE) {
2926 msg.body.key_info.action = ADDKEY_AP;
2927 msg.body.key_info.attr.wpa.mode = cipher_mode;
2929 if (mode == STATION_MODE)
2930 msg.body.key_info.action = ADDKEY;
2932 msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
2933 key_len,
2934 GFP_KERNEL);
2935 if (!msg.body.key_info.attr.wpa.key)
2936 return -ENOMEM;
2938 if (rx_mic)
2939 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2940 RX_MIC_KEY_LEN);
2942 if (tx_mic)
2943 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
2944 TX_MIC_KEY_LEN);
2946 msg.body.key_info.attr.wpa.index = index;
2947 msg.body.key_info.attr.wpa.key_len = key_len;
2948 msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
2950 result = wilc_enqueue_cmd(&msg);
2951 if (result)
2952 netdev_err(vif->ndev, "RX GTK\n");
2953 else
2954 wait_for_completion(&hif_drv->comp_test_key_block);
2956 return result;
2959 int wilc_set_pmkid_info(struct wilc_vif *vif,
2960 struct host_if_pmkid_attr *pmkid)
2962 int result = 0;
2963 struct host_if_msg msg;
2964 int i;
2966 memset(&msg, 0, sizeof(struct host_if_msg));
2968 msg.id = HOST_IF_MSG_KEY;
2969 msg.body.key_info.type = PMKSA;
2970 msg.body.key_info.action = ADDKEY;
2971 msg.vif = vif;
2973 for (i = 0; i < pmkid->numpmkid; i++) {
2974 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
2975 &pmkid->pmkidlist[i].bssid, ETH_ALEN);
2976 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
2977 &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
2980 result = wilc_enqueue_cmd(&msg);
2981 if (result)
2982 netdev_err(vif->ndev, "PMKID Info\n");
2984 return result;
2987 int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
2989 int result = 0;
2990 struct host_if_msg msg;
2992 memset(&msg, 0, sizeof(struct host_if_msg));
2994 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
2995 msg.body.get_mac_info.mac_addr = mac_addr;
2996 msg.vif = vif;
2998 result = wilc_enqueue_cmd(&msg);
2999 if (result) {
3000 netdev_err(vif->ndev, "Failed to send get mac address\n");
3001 return -EFAULT;
3004 wait_for_completion(&hif_wait_response);
3005 return result;
3008 int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
3009 size_t ssid_len, const u8 *ies, size_t ies_len,
3010 wilc_connect_result connect_result, void *user_arg,
3011 u8 security, enum AUTHTYPE auth_type,
3012 u8 channel, void *join_params)
3014 int result = 0;
3015 struct host_if_msg msg;
3016 struct host_if_drv *hif_drv = vif->hif_drv;
3018 if (!hif_drv || !connect_result) {
3019 netdev_err(vif->ndev, "Driver is null\n");
3020 return -EFAULT;
3023 if (!join_params) {
3024 netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
3025 return -EFAULT;
3028 memset(&msg, 0, sizeof(struct host_if_msg));
3030 msg.id = HOST_IF_MSG_CONNECT;
3032 msg.body.con_info.security = security;
3033 msg.body.con_info.auth_type = auth_type;
3034 msg.body.con_info.ch = channel;
3035 msg.body.con_info.result = connect_result;
3036 msg.body.con_info.arg = user_arg;
3037 msg.body.con_info.params = join_params;
3038 msg.vif = vif;
3040 if (bssid) {
3041 msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3042 if (!msg.body.con_info.bssid)
3043 return -ENOMEM;
3046 if (ssid) {
3047 msg.body.con_info.ssid_len = ssid_len;
3048 msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
3049 if (!msg.body.con_info.ssid)
3050 return -ENOMEM;
3053 if (ies) {
3054 msg.body.con_info.ies_len = ies_len;
3055 msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
3056 if (!msg.body.con_info.ies)
3057 return -ENOMEM;
3059 if (hif_drv->hif_state < HOST_IF_CONNECTING)
3060 hif_drv->hif_state = HOST_IF_CONNECTING;
3062 result = wilc_enqueue_cmd(&msg);
3063 if (result) {
3064 netdev_err(vif->ndev, "send message: Set join request\n");
3065 return -EFAULT;
3068 hif_drv->connect_timer_vif = vif;
3069 mod_timer(&hif_drv->connect_timer,
3070 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3072 return result;
3075 int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
3077 int result = 0;
3078 struct host_if_msg msg;
3079 struct host_if_drv *hif_drv = vif->hif_drv;
3081 if (!hif_drv) {
3082 netdev_err(vif->ndev, "Driver is null\n");
3083 return -EFAULT;
3086 memset(&msg, 0, sizeof(struct host_if_msg));
3088 msg.id = HOST_IF_MSG_DISCONNECT;
3089 msg.vif = vif;
3091 result = wilc_enqueue_cmd(&msg);
3092 if (result)
3093 netdev_err(vif->ndev, "Failed to send message: disconnect\n");
3094 else
3095 wait_for_completion(&hif_drv->comp_test_disconn_block);
3097 return result;
3100 static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
3101 u8 *assoc_resp_info,
3102 u32 max_assoc_resp_info_len,
3103 u32 *rcvd_assoc_resp_info_len)
3105 s32 result = 0;
3106 struct wid wid;
3108 wid.id = (u16)WID_ASSOC_RES_INFO;
3109 wid.type = WID_STR;
3110 wid.val = assoc_resp_info;
3111 wid.size = max_assoc_resp_info_len;
3113 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
3114 wilc_get_vif_idx(vif));
3115 if (result) {
3116 *rcvd_assoc_resp_info_len = 0;
3117 netdev_err(vif->ndev, "Failed to send association response\n");
3118 return -EINVAL;
3121 *rcvd_assoc_resp_info_len = wid.size;
3122 return result;
3125 int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
3127 int result;
3128 struct host_if_msg msg;
3130 memset(&msg, 0, sizeof(struct host_if_msg));
3131 msg.id = HOST_IF_MSG_SET_CHANNEL;
3132 msg.body.channel_info.set_ch = channel;
3133 msg.vif = vif;
3135 result = wilc_enqueue_cmd(&msg);
3136 if (result) {
3137 netdev_err(vif->ndev, "wilc mq send fail\n");
3138 return -EINVAL;
3141 return 0;
3144 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
3145 u8 ifc_id)
3147 int result = 0;
3148 struct host_if_msg msg;
3150 memset(&msg, 0, sizeof(struct host_if_msg));
3151 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3152 msg.body.drv.handler = index;
3153 msg.body.drv.mode = mode;
3154 msg.body.drv.name = ifc_id;
3155 msg.vif = vif;
3157 result = wilc_enqueue_cmd(&msg);
3158 if (result) {
3159 netdev_err(vif->ndev, "wilc mq send fail\n");
3160 result = -EINVAL;
3163 return result;
3166 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
3168 int result = 0;
3169 struct host_if_msg msg;
3171 memset(&msg, 0, sizeof(struct host_if_msg));
3172 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3173 msg.body.mode.mode = mode;
3174 msg.vif = vif;
3176 result = wilc_enqueue_cmd(&msg);
3177 if (result) {
3178 netdev_err(vif->ndev, "wilc mq send fail\n");
3179 result = -EINVAL;
3182 return result;
3185 s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3186 u32 *out_val)
3188 s32 result = 0;
3189 struct host_if_msg msg;
3190 struct host_if_drv *hif_drv = vif->hif_drv;
3192 if (!hif_drv) {
3193 netdev_err(vif->ndev, "driver is null\n");
3194 return -EFAULT;
3197 memset(&msg, 0, sizeof(struct host_if_msg));
3198 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3200 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3201 msg.vif = vif;
3203 result = wilc_enqueue_cmd(&msg);
3204 if (result)
3205 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3206 else
3207 wait_for_completion(&hif_drv->comp_inactive_time);
3209 *out_val = inactive_time;
3211 return result;
3214 int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
3216 int result = 0;
3217 struct host_if_msg msg;
3218 struct host_if_drv *hif_drv = vif->hif_drv;
3220 memset(&msg, 0, sizeof(struct host_if_msg));
3221 msg.id = HOST_IF_MSG_GET_RSSI;
3222 msg.vif = vif;
3224 result = wilc_enqueue_cmd(&msg);
3225 if (result) {
3226 netdev_err(vif->ndev, "Failed to send get host ch param\n");
3227 return -EFAULT;
3230 wait_for_completion(&hif_drv->comp_get_rssi);
3232 if (!rssi_level) {
3233 netdev_err(vif->ndev, "RSS pointer value is null\n");
3234 return -EFAULT;
3237 *rssi_level = rssi;
3239 return result;
3242 int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
3244 int result = 0;
3245 struct host_if_msg msg;
3247 memset(&msg, 0, sizeof(struct host_if_msg));
3248 msg.id = HOST_IF_MSG_GET_STATISTICS;
3249 msg.body.data = (char *)stats;
3250 msg.vif = vif;
3252 result = wilc_enqueue_cmd(&msg);
3253 if (result) {
3254 netdev_err(vif->ndev, "Failed to send get host channel\n");
3255 return -EFAULT;
3258 if (stats != &vif->wilc->dummy_statistics)
3259 wait_for_completion(&hif_wait_response);
3260 return result;
3263 int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
3264 u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
3265 size_t ies_len, wilc_scan_result scan_result, void *user_arg,
3266 struct hidden_network *hidden_network)
3268 int result = 0;
3269 struct host_if_msg msg;
3270 struct scan_attr *scan_info = &msg.body.scan_info;
3271 struct host_if_drv *hif_drv = vif->hif_drv;
3273 if (!hif_drv || !scan_result) {
3274 netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
3275 return -EFAULT;
3278 memset(&msg, 0, sizeof(struct host_if_msg));
3280 msg.id = HOST_IF_MSG_SCAN;
3282 if (hidden_network) {
3283 scan_info->hidden_network.net_info = hidden_network->net_info;
3284 scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
3287 msg.vif = vif;
3288 scan_info->src = scan_source;
3289 scan_info->type = scan_type;
3290 scan_info->result = scan_result;
3291 scan_info->arg = user_arg;
3293 scan_info->ch_list_len = ch_list_len;
3294 scan_info->ch_freq_list = kmemdup(ch_freq_list,
3295 ch_list_len,
3296 GFP_KERNEL);
3297 if (!scan_info->ch_freq_list)
3298 return -ENOMEM;
3300 scan_info->ies_len = ies_len;
3301 scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3302 if (!scan_info->ies)
3303 return -ENOMEM;
3305 result = wilc_enqueue_cmd(&msg);
3306 if (result) {
3307 netdev_err(vif->ndev, "Error in sending message queue\n");
3308 return -EINVAL;
3311 hif_drv->scan_timer_vif = vif;
3312 mod_timer(&hif_drv->scan_timer,
3313 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3315 return result;
3318 int wilc_hif_set_cfg(struct wilc_vif *vif,
3319 struct cfg_param_attr *cfg_param)
3321 struct host_if_msg msg;
3322 struct host_if_drv *hif_drv = vif->hif_drv;
3324 if (!hif_drv) {
3325 netdev_err(vif->ndev, "hif_drv NULL\n");
3326 return -EFAULT;
3329 memset(&msg, 0, sizeof(struct host_if_msg));
3330 msg.id = HOST_IF_MSG_CFG_PARAMS;
3331 msg.body.cfg_info = *cfg_param;
3332 msg.vif = vif;
3334 return wilc_enqueue_cmd(&msg);
3337 static void get_periodic_rssi(struct timer_list *unused)
3339 struct wilc_vif *vif = periodic_rssi_vif;
3341 if (!vif->hif_drv) {
3342 netdev_err(vif->ndev, "Driver handler is NULL\n");
3343 return;
3346 if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3347 wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
3349 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3352 int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
3354 int result = 0;
3355 struct host_if_drv *hif_drv;
3356 struct wilc_vif *vif;
3357 struct wilc *wilc;
3358 int i;
3360 vif = netdev_priv(dev);
3361 wilc = vif->wilc;
3363 scan_while_connected = false;
3365 init_completion(&hif_wait_response);
3367 hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
3368 if (!hif_drv) {
3369 result = -ENOMEM;
3370 goto _fail_;
3372 *hif_drv_handler = hif_drv;
3373 for (i = 0; i < wilc->vif_num; i++)
3374 if (dev == wilc->vif[i]->ndev) {
3375 wilc->vif[i]->hif_drv = hif_drv;
3376 hif_drv->driver_handler_id = i + 1;
3377 break;
3380 wilc_optaining_ip = false;
3382 if (clients_count == 0) {
3383 init_completion(&hif_thread_comp);
3384 init_completion(&hif_driver_comp);
3385 mutex_init(&hif_deinit_lock);
3388 init_completion(&hif_drv->comp_test_key_block);
3389 init_completion(&hif_drv->comp_test_disconn_block);
3390 init_completion(&hif_drv->comp_get_rssi);
3391 init_completion(&hif_drv->comp_inactive_time);
3393 if (clients_count == 0) {
3394 hif_workqueue = create_singlethread_workqueue("WILC_wq");
3395 if (!hif_workqueue) {
3396 netdev_err(vif->ndev, "Failed to create workqueue\n");
3397 result = -ENOMEM;
3398 goto _fail_;
3401 periodic_rssi_vif = vif;
3402 timer_setup(&periodic_rssi, get_periodic_rssi, 0);
3403 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3406 timer_setup(&hif_drv->scan_timer, timer_scan_cb, 0);
3407 timer_setup(&hif_drv->connect_timer, timer_connect_cb, 0);
3408 timer_setup(&hif_drv->remain_on_ch_timer, listen_timer_cb, 0);
3410 mutex_init(&hif_drv->cfg_values_lock);
3411 mutex_lock(&hif_drv->cfg_values_lock);
3413 hif_drv->hif_state = HOST_IF_IDLE;
3414 hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
3415 hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
3416 hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
3417 hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
3418 hif_drv->cfg_values.curr_tx_rate = AUTORATE;
3420 hif_drv->p2p_timeout = 0;
3422 mutex_unlock(&hif_drv->cfg_values_lock);
3424 clients_count++;
3426 _fail_:
3427 return result;
3430 int wilc_deinit(struct wilc_vif *vif)
3432 int result = 0;
3433 struct host_if_msg msg;
3434 struct host_if_drv *hif_drv = vif->hif_drv;
3436 if (!hif_drv) {
3437 netdev_err(vif->ndev, "hif_drv = NULL\n");
3438 return -EFAULT;
3441 mutex_lock(&hif_deinit_lock);
3443 terminated_handle = hif_drv;
3445 del_timer_sync(&hif_drv->scan_timer);
3446 del_timer_sync(&hif_drv->connect_timer);
3447 del_timer_sync(&periodic_rssi);
3448 del_timer_sync(&hif_drv->remain_on_ch_timer);
3450 wilc_set_wfi_drv_handler(vif, 0, 0, 0);
3451 wait_for_completion(&hif_driver_comp);
3453 if (hif_drv->usr_scan_req.scan_result) {
3454 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
3455 hif_drv->usr_scan_req.arg,
3456 NULL);
3457 hif_drv->usr_scan_req.scan_result = NULL;
3460 hif_drv->hif_state = HOST_IF_IDLE;
3462 scan_while_connected = false;
3464 memset(&msg, 0, sizeof(struct host_if_msg));
3466 if (clients_count == 1) {
3467 msg.id = HOST_IF_MSG_EXIT;
3468 msg.vif = vif;
3470 result = wilc_enqueue_cmd(&msg);
3471 if (result != 0)
3472 netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
3473 else
3474 wait_for_completion(&hif_thread_comp);
3476 destroy_workqueue(hif_workqueue);
3479 kfree(hif_drv);
3481 clients_count--;
3482 terminated_handle = NULL;
3483 mutex_unlock(&hif_deinit_lock);
3484 return result;
3487 void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3489 s32 result = 0;
3490 struct host_if_msg msg;
3491 int id;
3492 struct host_if_drv *hif_drv = NULL;
3493 struct wilc_vif *vif;
3495 id = buffer[length - 4];
3496 id |= (buffer[length - 3] << 8);
3497 id |= (buffer[length - 2] << 16);
3498 id |= (buffer[length - 1] << 24);
3499 vif = wilc_get_vif_from_idx(wilc, id);
3500 if (!vif)
3501 return;
3502 hif_drv = vif->hif_drv;
3504 if (!hif_drv || hif_drv == terminated_handle) {
3505 netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
3506 return;
3509 memset(&msg, 0, sizeof(struct host_if_msg));
3511 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
3512 msg.vif = vif;
3514 msg.body.net_info.len = length;
3515 msg.body.net_info.buffer = kmalloc(length, GFP_KERNEL);
3516 memcpy(msg.body.net_info.buffer, buffer, length);
3518 result = wilc_enqueue_cmd(&msg);
3519 if (result)
3520 netdev_err(vif->ndev, "message parameters (%d)\n", result);
3523 void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3525 s32 result = 0;
3526 struct host_if_msg msg;
3527 int id;
3528 struct host_if_drv *hif_drv = NULL;
3529 struct wilc_vif *vif;
3531 mutex_lock(&hif_deinit_lock);
3533 id = buffer[length - 4];
3534 id |= (buffer[length - 3] << 8);
3535 id |= (buffer[length - 2] << 16);
3536 id |= (buffer[length - 1] << 24);
3537 vif = wilc_get_vif_from_idx(wilc, id);
3538 if (!vif) {
3539 mutex_unlock(&hif_deinit_lock);
3540 return;
3543 hif_drv = vif->hif_drv;
3545 if (!hif_drv || hif_drv == terminated_handle) {
3546 mutex_unlock(&hif_deinit_lock);
3547 return;
3550 if (!hif_drv->usr_conn_req.conn_result) {
3551 netdev_err(vif->ndev, "there is no current Connect Request\n");
3552 mutex_unlock(&hif_deinit_lock);
3553 return;
3556 memset(&msg, 0, sizeof(struct host_if_msg));
3558 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
3559 msg.vif = vif;
3561 msg.body.async_info.len = length;
3562 msg.body.async_info.buffer = kmalloc(length, GFP_KERNEL);
3563 memcpy(msg.body.async_info.buffer, buffer, length);
3565 result = wilc_enqueue_cmd(&msg);
3566 if (result)
3567 netdev_err(vif->ndev, "synchronous info (%d)\n", result);
3569 mutex_unlock(&hif_deinit_lock);
3572 void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
3574 s32 result = 0;
3575 struct host_if_msg msg;
3576 int id;
3577 struct host_if_drv *hif_drv = NULL;
3578 struct wilc_vif *vif;
3580 id = buffer[length - 4];
3581 id |= buffer[length - 3] << 8;
3582 id |= buffer[length - 2] << 16;
3583 id |= buffer[length - 1] << 24;
3584 vif = wilc_get_vif_from_idx(wilc, id);
3585 if (!vif)
3586 return;
3587 hif_drv = vif->hif_drv;
3589 if (!hif_drv || hif_drv == terminated_handle)
3590 return;
3592 if (hif_drv->usr_scan_req.scan_result) {
3593 memset(&msg, 0, sizeof(struct host_if_msg));
3595 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
3596 msg.vif = vif;
3598 result = wilc_enqueue_cmd(&msg);
3599 if (result)
3600 netdev_err(vif->ndev, "complete param (%d)\n", result);
3604 int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
3605 u32 duration, u16 chan,
3606 wilc_remain_on_chan_expired expired,
3607 wilc_remain_on_chan_ready ready,
3608 void *user_arg)
3610 int result = 0;
3611 struct host_if_msg msg;
3613 memset(&msg, 0, sizeof(struct host_if_msg));
3615 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
3616 msg.body.remain_on_ch.ch = chan;
3617 msg.body.remain_on_ch.expired = expired;
3618 msg.body.remain_on_ch.ready = ready;
3619 msg.body.remain_on_ch.arg = user_arg;
3620 msg.body.remain_on_ch.duration = duration;
3621 msg.body.remain_on_ch.id = session_id;
3622 msg.vif = vif;
3624 result = wilc_enqueue_cmd(&msg);
3625 if (result)
3626 netdev_err(vif->ndev, "wilc mq send fail\n");
3628 return result;
3631 int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
3633 int result = 0;
3634 struct host_if_msg msg;
3635 struct host_if_drv *hif_drv = vif->hif_drv;
3637 if (!hif_drv) {
3638 netdev_err(vif->ndev, "driver is null\n");
3639 return -EFAULT;
3642 del_timer(&hif_drv->remain_on_ch_timer);
3644 memset(&msg, 0, sizeof(struct host_if_msg));
3645 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3646 msg.vif = vif;
3647 msg.body.remain_on_ch.id = session_id;
3649 result = wilc_enqueue_cmd(&msg);
3650 if (result)
3651 netdev_err(vif->ndev, "wilc mq send fail\n");
3653 return result;
3656 int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
3658 int result = 0;
3659 struct host_if_msg msg;
3661 memset(&msg, 0, sizeof(struct host_if_msg));
3663 msg.id = HOST_IF_MSG_REGISTER_FRAME;
3664 switch (frame_type) {
3665 case ACTION:
3666 msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
3667 break;
3669 case PROBE_REQ:
3670 msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
3671 break;
3673 default:
3674 break;
3676 msg.body.reg_frame.frame_type = frame_type;
3677 msg.body.reg_frame.reg = reg;
3678 msg.vif = vif;
3680 result = wilc_enqueue_cmd(&msg);
3681 if (result)
3682 netdev_err(vif->ndev, "wilc mq send fail\n");
3684 return result;
3687 int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
3688 u32 head_len, u8 *head, u32 tail_len, u8 *tail)
3690 int result = 0;
3691 struct host_if_msg msg;
3692 struct beacon_attr *beacon_info = &msg.body.beacon_info;
3694 memset(&msg, 0, sizeof(struct host_if_msg));
3696 msg.id = HOST_IF_MSG_ADD_BEACON;
3697 msg.vif = vif;
3698 beacon_info->interval = interval;
3699 beacon_info->dtim_period = dtim_period;
3700 beacon_info->head_len = head_len;
3701 beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
3702 if (!beacon_info->head) {
3703 result = -ENOMEM;
3704 goto error;
3706 beacon_info->tail_len = tail_len;
3708 if (tail_len > 0) {
3709 beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3710 if (!beacon_info->tail) {
3711 result = -ENOMEM;
3712 goto error;
3714 } else {
3715 beacon_info->tail = NULL;
3718 result = wilc_enqueue_cmd(&msg);
3719 if (result)
3720 netdev_err(vif->ndev, "wilc mq send fail\n");
3722 error:
3723 if (result) {
3724 kfree(beacon_info->head);
3726 kfree(beacon_info->tail);
3729 return result;
3732 int wilc_del_beacon(struct wilc_vif *vif)
3734 int result = 0;
3735 struct host_if_msg msg;
3737 msg.id = HOST_IF_MSG_DEL_BEACON;
3738 msg.vif = vif;
3740 result = wilc_enqueue_cmd(&msg);
3741 if (result)
3742 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3744 return result;
3747 int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
3749 int result = 0;
3750 struct host_if_msg msg;
3751 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3753 memset(&msg, 0, sizeof(struct host_if_msg));
3755 msg.id = HOST_IF_MSG_ADD_STATION;
3756 msg.vif = vif;
3758 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3759 if (add_sta_info->rates_len > 0) {
3760 add_sta_info->rates = kmemdup(sta_param->rates,
3761 add_sta_info->rates_len,
3762 GFP_KERNEL);
3763 if (!add_sta_info->rates)
3764 return -ENOMEM;
3767 result = wilc_enqueue_cmd(&msg);
3768 if (result)
3769 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3770 return result;
3773 int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
3775 int result = 0;
3776 struct host_if_msg msg;
3777 struct del_sta *del_sta_info = &msg.body.del_sta_info;
3779 memset(&msg, 0, sizeof(struct host_if_msg));
3781 msg.id = HOST_IF_MSG_DEL_STATION;
3782 msg.vif = vif;
3784 if (!mac_addr)
3785 eth_broadcast_addr(del_sta_info->mac_addr);
3786 else
3787 memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
3789 result = wilc_enqueue_cmd(&msg);
3790 if (result)
3791 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3792 return result;
3795 int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
3797 int result = 0;
3798 struct host_if_msg msg;
3799 struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
3800 u8 zero_addr[ETH_ALEN] = {0};
3801 int i;
3802 u8 assoc_sta = 0;
3804 memset(&msg, 0, sizeof(struct host_if_msg));
3806 msg.id = HOST_IF_MSG_DEL_ALL_STA;
3807 msg.vif = vif;
3809 for (i = 0; i < MAX_NUM_STA; i++) {
3810 if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
3811 memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i],
3812 ETH_ALEN);
3813 assoc_sta++;
3816 if (!assoc_sta)
3817 return result;
3819 del_all_sta_info->assoc_sta = assoc_sta;
3820 result = wilc_enqueue_cmd(&msg);
3822 if (result)
3823 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3824 else
3825 wait_for_completion(&hif_wait_response);
3827 return result;
3830 int wilc_edit_station(struct wilc_vif *vif,
3831 struct add_sta_param *sta_param)
3833 int result = 0;
3834 struct host_if_msg msg;
3835 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3837 memset(&msg, 0, sizeof(struct host_if_msg));
3839 msg.id = HOST_IF_MSG_EDIT_STATION;
3840 msg.vif = vif;
3842 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3843 if (add_sta_info->rates_len > 0) {
3844 add_sta_info->rates = kmemdup(sta_param->rates,
3845 add_sta_info->rates_len,
3846 GFP_KERNEL);
3847 if (!add_sta_info->rates)
3848 return -ENOMEM;
3851 result = wilc_enqueue_cmd(&msg);
3852 if (result)
3853 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3855 return result;
3858 int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
3860 int result = 0;
3861 struct host_if_msg msg;
3862 struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
3864 if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
3865 return 0;
3867 memset(&msg, 0, sizeof(struct host_if_msg));
3869 msg.id = HOST_IF_MSG_POWER_MGMT;
3870 msg.vif = vif;
3872 pwr_mgmt_info->enabled = enabled;
3873 pwr_mgmt_info->timeout = timeout;
3875 result = wilc_enqueue_cmd(&msg);
3876 if (result)
3877 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3878 return result;
3881 int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
3882 u32 count)
3884 int result = 0;
3885 struct host_if_msg msg;
3886 struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
3888 memset(&msg, 0, sizeof(struct host_if_msg));
3890 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
3891 msg.vif = vif;
3893 multicast_filter_param->enabled = enabled;
3894 multicast_filter_param->cnt = count;
3896 result = wilc_enqueue_cmd(&msg);
3897 if (result)
3898 netdev_err(vif->ndev, "wilc_mq_send fail\n");
3899 return result;
3902 static void *host_int_parse_join_bss_param(struct network_info *info)
3904 struct join_bss_param *param = NULL;
3905 u8 *ies;
3906 u16 ies_len;
3907 u16 index = 0;
3908 u8 rates_no = 0;
3909 u8 ext_rates_no;
3910 u16 offset;
3911 u8 pcipher_cnt;
3912 u8 auth_cnt;
3913 u8 pcipher_total_cnt = 0;
3914 u8 auth_total_cnt = 0;
3915 u8 i, j;
3917 ies = info->ies;
3918 ies_len = info->ies_len;
3920 param = kzalloc(sizeof(*param), GFP_KERNEL);
3921 if (!param)
3922 return NULL;
3924 param->dtim_period = info->dtim_period;
3925 param->beacon_period = info->beacon_period;
3926 param->cap_info = info->cap_info;
3927 memcpy(param->bssid, info->bssid, 6);
3928 memcpy((u8 *)param->ssid, info->ssid, info->ssid_len + 1);
3929 param->ssid_len = info->ssid_len;
3930 memset(param->rsn_pcip_policy, 0xFF, 3);
3931 memset(param->rsn_auth_policy, 0xFF, 3);
3933 while (index < ies_len) {
3934 if (ies[index] == SUPP_RATES_IE) {
3935 rates_no = ies[index + 1];
3936 param->supp_rates[0] = rates_no;
3937 index += 2;
3939 for (i = 0; i < rates_no; i++)
3940 param->supp_rates[i + 1] = ies[index + i];
3942 index += rates_no;
3943 } else if (ies[index] == EXT_SUPP_RATES_IE) {
3944 ext_rates_no = ies[index + 1];
3945 if (ext_rates_no > (MAX_RATES_SUPPORTED - rates_no))
3946 param->supp_rates[0] = MAX_RATES_SUPPORTED;
3947 else
3948 param->supp_rates[0] += ext_rates_no;
3949 index += 2;
3950 for (i = 0; i < (param->supp_rates[0] - rates_no); i++)
3951 param->supp_rates[rates_no + i + 1] = ies[index + i];
3953 index += ext_rates_no;
3954 } else if (ies[index] == HT_CAPABILITY_IE) {
3955 param->ht_capable = true;
3956 index += ies[index + 1] + 2;
3957 } else if ((ies[index] == WMM_IE) &&
3958 (ies[index + 2] == 0x00) && (ies[index + 3] == 0x50) &&
3959 (ies[index + 4] == 0xF2) &&
3960 (ies[index + 5] == 0x02) &&
3961 ((ies[index + 6] == 0x00) || (ies[index + 6] == 0x01)) &&
3962 (ies[index + 7] == 0x01)) {
3963 param->wmm_cap = true;
3965 if (ies[index + 8] & BIT(7))
3966 param->uapsd_cap = true;
3967 index += ies[index + 1] + 2;
3968 } else if ((ies[index] == P2P_IE) &&
3969 (ies[index + 2] == 0x50) && (ies[index + 3] == 0x6f) &&
3970 (ies[index + 4] == 0x9a) &&
3971 (ies[index + 5] == 0x09) && (ies[index + 6] == 0x0c)) {
3972 u16 p2p_cnt;
3974 param->tsf = info->tsf_lo;
3975 param->noa_enabled = 1;
3976 param->idx = ies[index + 9];
3978 if (ies[index + 10] & BIT(7)) {
3979 param->opp_enabled = 1;
3980 param->ct_window = ies[index + 10];
3981 } else {
3982 param->opp_enabled = 0;
3985 param->cnt = ies[index + 11];
3986 p2p_cnt = index + 12;
3988 memcpy(param->duration, ies + p2p_cnt, 4);
3989 p2p_cnt += 4;
3991 memcpy(param->interval, ies + p2p_cnt, 4);
3992 p2p_cnt += 4;
3994 memcpy(param->start_time, ies + p2p_cnt, 4);
3996 index += ies[index + 1] + 2;
3997 } else if ((ies[index] == RSN_IE) ||
3998 ((ies[index] == WPA_IE) && (ies[index + 2] == 0x00) &&
3999 (ies[index + 3] == 0x50) && (ies[index + 4] == 0xF2) &&
4000 (ies[index + 5] == 0x01))) {
4001 u16 rsn_idx = index;
4003 if (ies[rsn_idx] == RSN_IE) {
4004 param->mode_802_11i = 2;
4005 } else {
4006 if (param->mode_802_11i == 0)
4007 param->mode_802_11i = 1;
4008 rsn_idx += 4;
4011 rsn_idx += 7;
4012 param->rsn_grp_policy = ies[rsn_idx];
4013 rsn_idx++;
4014 offset = ies[rsn_idx] * 4;
4015 pcipher_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx];
4016 rsn_idx += 2;
4018 for (i = pcipher_total_cnt, j = 0; i < pcipher_cnt + pcipher_total_cnt && i < 3; i++, j++)
4019 param->rsn_pcip_policy[i] = ies[rsn_idx + ((j + 1) * 4) - 1];
4021 pcipher_total_cnt += pcipher_cnt;
4022 rsn_idx += offset;
4024 offset = ies[rsn_idx] * 4;
4026 auth_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx];
4027 rsn_idx += 2;
4029 for (i = auth_total_cnt, j = 0; i < auth_total_cnt + auth_cnt; i++, j++)
4030 param->rsn_auth_policy[i] = ies[rsn_idx + ((j + 1) * 4) - 1];
4032 auth_total_cnt += auth_cnt;
4033 rsn_idx += offset;
4035 if (ies[index] == RSN_IE) {
4036 param->rsn_cap[0] = ies[rsn_idx];
4037 param->rsn_cap[1] = ies[rsn_idx + 1];
4038 rsn_idx += 2;
4040 param->rsn_found = true;
4041 index += ies[index + 1] + 2;
4042 } else {
4043 index += ies[index + 1] + 2;
4047 return (void *)param;
4050 int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4052 int result = 0;
4053 struct host_if_msg msg;
4055 memset(&msg, 0, sizeof(struct host_if_msg));
4057 msg.id = HOST_IF_MSG_SET_IPADDRESS;
4059 msg.body.ip_info.ip_addr = ip_addr;
4060 msg.vif = vif;
4061 msg.body.ip_info.idx = idx;
4063 result = wilc_enqueue_cmd(&msg);
4064 if (result)
4065 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4067 return result;
4070 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4072 int result = 0;
4073 struct host_if_msg msg;
4075 memset(&msg, 0, sizeof(struct host_if_msg));
4077 msg.id = HOST_IF_MSG_GET_IPADDRESS;
4079 msg.body.ip_info.ip_addr = ip_addr;
4080 msg.vif = vif;
4081 msg.body.ip_info.idx = idx;
4083 result = wilc_enqueue_cmd(&msg);
4084 if (result)
4085 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4087 return result;
4090 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4092 int ret = 0;
4093 struct host_if_msg msg;
4095 memset(&msg, 0, sizeof(struct host_if_msg));
4097 msg.id = HOST_IF_MSG_SET_TX_POWER;
4098 msg.body.tx_power.tx_pwr = tx_power;
4099 msg.vif = vif;
4101 ret = wilc_enqueue_cmd(&msg);
4102 if (ret)
4103 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4105 return ret;
4108 int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4110 int ret = 0;
4111 struct host_if_msg msg;
4113 memset(&msg, 0, sizeof(struct host_if_msg));
4115 msg.id = HOST_IF_MSG_GET_TX_POWER;
4116 msg.vif = vif;
4118 ret = wilc_enqueue_cmd(&msg);
4119 if (ret)
4120 netdev_err(vif->ndev, "Failed to get TX PWR\n");
4122 wait_for_completion(&hif_wait_response);
4123 *tx_power = msg.body.tx_power.tx_pwr;
4125 return ret;