2 * Copyright (C) 2014 Spreadtrum Communications Inc.
4 * Authors:<jinglong.chen@spreadtrum.com>
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include "wlan_common.h"
20 #include "wlan_cfg80211.h"
21 #define CMD_WAIT_TIMEOUT (3000)
22 #define CMD_ITEM(CMD) { CMD, (#CMD) }
28 static cmd_t g_cmd_table[] = {
29 CMD_ITEM(WIFI_CMD_GET_MODE),
30 CMD_ITEM(WIFI_CMD_GET_RSSI),
31 CMD_ITEM(WIFI_CMD_GET_TXRATE_TXFAILED),
32 CMD_ITEM(WIFI_CMD_SET_SCAN),
33 CMD_ITEM(WIFI_CMD_SET_AUTH_TYPE),
34 CMD_ITEM(WIFI_CMD_SET_WPA_VERSION),
35 CMD_ITEM(WIFI_CMD_SET_PAIRWISE_CIPHER),
36 CMD_ITEM(WIFI_CMD_SET_GROUP_CIPHER),
37 CMD_ITEM(WIFI_CMD_SET_AKM_SUITE),
38 CMD_ITEM(WIFI_CMD_SET_CHANNEL),
39 CMD_ITEM(WIFI_CMD_SET_BSSID),
40 CMD_ITEM(WIFI_CMD_SET_ESSID),
41 CMD_ITEM(WIFI_CMD_KEY_ADD),
42 CMD_ITEM(WIFI_CMD_KEY_DEL),
43 CMD_ITEM(WIFI_CMD_KEY_SET),
44 CMD_ITEM(WIFI_CMD_SET_DISCONNECT),
45 CMD_ITEM(WIFI_CMD_SET_RTS_THRESHOLD),
46 CMD_ITEM(WIFI_CMD_SET_FRAG_THRESHOLD),
47 CMD_ITEM(WIFI_CMD_SET_PMKSA),
48 CMD_ITEM(WIFI_CMD_DEL_PMKSA),
49 CMD_ITEM(WIFI_CMD_FLUSH_PMKSA),
50 CMD_ITEM(WIFI_CMD_SET_DEV_OPEN),
51 CMD_ITEM(WIFI_CMD_SET_DEV_CLOSE),
52 CMD_ITEM(WIFI_CMD_SET_PSK),
53 CMD_ITEM(WIFI_CMD_START_BEACON),
54 CMD_ITEM(WIFI_CMD_SET_WPS_IE),
55 CMD_ITEM(WIFI_CMD_TX_MGMT),
56 CMD_ITEM(WIFI_CMD_REMAIN_CHAN),
57 CMD_ITEM(WIFI_CMD_CANCEL_REMAIN_CHAN),
58 CMD_ITEM(WIFI_CMD_P2P_IE),
59 CMD_ITEM(WIFI_CMD_CHANGE_BEACON),
60 CMD_ITEM(WIFI_CMD_REGISTER_FRAME),
61 CMD_ITEM(WIFI_CMD_NPI_MSG),
62 CMD_ITEM(WIFI_CMD_SET_FT_IE),
63 CMD_ITEM(WIFI_EVENT_CONNECT),
64 CMD_ITEM(WIFI_EVENT_DISCONNECT),
65 CMD_ITEM(WIFI_EVENT_SCANDONE),
66 CMD_ITEM(WIFI_EVENT_MGMT_DEAUTH),
67 CMD_ITEM(WIFI_EVENT_MGMT_DISASSOC),
68 CMD_ITEM(WIFI_EVENT_REMAIN_ON_CHAN_EXPIRED),
69 CMD_ITEM(WIFI_EVENT_NEW_STATION),
70 CMD_ITEM(WIFI_EVENT_REPORT_FRAME),
71 CMD_ITEM(WIFI_EVENT_CONNECT_AP),
72 CMD_ITEM(WIFI_CMD_ASSERT),
73 CMD_ITEM(WIFI_EVENT_SDIO_SEQ_NUM),
74 CMD_ITEM(WIFI_CMD_MAX),
75 CMD_ITEM(WIFI_EVENT_REPORT_SCAN_FRAME),
76 CMD_ITEM(WIFI_CMD_SLEEP),
77 CMD_ITEM(WIFI_CMD_GET_IP),
78 CMD_ITEM(WIFI_EVENT_REPORT_MIC_FAIL),
79 CMD_ITEM(WIFI_CMD_REQ_LTE_CONCUR),
80 CMD_ITEM(WIFI_CMD_SCAN_NOR_CHANNELS),
81 CMD_ITEM(WIFI_EVENT_REPORT_CQM_RSSI_LOW),
82 CMD_ITEM(WIFI_EVENT_REPORT_CQM_RSSI_HIGH),
83 CMD_ITEM(WIFI_EVENT_REPORT_CQM_RSSI_LOSS_BEACON),
84 CMD_ITEM(WIFI_EVENT_MLME_TX_STATUS),
85 CMD_ITEM(WIFI_EVENT_REPORT_VERSION),
88 char *get_cmd_name(int id)
91 int id_num = sizeof(g_cmd_table) / sizeof(cmd_t);
92 for (i = 0; i < id_num; i++) {
93 if (id == g_cmd_table[i].id) {
94 return g_cmd_table[i].cmd;
100 #define WLAN_CMD_MEM_LEN (8 * 1024)
101 int wlan_cmd_init(void)
103 wlan_cmd_t *cmd = &(g_wlan.cmd);
104 cmd->mem = kmalloc(WLAN_CMD_MEM_LEN, GFP_KERNEL);
105 atomic_set(&(cmd->refcnt), 0);
106 mutex_init(&(cmd->cmd_lock));
107 mutex_init(&cmd->mem_lock);
108 init_waitqueue_head(&(cmd->waitQ));
113 int wlan_cmd_deinit(void)
115 wlan_cmd_t *cmd = &(g_wlan.cmd);
117 unsigned long timeout;
119 if (NULL != cmd->mem) {
125 wake_up(&cmd->waitQ);
126 timeout = jiffies + msecs_to_jiffies(3000);
127 while (atomic_read(&(cmd->refcnt)) > 0) {
128 if (time_after(jiffies, timeout)) {
129 printkd("[%s][wait cmd lock timeout]\n", __func__);
132 usleep_range(2000, 2500);
134 mutex_destroy(&(cmd->cmd_lock));
135 mutex_destroy(&(cmd->mem_lock));
136 printkd("[%s][exit]\n", __func__);
141 int wlan_cmd_lock(wlan_cmd_t *cmd)
143 if (1 == g_wlan.sync.exit)
145 atomic_inc(&(cmd->refcnt));
146 mutex_lock(&(cmd->cmd_lock));
147 if (1 == g_wlan.sync.exit)
151 printkd("[%s][ERROR]\n", __func__);
155 int wlan_cmd_unlock(wlan_cmd_t *cmd)
157 mutex_unlock(&(cmd->cmd_lock));
158 atomic_dec(&(cmd->refcnt));
162 static inline void wlan_cmd_clean(void)
164 wlan_cmd_t *cmd = &g_wlan.cmd;
166 mutex_lock(&cmd->mem_lock);
168 msg = (r_msg_hdr_t *) cmd->mem;
169 printke("%s drop msg [%d][%s][%d]\n",
171 get_cmd_name(msg->subtype), msg->len);
174 mutex_unlock(&cmd->mem_lock);
177 int wlan_cmd_send_to_ic(unsigned char vif_id, unsigned char *data, int len,
181 tx_msg_t msg = { 0 };
182 msg_q_t *msg_q = &(g_wlan.netif[vif_id].msg_q[0]);
183 wlan_cmd_t *cmd = &(g_wlan.cmd);
185 if (NULL == cmd->mem) {
186 printkd("[SEND_CMD][%d][%s][ERR][CMD MEM NULL]\n", vif_id,
187 get_cmd_name(subtype));
190 msg.hdr.mode = vif_id;
191 msg.hdr.type = HOST_SC2331_CMD;
192 msg.hdr.subtype = subtype;
193 if ((len == 0) || (data == NULL)) {
196 msg.slice[0].data = NULL;
197 msg.slice[0].len = 0;
200 msg.slice[0].data = data;
201 msg.slice[0].len = len;
204 ret = msg_q_in(msg_q, &msg);
206 printkd("[SEND_CMD][%d][%s][ERR][MSG_Q NULL]\n", vif_id,
207 get_cmd_name(subtype));
210 printkd("[SEND_CMD][%d][%s]\n", vif_id, get_cmd_name(subtype));
211 g_wlan.wlan_core.need_tx++;
216 int wlan_timeout_recv_rsp(unsigned char *r_buf, unsigned short *r_len,
217 unsigned int timeout)
221 wlan_cmd_t *cmd = &(g_wlan.cmd);
223 ret = wait_event_timeout(cmd->waitQ, ((1 == cmd->wakeup)
224 || (1 == g_wlan.sync.exit)),
225 msecs_to_jiffies(timeout));
227 printke("[%s][%d][err]\n", __func__, __LINE__);
231 if (1 == g_wlan.sync.exit)
233 mutex_lock(&cmd->mem_lock);
235 msg = (r_msg_hdr_t *) (cmd->mem);
236 if (*r_len < msg->len) {
237 printke("[%s][%d][err]\n", __func__, __LINE__);
241 memcpy(r_buf, cmd->mem, sizeof(r_msg_hdr_t) + msg->len);
242 mutex_unlock(&cmd->mem_lock);
246 int wlan_cmd_send_recv(unsigned char vif_id, unsigned char *pData, int len,
247 int subtype, int timeout)
252 struct wlan_cmd_rsp_state_code *state;
253 wlan_cmd_t *cmd = &(g_wlan.cmd);
254 unsigned char r_buf[sizeof(r_msg_hdr_t) +
255 sizeof(struct wlan_cmd_rsp_state_code)] = { 0 };
256 unsigned short r_len = sizeof(struct wlan_cmd_rsp_state_code);
258 msg = (r_msg_hdr_t *) (&r_buf[0]);
259 ret = wlan_cmd_lock(cmd);
262 if ((NULL == pData) || (0 == len))
263 ret = wlan_cmd_send_to_ic(vif_id, NULL, 0, subtype);
265 ret = wlan_cmd_send_to_ic(vif_id, pData, len, subtype);
268 wlan_cmd_unlock(cmd);
272 ret = wlan_timeout_recv_rsp(r_buf, &r_len, timeout);
274 printke("[SEND_CMD %s %d ERROR][rsp timeout]\n",
275 get_cmd_name(subtype), vif_id);
278 if ((SC2331_HOST_RSP != msg->type) || (subtype != msg->subtype)) {
279 printke("[SEND_CMD %s %d ERROR][rsp match %s]\n",
280 get_cmd_name(subtype), vif_id,
281 get_cmd_name(msg->subtype));
284 wlan_cmd_unlock(cmd);
286 state = (struct wlan_cmd_rsp_state_code *)(&r_buf[sizeof(r_msg_hdr_t)]);
287 if (WIFI_CMD_SET_SCAN == subtype)
291 if (2 == g_wlan.sync.cp2_status)
296 int wlan_cmd_start_ap(unsigned char vif_id, unsigned char *beacon,
300 unsigned short dataLen;
301 struct wlan_cmd_beacon_t *beacon_ptr;
302 dataLen = sizeof(struct wlan_cmd_beacon_t) + len;
303 beacon_ptr = kmalloc(dataLen, GFP_KERNEL);
304 beacon_ptr->len = len;
305 memcpy(beacon_ptr->value, beacon, len);
307 wlan_cmd_send_recv(vif_id, (unsigned char *)beacon_ptr, dataLen,
308 WIFI_CMD_START_BEACON, CMD_WAIT_TIMEOUT);
312 int wlan_cmd_disassoc(unsigned char vif_id, const unsigned char *mac_addr,
313 unsigned short reason_code)
316 struct wlan_cmd_disassoc *ptr = NULL;
318 dataLen = sizeof(struct wlan_cmd_disassoc);
319 ptr = kzalloc(dataLen, GFP_KERNEL);
320 if (NULL != mac_addr)
321 memcpy(&(ptr->mac[0]), mac_addr, 6);
322 ptr->reason_code = reason_code;
324 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
325 WIFI_CMD_DISASSOC, CMD_WAIT_TIMEOUT);
330 int wlan_cmd_register_frame(unsigned char vif_id,
331 struct wlan_cmd_register_frame_t *data)
334 struct wlan_cmd_register_frame_t *ptr;
335 unsigned short dataLen;
336 dataLen = sizeof(struct wlan_cmd_register_frame_t);
337 ptr = kmalloc(dataLen, GFP_KERNEL);
338 memcpy((unsigned char *)ptr, (unsigned char *)(data), dataLen);
340 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
341 WIFI_CMD_REGISTER_FRAME, CMD_WAIT_TIMEOUT);
345 int wlan_cmd_set_p2p_ie(unsigned char vif_id, u8 type, const u8 *ie, u16 len)
347 struct wlan_cmd_p2p_ie_t *p2p_ptr;
349 unsigned short dataLen;
351 if (type != P2P_ASSOC_IE && type != P2P_BEACON_IE &&
352 type != P2P_PROBERESP_IE && type != P2P_ASSOCRESP_IE &&
353 type != P2P_BEACON_IE_HEAD && type != P2P_BEACON_IE_TAIL) {
354 printke("%s wrong ie type is %d\n", __func__, type);
357 printkd("%s type:%d ie_len:%d\n", __func__, type, len);
358 dataLen = sizeof(struct wlan_cmd_p2p_ie_t) + len;
359 p2p_ptr = kmalloc(dataLen, GFP_KERNEL);
360 p2p_ptr->type = type;
362 memcpy(p2p_ptr->value, ie, len);
364 wlan_cmd_send_recv(vif_id, (unsigned char *)p2p_ptr, dataLen,
365 WIFI_CMD_P2P_IE, CMD_WAIT_TIMEOUT);
369 int wlan_cmd_set_ft_ie(unsigned char vif_id, const unsigned char *ies,
372 unsigned char *ptr = NULL;
373 unsigned short dataLen = len + 2;
375 ptr = kmalloc(dataLen, GFP_KERNEL);
376 *((unsigned short *)ptr) = len;
377 memcpy(ptr + 2, ies, len);
379 hex_dump("ftie:", strlen("ftie:"), ptr, dataLen);
380 return wlan_cmd_send_recv(vif_id, ptr, dataLen, WIFI_CMD_SET_FT_IE,
384 int wlan_cmd_set_tx_mgmt(unsigned char vif_id,
385 struct ieee80211_channel *channel,
386 u8 dont_wait_for_ack, unsigned int wait,
387 u64 *cookie, const unsigned char *mac, size_t mac_len)
389 unsigned short dataLen;
390 struct wlan_cmd_mgmt_tx_t *mgmt_tx;
392 unsigned char send_chan;
394 dataLen = sizeof(struct wlan_cmd_mgmt_tx_t) + mac_len;
395 mgmt_tx = kmalloc(dataLen, GFP_KERNEL);
396 send_chan = ieee80211_frequency_to_channel(channel->center_freq);
398 mgmt_tx->chan = send_chan;
399 mgmt_tx->dont_wait_for_ack = dont_wait_for_ack;
400 mgmt_tx->wait = wait;
401 mgmt_tx->cookie = *cookie;
402 mgmt_tx->len = mac_len;
403 memcpy(mgmt_tx->value, mac, mac_len);
405 wlan_cmd_send_recv(vif_id, (unsigned char *)mgmt_tx, dataLen,
406 WIFI_CMD_TX_MGMT, CMD_WAIT_TIMEOUT);
410 int wlan_cmd_remain_chan(unsigned char vif_id,
411 struct ieee80211_channel *channel,
412 enum nl80211_channel_type channel_type,
413 unsigned int duration, u64 *cookie)
416 unsigned short dataLen;
417 struct wlan_cmd_remain_chan_t *remain_chan;
419 dataLen = sizeof(struct wlan_cmd_remain_chan_t);
420 remain_chan = kmalloc(dataLen, GFP_KERNEL);
423 ieee80211_frequency_to_channel(channel->center_freq);;
424 remain_chan->chan_type = channel_type;
425 remain_chan->duraion = duration;
426 remain_chan->cookie = *cookie;
429 wlan_cmd_send_recv(vif_id, (unsigned char *)remain_chan, dataLen,
430 WIFI_CMD_REMAIN_CHAN, CMD_WAIT_TIMEOUT);
434 int wlan_cmd_cancel_remain_chan(unsigned char vif_id, u64 cookie)
438 unsigned short dataLen;
440 struct wlan_cmd_cancel_remain_chan_t *ptr;
442 dataLen = sizeof(struct wlan_cmd_cancel_remain_chan_t);
444 ptr = kmalloc(dataLen, GFP_KERNEL);
446 ptr->cookie = cookie;
449 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
450 WIFI_CMD_CANCEL_REMAIN_CHAN, CMD_WAIT_TIMEOUT);
454 int wlan_cmd_scan(unsigned char vif_id, const unsigned char *ssid,
455 const unsigned char *channels, int len)
458 struct wlan_cmd_scan *ptr = NULL;
461 u8 ch_num = channels[0] + 1;
463 dataLen = sizeof(struct wlan_cmd_scan) + len + ch_num;
464 psend = send = kmalloc(dataLen, GFP_KERNEL);
466 memcpy(send, channels, ch_num);
469 ptr = (struct wlan_cmd_scan *)send;
470 memcpy(ptr->ssid, ssid, len);
473 hex_dump("scan data ", 10, psend, dataLen);
474 wlan_cmd_send_recv(vif_id, (unsigned char *)psend, dataLen,
475 WIFI_CMD_SET_SCAN, CMD_WAIT_TIMEOUT);
479 int wlan_cmd_set_wpa_version(unsigned char vif_id, unsigned int wpa_version)
482 struct wlan_cmd_set_wpa_version *ptr;
484 dataLen = sizeof(struct wlan_cmd_set_wpa_version);
485 ptr = kmalloc(dataLen, GFP_KERNEL);
487 ptr->wpa_version = wpa_version;
489 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
490 WIFI_CMD_SET_WPA_VERSION, CMD_WAIT_TIMEOUT);
494 int wlan_cmd_set_auth_type(unsigned char vif_id, unsigned int type)
497 struct wlan_cmd_set_auth_type *ptr;
499 dataLen = sizeof(struct wlan_cmd_set_auth_type);
500 ptr = kmalloc(dataLen, GFP_KERNEL);
503 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
504 WIFI_CMD_SET_AUTH_TYPE, CMD_WAIT_TIMEOUT);
508 /* unicast cipher or group cipher */
509 int wlan_cmd_set_cipher(unsigned char vif_id, unsigned int cipher,
510 unsigned char cmd_id)
513 struct wlan_cmd_set_cipher *ptr;
515 dataLen = sizeof(struct wlan_cmd_set_cipher);
516 if ((cmd_id != WIFI_CMD_SET_PAIRWISE_CIPHER)
517 && (cmd_id != WIFI_CMD_SET_GROUP_CIPHER)) {
518 printkd("not support this type cipher \n");
521 ptr = kmalloc(dataLen, GFP_KERNEL);
522 ptr->cipher = cipher;
524 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, cmd_id,
530 int wlan_cmd_set_key_management(unsigned char vif_id, unsigned char key_mgmt)
533 struct wlan_cmd_set_key_management *ptr;
535 dataLen = sizeof(struct wlan_cmd_set_key_management);
536 ptr = kmalloc(dataLen, GFP_KERNEL);
537 ptr->key_mgmt = key_mgmt;
539 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
540 WIFI_CMD_SET_AKM_SUITE, CMD_WAIT_TIMEOUT);
544 int wlan_cmd_set_psk(unsigned char vif_id, const unsigned char *key,
545 unsigned int key_len)
548 struct wlan_cmd_set_psk *ptr;
550 dataLen = sizeof(struct wlan_cmd_set_psk) + key_len;
551 ptr = kmalloc(dataLen, GFP_KERNEL);
553 memcpy(ptr->key, key, key_len);
555 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
556 WIFI_CMD_SET_PSK, CMD_WAIT_TIMEOUT);
561 int wlan_cmd_set_channel(unsigned char vif_id, unsigned int channel)
564 struct wlan_cmd_set_channel *ptr;
566 dataLen = sizeof(struct wlan_cmd_set_channel);
567 ptr = kmalloc(dataLen, GFP_KERNEL);
568 ptr->channel = channel;
570 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
571 WIFI_CMD_SET_CHANNEL, CMD_WAIT_TIMEOUT);
575 int wlan_cmd_set_bssid(unsigned char vif_id, const unsigned char *addr)
578 struct wlan_cmd_set_bssid *ptr;
580 dataLen = sizeof(struct wlan_cmd_set_bssid);
581 ptr = kmalloc(dataLen, GFP_KERNEL);
582 memcpy(&(ptr->addr[0]), addr, 6);
584 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
585 WIFI_CMD_SET_BSSID, CMD_WAIT_TIMEOUT);
589 int wlan_cmd_get_ip(unsigned char vif_id, u8 *ip)
592 struct wlan_cmd_get_ip *ptr;
594 dataLen = sizeof(struct wlan_cmd_get_ip);
595 ptr = kmalloc(dataLen, GFP_KERNEL);
596 memcpy(&(ptr->ip[0]), ip, 4);
597 hex_dump("inetaddr ip", strlen("inetaddr ip"), ip, 4);
599 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
600 WIFI_CMD_GET_IP, CMD_WAIT_TIMEOUT);
604 int wlan_cmd_set_essid(unsigned char vif_id, const unsigned char *essid,
609 struct wlan_cmd_set_essid *ptr;
611 dataLen = sizeof(struct wlan_cmd_set_essid) + essid_len;
612 ptr = kmalloc(dataLen, GFP_KERNEL);
613 ptr->len = essid_len;
614 memcpy(ptr->essid, essid, essid_len);
616 return wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
617 WIFI_CMD_SET_ESSID, CMD_WAIT_TIMEOUT);
620 int wlan_cmd_req_lte_concur(unsigned char vif_id, const unsigned char *val,
624 ptr = kmalloc(len, GFP_KERNEL);
625 memcpy(ptr, val, len);
626 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, len,
627 WIFI_CMD_REQ_LTE_CONCUR, CMD_WAIT_TIMEOUT);
631 int wlan_cmd_pmksa(unsigned char vif_id, const unsigned char *bssid,
632 const unsigned char *pmkid, unsigned char type)
635 struct wlan_cmd_pmkid *cmd;
637 dataLen = sizeof(struct wlan_cmd_pmkid);
638 cmd = kmalloc(dataLen, GFP_KERNEL);
639 memset((unsigned char *)cmd, 0, dataLen);
641 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
643 memcpy(cmd->pmkid, pmkid, sizeof(cmd->pmkid));
645 wlan_cmd_send_recv(vif_id, (unsigned char *)cmd, dataLen, type,
650 int wlan_cmd_cmq_rssi(unsigned char vif_id,
651 s32 rssi_thold, u32 rssi_hyst, unsigned char type)
654 struct wlan_cmd_cqm_rssi *cmd;
656 dataLen = sizeof(struct wlan_cmd_cqm_rssi);
657 cmd = kmalloc(dataLen, GFP_KERNEL);
658 memset((char *)cmd, 0, dataLen);
660 cmd->rssih = rssi_thold;
661 cmd->rssil = rssi_hyst;
663 wlan_cmd_send_recv(vif_id, (unsigned char *)cmd, dataLen,
664 type, CMD_WAIT_TIMEOUT);
668 int wlan_cmd_disconnect(unsigned char vif_id, unsigned short reason_code)
672 struct wlan_cmd_disconnect *ptr;
674 dataLen = sizeof(struct wlan_cmd_disconnect);
675 ptr = kmalloc(dataLen, GFP_KERNEL);
676 ptr->reason_code = reason_code;
678 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
679 WIFI_CMD_SET_DISCONNECT, CMD_WAIT_TIMEOUT);
683 int wlan_cmd_add_key(unsigned char vif_id, const unsigned char *key_data,
684 unsigned char key_len, unsigned char pairwise,
685 unsigned char key_index, const unsigned char *key_seq,
686 unsigned char cypher_type, const unsigned char *pmac)
690 struct wlan_cmd_add_key *ptr;
692 dataLen = sizeof(struct wlan_cmd_add_key) + key_len;
693 ptr = kmalloc(dataLen, GFP_KERNEL);
694 memset(ptr, 0, dataLen);
696 ptr->cypher_type = cypher_type;
698 memcpy(ptr->keyseq, key_seq, 8);
699 ptr->key_index = key_index;
700 ptr->key_len = key_len;
702 memcpy(ptr->mac, pmac, 6);
703 ptr->pairwise = pairwise;
704 if (NULL != key_data)
705 memcpy(ptr->value, key_data, key_len);
707 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
708 WIFI_CMD_KEY_ADD, CMD_WAIT_TIMEOUT);
713 int wlan_cmd_del_key(unsigned char vif_id, unsigned short key_index,
714 const unsigned char *mac_addr)
717 struct wlan_cmd_del_key *ptr = NULL;
719 dataLen = sizeof(struct wlan_cmd_del_key);
720 ptr = kmalloc(dataLen, GFP_KERNEL);
721 memset(ptr, 0, dataLen);
722 ptr->key_index = key_index;
723 if (NULL != mac_addr)
724 memcpy(&(ptr->mac[0]), mac_addr, 6);
726 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
727 WIFI_CMD_KEY_DEL, CMD_WAIT_TIMEOUT);
732 int wlan_cmd_set_key(unsigned char vif_id, unsigned char key_index)
736 struct wlan_cmd_set_key *ptr;
738 dataLen = sizeof(struct wlan_cmd_set_key);
739 ptr = kmalloc(dataLen, GFP_KERNEL);
740 ptr->key_index = key_index;
742 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
743 WIFI_CMD_KEY_SET, CMD_WAIT_TIMEOUT);
748 int wlan_cmd_set_rts(unsigned char vif_id, unsigned short rts_threshold)
751 struct wlan_cmd_set_rts *ptr;
752 dataLen = sizeof(struct wlan_cmd_set_rts);
753 ptr = kmalloc(dataLen, GFP_KERNEL);
754 ptr->threshold = rts_threshold;
756 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
757 WIFI_CMD_SET_RTS_THRESHOLD, CMD_WAIT_TIMEOUT);
762 int wlan_cmd_set_frag(unsigned char vif_id, unsigned short frag_threshold)
764 struct wlan_cmd_set_frag *frag;
766 frag = kmalloc(sizeof(struct wlan_cmd_set_frag), GFP_KERNEL);
767 frag->frag = frag_threshold;
769 wlan_cmd_send_recv(vif_id, (unsigned char *)frag,
770 sizeof(struct wlan_cmd_set_frag),
771 WIFI_CMD_SET_FRAG_THRESHOLD, CMD_WAIT_TIMEOUT);
776 int wlan_cmd_set_wps_ie(unsigned char vif_id, unsigned char type,
777 const unsigned char *ie, unsigned char len)
779 struct wlan_cmd_wps_ie *wps_ptr = NULL;
781 wps_ptr = kmalloc(sizeof(struct wlan_cmd_wps_ie) + len, GFP_KERNEL);
782 wps_ptr->type = type;
784 memcpy(wps_ptr->value, ie, len);
786 wlan_cmd_send_recv(vif_id, (unsigned char *)wps_ptr,
787 sizeof(struct wlan_cmd_wps_ie) + len,
788 WIFI_CMD_SET_WPS_IE, CMD_WAIT_TIMEOUT);
793 int wlan_cmd_update_ft_ies(unsigned char vif_id,
794 struct cfg80211_update_ft_ies_params *ft_ies)
797 struct wlan_cmd_ft_ies_params *ptr;
798 dataLen = sizeof(struct wlan_cmd_ft_ies_params) + ft_ies->ie_len;
799 ptr = kmalloc(dataLen, GFP_KERNEL);
802 ptr->md = ft_ies->md;
803 ptr->ie_len = ft_ies->ie_len;
804 memcpy(&(ptr->ie[0]), ft_ies->ie, ft_ies->ie_len);
805 hex_dump("update_ft_ie:", strlen("update_ft_ie:"), (unsigned char *)ptr,
808 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
809 WIFI_CMD_UPDATE_FT_IE, CMD_WAIT_TIMEOUT);
813 int wlan_cmd_mac_open(unsigned char vif_id, unsigned char mode,
814 unsigned char *mac_addr)
817 static int sync_flag = -1;
818 struct wlan_cmd_mac_open *open;
819 if (-1 == sync_flag) {
820 g_wlan.hw.tx_cnt = 0;
821 g_wlan.hw.rx_cnt = 0;
822 g_wlan.hw.rx_record = 0;
825 open = kmalloc(sizeof(struct wlan_cmd_mac_open), GFP_KERNEL);
826 memset((unsigned char *)open, 0, sizeof(struct wlan_cmd_mac_open));
828 if (NULL != mac_addr)
829 memcpy((unsigned char *)(&(open->mac[0])), mac_addr, 6);
832 wlan_cmd_send_recv(vif_id, (unsigned char *)open,
833 sizeof(struct wlan_cmd_mac_open),
834 WIFI_CMD_SET_DEV_OPEN, 8000);
838 int wlan_cmd_mac_close(unsigned char vif_id, unsigned char mode)
840 struct wlan_cmd_mac_close *close;
841 close = kmalloc(sizeof(struct wlan_cmd_mac_close), GFP_KERNEL);
844 wlan_cmd_send_recv(vif_id, (unsigned char *)(close),
845 sizeof(struct wlan_cmd_mac_close),
846 WIFI_CMD_SET_DEV_CLOSE, CMD_WAIT_TIMEOUT);
850 int wlan_cmd_assert(unsigned char vif_id, unsigned int reason_code)
853 struct wlan_cmd_assert_t *assert_cmd = NULL;
854 unsigned int dataLen = sizeof(struct wlan_cmd_assert_t);
855 assert_cmd = kmalloc(sizeof(struct wlan_cmd_assert_t), GFP_KERNEL);
856 assert_cmd->reason_code = reason_code;
857 assert_cmd->tx_cnt = g_wlan.hw.tx_cnt;
858 assert_cmd->rx_cnt = g_wlan.hw.rx_cnt;
859 wlan_cmd_send_to_ic(vif_id, (unsigned char *)(assert_cmd), dataLen,
864 #ifdef CONFIG_MACH_SAMSUNG
865 int wlan_cmd_set_cap(unsigned int cap)
867 #define WLNPI_CMD_SET_WLAN_CAP (40)
869 unsigned char r_buf[512] = { 0 };
870 unsigned short r_len = 0;
871 struct npi_cmd_hdr *msg;
873 unsigned char s_buff[8];
875 msg = (struct npi_cmd_hdr *)s_buff;
876 msg->type = HOST_TO_MARLIN_CMD;
877 msg->subtype = WLNPI_CMD_SET_WLAN_CAP;
878 msg->len = 4; /*sizeof(unsigned int) */
879 s_len = msg->len + sizeof(struct npi_cmd_hdr);
880 memcpy(s_buff + sizeof(struct npi_cmd_hdr), &cap,
881 sizeof(unsigned int));
882 ret = wlan_cmd_npi_send_recv(s_buff, s_len,
884 printke("[Send wlan capability = 0x%x %s!]\n",
885 cap, ret ? "failed" : "success");
890 int wlan_cmd_set_psm_cap(void)
892 #define PSM_PATH "/opt/etc/.psm.info"
899 #define STA_GC_EN_SLEEP (0x3)
900 #define STA_GC_NO_SLEEP (0x0)
904 unsigned int flag = 0;
905 unsigned char file_data;
907 fp = filp_open(PSM_PATH, O_RDONLY, 0);
909 flag = STA_GC_EN_SLEEP;
916 vfs_read(fp, &file_data, sizeof(file_data), pos);
918 filp_close(fp, NULL);
921 if (simple_strtoul((char *)&file_data, NULL, 10))
922 flag = STA_GC_EN_SLEEP;
924 flag = STA_GC_NO_SLEEP;
926 printke("[%s psm is:%s]\n", __func__,
927 flag ? "normal mode" : "rf mode");
929 return wlan_cmd_set_cap(flag);
933 int wlan_cmd_sleep(int ops)
935 unsigned char *ops_code;
936 ops_code = (unsigned char *)kmalloc(4, GFP_KERNEL);
937 memcpy(ops_code, (unsigned char *)(&ops), 4);
938 wlan_cmd_send_to_ic(0, ops_code, 4, WIFI_CMD_SLEEP);
942 int wlan_cmd_get_rssi(unsigned char vif_id, unsigned char *signal,
943 unsigned char *noise)
948 wlan_cmd_t *cmd = &(g_wlan.cmd);
949 unsigned char r_buf[sizeof(r_msg_hdr_t) + 8] = { 0 };
950 unsigned short r_len = 8;
951 msg = (r_msg_hdr_t *) (&r_buf[0]);
952 ret = wlan_cmd_lock(cmd);
955 ret = wlan_cmd_send_to_ic(vif_id, NULL, 0, WIFI_CMD_GET_RSSI);
956 ret = wlan_timeout_recv_rsp(r_buf, &r_len, CMD_WAIT_TIMEOUT);
958 printke("[SEND_CMD %s %d ERROR][rsp timeout]\n",
959 get_cmd_name(WIFI_CMD_GET_RSSI), vif_id);
962 if ((SC2331_HOST_RSP != msg->type)
963 || (WIFI_CMD_GET_RSSI != msg->subtype)) {
964 printke("[SEND_CMD %s %d ERROR][rsp match %s]\n",
965 get_cmd_name(WIFI_CMD_GET_RSSI), vif_id,
966 get_cmd_name(msg->subtype));
969 rssi = (int *)(&r_buf[sizeof(r_msg_hdr_t) + 4]);
970 *signal = (unsigned char)(le32_to_cpu(*rssi) | 0xffff0000);
972 (unsigned char)((le32_to_cpu(*rssi) | 0x0000ffff) >> 16);
974 wlan_cmd_unlock(cmd);
977 wlan_cmd_unlock(cmd);
981 int wlan_cmd_get_txrate_txfailed(unsigned char vif_id, unsigned int *rate,
982 unsigned int *failed)
986 wlan_cmd_t *cmd = &(g_wlan.cmd);
987 unsigned char r_buf[sizeof(r_msg_hdr_t) + 12] = { 0 };
988 unsigned short r_len = 12;
989 msg = (r_msg_hdr_t *) (&r_buf[0]);
990 ret = wlan_cmd_lock(cmd);
992 if (2 == g_wlan.sync.cp2_status)
997 wlan_cmd_send_to_ic(vif_id, NULL, 0, WIFI_CMD_GET_TXRATE_TXFAILED);
998 ret = wlan_timeout_recv_rsp(r_buf, &r_len, CMD_WAIT_TIMEOUT);
1000 printke("[SEND_CMD %s %d ERROR][rsp timeout]\n",
1001 get_cmd_name(WIFI_CMD_GET_TXRATE_TXFAILED), vif_id);
1004 if ((SC2331_HOST_RSP != msg->type)
1005 || (WIFI_CMD_GET_TXRATE_TXFAILED != msg->subtype)) {
1006 printke("[SEND_CMD %s %d ERROR][rsp match %s]\n",
1007 get_cmd_name(WIFI_CMD_GET_TXRATE_TXFAILED), vif_id,
1008 get_cmd_name(msg->subtype));
1011 memcpy((unsigned char *)rate, &r_buf[sizeof(r_msg_hdr_t) + 4],
1013 memcpy((unsigned char *)failed, &r_buf[sizeof(r_msg_hdr_t) + 8],
1016 wlan_cmd_unlock(cmd);
1019 wlan_cmd_unlock(cmd);
1020 if (2 == g_wlan.sync.cp2_status)
1025 int wlan_cmd_set_regdom(unsigned char vif_id, unsigned char *regdom,
1029 wlan_ieee80211_regdomain *ptr;
1032 ptr = kmalloc(dataLen, GFP_KERNEL);
1033 memcpy(ptr, regdom, dataLen);
1035 wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen,
1036 WIFI_CMD_SCAN_NOR_CHANNELS, CMD_WAIT_TIMEOUT);
1040 int wlan_cmd_npi_send_recv(unsigned char *s_buf, unsigned short s_len,
1041 unsigned char *r_buf, unsigned short *r_len)
1045 wlan_cmd_t *cmd = &(g_wlan.cmd);
1046 unsigned char *s_data = NULL;
1048 s_data = kmalloc(s_len, GFP_KERNEL);
1049 memcpy(s_data, s_buf, s_len);
1051 ret = wlan_cmd_lock(cmd);
1054 ret = wlan_cmd_send_to_ic(0, s_data, s_len, WIFI_CMD_NPI_MSG);
1055 ret = wait_event_timeout(cmd->waitQ, ((1 == cmd->wakeup)
1056 || (1 == g_wlan.sync.exit)),
1057 msecs_to_jiffies(5000));
1060 printke("%s(), wait timeout\n", __func__);
1063 msg = (r_msg_hdr_t *) cmd->mem;
1064 if ((SC2331_HOST_RSP == msg->type)
1065 && (WIFI_CMD_NPI_MSG == msg->subtype)) {
1067 memcpy(r_buf, (unsigned char *)(cmd->mem) + sizeof(r_msg_hdr_t),
1071 printke("[%s] rsp not match, rsp:[%s]\n",
1072 get_cmd_name(WIFI_CMD_NPI_MSG),
1073 get_cmd_name(msg->subtype));
1076 wlan_cmd_unlock(cmd);
1077 printkd("%s cmd ok!\n", get_cmd_name(WIFI_CMD_NPI_MSG));
1080 wlan_cmd_unlock(cmd);
1081 printke("[%s][ERROR]\n", get_cmd_name(WIFI_CMD_NPI_MSG));
1085 int wlan_rx_rsp_process(const unsigned char vif_id, r_msg_hdr_t *msg)
1087 wlan_cmd_t *cmd = &(g_wlan.cmd);
1089 if (mutex_trylock(&cmd->mem_lock)) {
1090 printkd("[RECV_RSP][%d][%s][%d][%d]\n", vif_id,
1091 get_cmd_name(msg->subtype), msg->len,
1092 *((int *)(msg + 1)));
1093 if (msg->len + sizeof(r_msg_hdr_t) > WLAN_CMD_MEM_LEN)
1095 memcpy(cmd->mem, (unsigned char *)msg,
1096 msg->len + sizeof(r_msg_hdr_t));
1098 wake_up(&cmd->waitQ);
1099 mutex_unlock(&cmd->mem_lock);
1101 printke("[RECV_RSP][%d][%s][%d], but drop it!\n",
1102 vif_id, get_cmd_name(msg->subtype), msg->len);
1108 int wlan_rx_event_process(const unsigned char vif_id, unsigned char event,
1109 unsigned char *pData, unsigned short len)
1111 if ((WIFI_EVENT_REPORT_SCAN_FRAME != event)
1112 && (WIFI_EVENT_SDIO_SEQ_NUM != event))
1113 printkd("[RECV_EVENT][%d][%s][%d]\n", vif_id,
1114 get_cmd_name(event), len);
1116 case WIFI_EVENT_CONNECT:
1117 cfg80211_report_connect_result(vif_id, pData, len);
1119 case WIFI_EVENT_DISCONNECT:
1120 cfg80211_report_disconnect_done(vif_id, pData, len);
1122 case WIFI_EVENT_SCANDONE:
1123 cfg80211_report_scan_done(vif_id, pData, len, false);
1125 case WIFI_EVENT_MGMT_DEAUTH:
1126 cfg80211_report_mgmt_deauth(vif_id, pData, len);
1128 case WIFI_EVENT_MGMT_DISASSOC:
1129 cfg80211_report_mgmt_disassoc(vif_id, pData, len);
1131 case WIFI_EVENT_REMAIN_ON_CHAN_EXPIRED:
1132 cfg80211_report_remain_on_channel_expired(vif_id, pData, len);
1134 case WIFI_EVENT_NEW_STATION:
1135 cfg80211_report_station(vif_id, pData, len);
1137 case WIFI_EVENT_REPORT_FRAME:
1138 cfg80211_report_frame(vif_id, pData, len);
1140 case WIFI_EVENT_CONNECT_AP:
1142 case WIFI_EVENT_SDIO_SEQ_NUM:
1144 case WIFI_EVENT_REPORT_SCAN_FRAME:
1145 cfg80211_report_scan_frame(vif_id, pData, len);
1147 case WIFI_EVENT_REPORT_MIC_FAIL:
1148 cfg80211_report_mic_failure(vif_id, pData, len);
1150 case WIFI_EVENT_REPORT_CQM_RSSI_LOW:
1151 cfg80211_report_cqm_low(vif_id, pData, len);
1153 case WIFI_EVENT_REPORT_CQM_RSSI_HIGH:
1154 cfg80211_report_cqm_high(vif_id, pData, len);
1156 case WIFI_EVENT_REPORT_CQM_RSSI_LOSS_BEACON:
1157 cfg80211_report_cqm_beacon_loss(vif_id, pData, len);
1159 case WIFI_EVENT_MLME_TX_STATUS:
1160 cfg80211_report_mlme_tx_status(vif_id, pData, len);
1162 case WIFI_EVENT_REPORT_VERSION:
1163 // cfg80211_report_version(vif_id, pData, len);
1171 int hex_dump(unsigned char *name, unsigned short nLen, unsigned char *pData,
1178 str = kmalloc(((len + 1) * 3 + nLen), GFP_KERNEL);
1179 memset(str, 0, (len + 1) * 3 + nLen);
1180 memcpy(str, name, nLen);
1181 if ((NULL == pData) || (0 == len)) {
1182 printke("%s\n", str);
1187 for (i = 0; i < len; i++) {
1188 ret = sprintf((str + nLen + p), "%02x ", *(pData + i));
1191 printke("%s\n\n", str);