diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/net/wireless/rda/rda_wlan/wlan_wid.c | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2 FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip |
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized.
Changes are basically to make it look like kernel structure.
Diffstat (limited to 'drivers/net/wireless/rda/rda_wlan/wlan_wid.c')
-rwxr-xr-x | drivers/net/wireless/rda/rda_wlan/wlan_wid.c | 1771 |
1 files changed, 1771 insertions, 0 deletions
diff --git a/drivers/net/wireless/rda/rda_wlan/wlan_wid.c b/drivers/net/wireless/rda/rda_wlan/wlan_wid.c new file mode 100755 index 00000000..e653accd --- /dev/null +++ b/drivers/net/wireless/rda/rda_wlan/wlan_wid.c @@ -0,0 +1,1771 @@ +#include "wlan_includes.h" + +void wlan_clean_wid_node(wlan_wid_packet_node * widNode) +{ + if (!widNode) + return; + + if (widNode->Buf) + kfree(widNode->Buf); + + if (widNode->RspBuf) + kfree(widNode->RspBuf); + + widNode->Buf = NULL; + widNode->BufLen = 0; + widNode->RspBuf = NULL; + widNode->RspLen = 0; + widNode->WidWaitOption = FALSE; + widNode->WidCmd = 0; + widNode->WidMsgId = 0; +} + +wlan_wid_packet_node *wlan_get_wid_node_in_freeQ(wlan_private * priv) +{ + wlan_wid_packet_node *widNode = NULL; + + ENTER(); + + if (priv->Suspend || priv->CardRemoved) + return NULL; + + spin_lock(&priv->WidLock); + if (!list_empty(&priv->WidFreeQ)) { + widNode = (wlan_wid_packet_node *) priv->WidFreeQ.next; + list_del(&widNode->List); + } + spin_unlock(&priv->WidLock); + + if (widNode) + wlan_clean_wid_node(widNode); + else + WLAN_ERRP("no free wid node \n"); + + LEAVE(); + return widNode; +} + +void wlan_put_wid_node_in_freeQ(wlan_private * priv, + wlan_wid_packet_node * widNode) +{ + if (!widNode || priv->CardRemoved) + return; + + ENTER(); + spin_lock(&priv->WidLock); + list_add_tail(&widNode->List, &priv->WidFreeQ); + spin_unlock(&priv->WidLock); + LEAVE(); +} + +int wlan_put_wid_node_in_pendingQ(wlan_private * priv, + wlan_wid_packet_node * widNode) +{ + int ret = 0; + wlan_tx_packet_node *txPacketNode = NULL; + + if (!widNode || priv->CardRemoved) + return -1; + + txPacketNode = (wlan_tx_packet_node *)kzalloc(sizeof(wlan_tx_packet_node), GFP_KERNEL); + if (!txPacketNode) { + WLAN_ERRP("no memory \n"); + return -ENOMEM; + } + + ENTER(); + + txPacketNode->type = WLAN_CMD; + txPacketNode->wid_node = widNode; + + //add to pending queue + widNode->WidWaitOption = FALSE; + + //add to pending queue + spin_lock(&priv->WidLock); + list_add_tail(&widNode->List, &priv->WidPendingQ); + spin_unlock(&priv->WidLock); + + //add to tx queue , send to card + spin_lock(&priv->TxLock); + list_add_tail(&txPacketNode->List, &priv->TxQueue); + spin_unlock(&priv->TxLock); + + complete(&priv->TxThread.comp); + ret = wait_event_timeout(widNode->WidDone, widNode->WidWaitOption, HZ * 5); + if (!ret) { + WLAN_ERRP("wait event timeout \n"); + priv->EventErrorCount++; + } else if (ret == -ERESTARTSYS) { + WLAN_ERRP("wait event was interrupt by signal \n"); + priv->EventErrorCount++; + } else { + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "wlan_put_wid_node_in_pendingQ received event success!! \n"); + priv->EventErrorCount=0; + } + + //delete from pending queue do not add to freeQ now because we should get wid response + spin_lock(&priv->WidLock); + widNode->BufLen = 0; + list_del(&widNode->List); + spin_unlock(&priv->WidLock); + +#ifdef CHECK_SDIO_STAUTS + if (!rda_combo_wifi_in_test_mode() && is_sdio_init_complete() && priv->EventErrorCount > WLAN_EVENT_MAX_ERR) { + WLAN_ERRP("Wait event timeout, push event : WLAN_EVENT_CHECK_SDIO \n"); + wlan_push_event(priv, WLAN_EVENT_CHECK_SDIO, priv, FALSE); + priv->EventErrorCount = 0; + priv->sdio_need_reset = 1; + } +#endif + + if (ret > 0) + ret = 0; + else if (!ret) + ret = -1; + + LEAVE(); + + return ret; +} + +//do not del wid node in this, after wid complete it will be delete +wlan_wid_packet_node *wlan_get_wid_node_in_pendingQ(wlan_private * priv) +{ + wlan_wid_packet_node *widNode = NULL; + + if (priv->Suspend || priv->CardRemoved) + return NULL; + + spin_lock(&priv->WidLock); + if (!list_empty(&priv->WidPendingQ)) { + widNode = (wlan_wid_packet_node *) priv->WidPendingQ.next; + } + spin_unlock(&priv->WidLock); + if (!widNode) + WLAN_ERRP("no wid pendingQ \n"); + return widNode; +} + +int wlan_alloc_wid_queue(wlan_private * priv) +{ + int ret = -1; + u32 i = 0; + wlan_wid_packet_node *widNode; + + for (i = 0; i < WLAN_CMD_QUEUE_NUM; i++) { + widNode = kzalloc(sizeof(wlan_wid_packet_node), GFP_KERNEL); + if (widNode) { + init_waitqueue_head(&widNode->WidDone); + spin_lock(&priv->WidLock); + list_add_tail(&widNode->List, &priv->WidFreeQ); + spin_unlock(&priv->WidLock); + ret = 0; + } else { + WLAN_ERRP("kzalloc wlan_wid_packet_node memory failed!\n"); + ret =-1; + break; + } + } + return ret; +} + +int wlan_release_wid_pending_queue(wlan_private * priv) +{ + wlan_wid_packet_node *widNode; + struct list_head *qe, *qen; + ENTER(); + + spin_lock(&priv->WidLock); + if (!list_empty(&priv->WidPendingQ)) { + list_for_each_safe(qe, qen, &priv->WidPendingQ) { + widNode = (wlan_wid_packet_node *) qe; + list_del(&widNode->List); + + wake_up(&widNode->WidDone); + } + } + spin_unlock(&priv->WidLock); + LEAVE(); + return 0; +} + +int wlan_free_wid_queue(wlan_private * priv) +{ + struct list_head *qe = NULL, *qen = NULL; + wlan_wid_packet_node *widNode; + + ENTER(); + + spin_lock(&priv->WidLock); + if (!list_empty(&priv->WidFreeQ)) { + list_for_each_safe(qe, qen, &priv->WidFreeQ) { + widNode = (wlan_wid_packet_node *) qe; + list_del(&widNode->List); + + if (widNode->Buf) + kfree(widNode->Buf); + widNode->Buf = NULL; + + if (widNode->RspBuf) + kfree(widNode->RspBuf); + widNode->RspBuf = NULL; + + kfree(widNode); + } + } + spin_unlock(&priv->WidLock); + LEAVE(); + return 0; +} + +int wlan_read_wid_rsp_polling(wlan_private * priv) +{ + u8 status; + int ret = 0; + u8 size_l = 0, size_h = 0; + u16 size = 0, rx_len = 0; + struct sk_buff *skb = NULL; + s16 count = 1000; + u8 *payload = NULL, rx_type = 0, msg_type = 0; + wlan_sdio_card *card = (wlan_sdio_card *) priv->card; + + ENTER(); + while (!is_sdio_init_complete() && !priv->CardRemoved && count--) { + sdio_claim_host(card->func); + ret = wlan_read_byte(priv, IF_SDIO_FUN1_INT_STAT, &status); + if (!ret) { + if (status & IF_SDIO_INT_AHB2SDIO) { + ret = wlan_read_byte(priv, IF_SDIO_AHB2SDIO_PKTLEN_L, &size_l); + if (ret) { + sdio_release_host(card->func); + break; + } + + ret = wlan_read_byte(priv, IF_SDIO_AHB2SDIO_PKTLEN_H, &size_h); + if (ret) { + sdio_release_host(card->func); + break; + } + + size = (size_l | ((size_h & 0x7f) << 8)) * 4; + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_NORM, "size = %d \n", size); + + skb = dev_alloc_skb(size + NET_IP_ALIGN + 3); + if (!skb) { + sdio_release_host(card->func); + ret = -1; + break; + } + + skb_reserve(skb, NET_IP_ALIGN); + skb_align(skb, 4); + + if (wlan_read_bytes(priv, IF_SDIO_FUN1_FIFO_RD, skb->data, size) + || priv->CardRemoved) { + dev_kfree_skb(skb); + sdio_release_host(card->func); + ret = -1; + goto out; + } + sdio_release_host(card->func); + skb_put(skb, size); + + payload = skb->data; + + rx_type = payload[1] & 0xf0; + rx_len = (u16) (payload[0] + ((payload[1] & 0x0f) << 8)); + if (rx_type == HOST_MSG_CONFIGRSP) { + msg_type = payload[2]; + if (msg_type == 'R') { + wlan_wid_response(priv, payload + 2, rx_len - 2); + dev_kfree_skb(skb); + ret = 0; + break; + } else if (msg_type == 'I') { + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_NORM, "received a mac status \n"); + } + } + dev_kfree_skb(skb); + } else + sdio_release_host(card->func); + } else + sdio_release_host(card->func); + udelay(10); + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_NORM, "IF_SDIO_FUN1_INT_STAT count:%d stats:0x%x\n", count, status); + } + + if (count < 0) { + ret = -1; + WLAN_ERRP("polling wid rsp failed \n"); + } else { + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_NORM, "polling wid rsp success \n"); + } + +out: + LEAVE(); + return ret; +} + +//return 0 success +int wlan_generic_get(wlan_private * priv, + u16 wid, u8 * val, u16 val_len, u32 * rspLen, + WID_TYPE_T type) +{ + int ret; + u8 wid_msg_id; + wlan_wid_packet_node *widNode = NULL; + u8 *wid_req = NULL; + u8 wid_req_len = 6; + + ENTER(); + + if(priv->sdio_need_reset == 1) + return -ENOMEM; + + widNode = wlan_get_wid_node_in_freeQ(priv); + + if (!widNode) + return -ENOMEM; + + wid_msg_id = priv->wid_msg_id++; + + widNode->Buf = kmalloc(wid_req_len + WID_HEADER_LEN, GFP_KERNEL); + widNode->BufLen = wid_req_len; + + widNode->RspBuf = kmalloc(val_len, GFP_KERNEL); + widNode->RspLen = val_len; + widNode->WidMsgId = wid_msg_id; + widNode->WidCmd = wid; + widNode->BufType = type; + + wid_req = widNode->Buf + WID_HEADER_LEN; + + wid_req[0] = 'Q'; + wid_req[1] = wid_msg_id; + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + wid_req[4] = (char)(wid & 0x00FF); + wid_req[5] = (char)((wid & 0xFF00) >> 8); + + ret = wlan_put_wid_node_in_pendingQ(priv, widNode); + + if (!ret) { + memcpy(val, widNode->RspBuf, widNode->RspLen); + if (rspLen) + *rspLen = widNode->RspLen; + } + + wlan_put_wid_node_in_freeQ(priv, widNode); + LEAVE(); + return ret; +} + +int wlan_generic_get_uchar(wlan_private * priv, u16 wid, u8 * val) +{ + int ret; + ENTER(); + + ret = wlan_generic_get(priv, wid, val, 1, NULL, WID_CHAR); + + LEAVE(); + return ret; +} + +int wlan_generic_get_ushort(wlan_private * priv, u16 wid, u8 * val) +{ + int ret; + ENTER(); + + ret = wlan_generic_get(priv, wid, val, 2, NULL, WID_SHORT); + + LEAVE(); + return ret; +} + +int wlan_generic_get_ulong(wlan_private * priv, u16 wid, u8 * val) +{ + int ret; + ENTER(); + + ret = wlan_generic_get(priv, wid, (u8 *) val, 4, NULL, WID_INT); + + LEAVE(); + return ret; +} + +int wlan_generic_get_str(wlan_private * priv, + u16 wid, u8 * val, u32 len, u32 * rspLen) +{ + int ret; + ENTER(); + + ret = wlan_generic_get(priv, wid, val, len, rspLen, WID_STR); + + LEAVE(); + return ret; +} + +//return 0 success +int wlan_send_wid_packet(wlan_private * priv, u8 * val, u16 val_len, + u8 wid_msg_id) +{ + int ret = 0; + wlan_wid_packet_node *widNode = NULL; + u8 *wid_req = NULL; + u16 wid_req_len = val_len; + + ENTER(); + + if(priv->sdio_need_reset == 1) + return -ENOMEM; + + widNode = wlan_get_wid_node_in_freeQ(priv); + if (!widNode) + return -ENOMEM; + + widNode->Buf = kmalloc(wid_req_len + WID_HEADER_LEN, GFP_KERNEL); + widNode->BufLen = wid_req_len; + + widNode->RspBuf = kmalloc(4, GFP_KERNEL); + widNode->RspLen = 4; + widNode->WidMsgId = wid_msg_id; + widNode->WidCmd = WID_STATUS; + widNode->BufType = WID_STR; + + wid_req = widNode->Buf + WID_HEADER_LEN; + memcpy(wid_req, val, val_len); + + ret = wlan_put_wid_node_in_pendingQ(priv, widNode); + //check wid status + if (!ret) { + if (widNode->RspBuf[0] != WID_STATUS_SUCCESS) + ret = -EINVAL; + } + + wlan_put_wid_node_in_freeQ(priv, widNode); + LEAVE(); + return ret; +} + +int wlan_generic_set(wlan_private * priv, + u16 wid, u8 * val, u16 val_len, WID_TYPE_T type) +{ + int ret; + u8 wid_msg_id; + wlan_wid_packet_node *widNode = NULL; + u8 *wid_req = NULL; + u8 wid_req_len = 7 + val_len; + + ENTER(); + + if(priv->sdio_need_reset == 1) + return -ENOMEM; + + widNode = wlan_get_wid_node_in_freeQ(priv); + if (!widNode) + return -ENOMEM; + + wid_msg_id = priv->wid_msg_id++; + + if(type == WID_BIN_DATA) + wid_req_len += 2; //1for length feild, 1 for crc + + widNode->Buf = kmalloc(wid_req_len + WID_HEADER_LEN, GFP_KERNEL); + widNode->BufLen = wid_req_len; + + widNode->RspBuf = kmalloc(4, GFP_KERNEL); + widNode->RspLen = 4; + widNode->WidMsgId = wid_msg_id; + widNode->WidCmd = wid; + widNode->BufType = type; + + wid_req = widNode->Buf + WID_HEADER_LEN; + + wid_req[0] = 'W'; + wid_req[1] = wid_msg_id; + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + wid_req[4] = (char)(wid & 0x00FF); + wid_req[5] = (char)((wid & 0xFF00) >> 8); + + if(type != WID_BIN_DATA){ + wid_req[6] = val_len; + memcpy(&wid_req[7], val, val_len); + }else{ + wid_req[6] = val_len & 0xff; + wid_req[7] = (val_len & 0xff00) >> 8; + memcpy(&wid_req[8], val, val_len); + } + + ret = wlan_put_wid_node_in_pendingQ(priv, widNode); + //check wid status + if (!ret) { + if (widNode->RspBuf[0] != WID_STATUS_SUCCESS) + ret = -EINVAL; + } + + wlan_put_wid_node_in_freeQ(priv, widNode); + LEAVE(); + return ret; +} + +int wlan_generic_set_uchar(wlan_private * priv, u16 wid, u8 val) +{ + int ret; + u8 tPara = val; + ENTER(); + + ret = wlan_generic_set(priv, wid, &tPara, 1, WID_CHAR); + + LEAVE(); + return ret; +} + +int wlan_generic_set_ushort(wlan_private * priv, u16 wid, u16 val) +{ + int ret; + u16 tPara = val; + ENTER(); + + ret = wlan_generic_set(priv, wid, (u8 *) & tPara, 2, WID_SHORT); + + LEAVE(); + return ret; +} + +int wlan_generic_set_ulong(wlan_private * priv, u16 wid, u32 val) +{ + int ret; + u32 tPara = val; + ENTER(); + + ret = wlan_generic_set(priv, wid, (u8 *) & tPara, 4, WID_INT); + + LEAVE(); + return ret; +} + +int wlan_generic_set_str(wlan_private * priv, u16 wid, u8 * val, u32 val_len) +{ + int ret; + ENTER(); + + ret = wlan_generic_set(priv, wid, val, val_len, WID_STR); + + LEAVE(); + return ret; +} + +int wlan_generic_set_bin(wlan_private * priv, u16 wid, u8 * val, u32 val_len) +{ + int ret; + ENTER(); + + ret = wlan_generic_set(priv, wid, val, val_len, WID_BIN_DATA); + + LEAVE(); + return ret; +} + +int wlan_set_core_init_patch(wlan_private * priv, const u32(*data)[2], u8 num) +{ + int ret, count = 0; + u8 wid_msg_id; + wlan_wid_packet_node *widNode = NULL; + u8 *wid_req = NULL, *p_wid_req; + u8 wid_req_len = 4 + 14 * num; + u16 wid = WID_STATUS; + + ENTER(); + + widNode = wlan_get_wid_node_in_freeQ(priv); + + if (!widNode) + return -ENOMEM; + + wid_msg_id = priv->wid_msg_id++; + + widNode->Buf = kmalloc(wid_req_len + WID_HEADER_LEN + 4, GFP_KERNEL); + widNode->BufLen = wid_req_len; + + widNode->RspBuf = kmalloc(4, GFP_KERNEL); + widNode->RspLen = 4; + widNode->WidMsgId = wid_msg_id; + widNode->WidCmd = wid; + widNode->BufType = WID_STR; + wid_req = widNode->Buf + WID_HEADER_LEN; + + wid_req[0] = 'W'; + wid_req[1] = wid_msg_id; + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + p_wid_req = wid_req + 4; + for (count = 0; count < num; count++) { + wid = WID_MEMORY_ADDRESS; + p_wid_req[0] = (char)(wid & 0x00FF); + p_wid_req[1] = (char)((wid & 0xFF00) >> 8); + + p_wid_req[2] = (char)4; + memcpy((u8 *) (p_wid_req + 3), (u8 *) (&data[count][0]), 4); + + wid = WID_MEMORY_ACCESS_32BIT; + p_wid_req[7] = (char)(wid & 0x00FF); + p_wid_req[8] = (char)((wid & 0xFF00) >> 8); + + p_wid_req[9] = (char)4; + memcpy((u8 *) (p_wid_req + 10), (u8 *) (&data[count][1]), 4); + p_wid_req += 14; + } + ret = wlan_put_wid_node_in_pendingQ(priv, widNode); + //check wid status + if (!ret) { + if (widNode->RspBuf[0] != WID_STATUS_SUCCESS) + ret = -EINVAL; + } + + wlan_put_wid_node_in_freeQ(priv, widNode); + + LEAVE(); + return ret; +} + +int wlan_set_core_patch(wlan_private * priv, const u8(*patch)[2], u8 num) +{ + int ret, count = 0; + u8 wid_msg_id; + wlan_wid_packet_node *widNode = NULL; + u8 *wid_req = NULL, *p_wid_req; + u8 wid_req_len = 4 + 8 * num; + u16 wid = WID_STATUS; + + ENTER(); + + widNode = wlan_get_wid_node_in_freeQ(priv); + + if (!widNode) + return -ENOMEM; + + wid_msg_id = priv->wid_msg_id++; + + widNode->Buf = kmalloc(wid_req_len + WID_HEADER_LEN + 4, GFP_KERNEL); + widNode->BufLen = wid_req_len; + + widNode->RspBuf = kmalloc(4, GFP_KERNEL); + widNode->RspLen = 4; + widNode->WidMsgId = wid_msg_id; + widNode->WidCmd = wid; + widNode->BufType = WID_STR; + wid_req = widNode->Buf + WID_HEADER_LEN; + + wid_req[0] = 'W'; + wid_req[1] = wid_msg_id; + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + p_wid_req = wid_req + 4; + + for (count = 0; count < num; count++) { + wid = WID_PHY_ACTIVE_REG; + p_wid_req[0] = (char)(wid & 0x00FF); + p_wid_req[1] = (char)((wid & 0xFF00) >> 8); + + p_wid_req[2] = (char)(0x01); + p_wid_req[3] = (char)patch[count][0]; + + wid = WID_PHY_ACTIVE_REG_VAL; + p_wid_req[4] = (char)(wid & 0x00FF); + p_wid_req[5] = (char)((wid & 0xFF00) >> 8); + + p_wid_req[6] = (char)(0x01); + p_wid_req[7] = (char)patch[count][1]; + p_wid_req += 8; + } + ret = wlan_put_wid_node_in_pendingQ(priv, widNode); + //check wid status + if (!ret) { + if (widNode->RspBuf[0] != WID_STATUS_SUCCESS) + ret = -EINVAL; + } + + wlan_put_wid_node_in_freeQ(priv, widNode); + + LEAVE(); + return ret; +} + +void wlan_wid_response(wlan_private * priv, u8 * wid_rsp, u16 wid_rsp_len) +{ + u16 rsp_len; + u16 rsp_wid; + u8 msg_id = 0; + u8 *payload = NULL, payload_len = 0; + struct list_head *qe, *qen; + wlan_wid_packet_node *widNode = NULL; + + if (wid_rsp[0] != 'R') { + WLAN_ERRP("wid_rsp[0] != 'R'\n"); + goto err; + } + + if (wid_rsp_len < 4) { + WLAN_ERRP("wid_rsp_len < 4\n"); + goto err; + } + + rsp_len = wid_rsp[2] | (wid_rsp[3] << 8); + if (wid_rsp_len != rsp_len) { + WLAN_ERRP("wid_rsp_len not match, %d != %d\n", wid_rsp_len, rsp_len); + goto err; + } + + if (wid_rsp_len < 7) { + WLAN_ERRP("wid_rsp_len < 7\n"); + goto err; + } + + msg_id = wid_rsp[1]; + rsp_wid = wid_rsp[4] | (wid_rsp[5] << 8); + payload_len = wid_rsp[6]; + payload = &wid_rsp[7]; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_DEBUG,"msg_id:%d rsp_wid:%d \n", msg_id, rsp_wid); + spin_lock(&priv->WidLock); + list_for_each_safe(qe, qen, &priv->WidPendingQ) { + widNode = (wlan_wid_packet_node *) qe; + //process wid write + if (rsp_wid == WID_STATUS) { + if (widNode->WidMsgId == msg_id) { + payload_len = widNode->RspLen > payload_len ? payload_len : widNode->RspLen; + memcpy(widNode->RspBuf, payload, payload_len); + widNode->WidWaitOption = TRUE; + wake_up(&widNode->WidDone); + if (is_sdio_init_complete()) + complete(&priv->widComp); + } + } else { //process wid query + if (widNode->WidMsgId == msg_id) { + rsp_len = widNode->BufLen > payload_len ? payload_len : widNode->BufLen; + memcpy(widNode->RspBuf, payload, rsp_len); + widNode->WidWaitOption = TRUE; + widNode->RspLen = (u32) rsp_len; + wake_up(&widNode->WidDone); + if (is_sdio_init_complete()) + complete(&priv->widComp); + } + } + } + spin_unlock(&priv->WidLock); + +err: + + return; +} + +int wlan_set_scan_timeout(wlan_private * priv) +{ + int ret; + char wid_req[24]; + u16 wid_req_len = 19; + u8 wid_msg_id = priv->wid_msg_id++; + u16 wid = 0; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "wlan_set_scan_timeout <<< \n"); + + wid = WID_SITE_SURVEY_SCAN_TIME; + + wid_req[0] = 'W'; + wid_req[1] = wid_msg_id; + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + wid_req[4] = (char)(wid & 0x00FF); + wid_req[5] = (char)((wid & 0xFF00) >> 8); + wid_req[6] = 2; + wid_req[7] = SCAN_TIME_AT_EACH_CHANNEL; //50 ms one channel + wid_req[8] = 0; + + wid = WID_ACTIVE_SCAN_TIME; + wid_req[9] = (char)(wid & 0x00FF); + wid_req[10] = (char)((wid & 0xFF00) >> 8); + wid_req[11] = 2; + wid_req[12] = SCAN_TIME_AT_EACH_CHANNEL; //50 ms one channel + wid_req[13] = 0; + + wid = WID_PASSIVE_SCAN_TIME; + wid_req[14] = (char)(wid & 0x00FF); + wid_req[15] = (char)((wid & 0xFF00) >> 8); + wid_req[16] = 2; + wid_req[17] = SCAN_TIME_AT_EACH_CHANNEL; //50 ms one channel + wid_req[18] = 0; + + ret = wlan_send_wid_packet(priv, wid_req, wid_req_len, wid_msg_id); + + return ret; +} + +int wlan_start_scan_enable_network_info(wlan_private * priv) +{ + int ret; + char wid_req[255], *pWid_req; + u16 wid_req_len = 16; + u16 wid; + u8 wid_msg_id = 0; + ENTER(); + + wid_msg_id = priv->wid_msg_id++; + + wid_req[0] = 'W'; + wid_req[1] = wid_msg_id; + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + wid = WID_SITE_SURVEY; + wid_req[4] = (char)(wid & 0x00FF); + wid_req[5] = (char)((wid & 0xFF00) >> 8); + + wid_req[6] = (char)(0x01); + wid_req[7] = (char)(0x01); + + wid = WID_START_SCAN_REQ; + wid_req[8] = (char)(wid & 0x00FF); + wid_req[9] = (char)((wid & 0xFF00) >> 8); + + wid_req[10] = (char)(0x01); + wid_req[11] = (char)(0x01); + + wid = WID_NETWORK_INFO_EN; + wid_req[12] = (char)(wid & 0x00FF); + wid_req[13] = (char)((wid & 0xFF00) >> 8); + + wid_req[14] = (char)(0x01); + wid_req[15] = (char)(0x01); // 0x01 scan network info + + wid_req_len = 16; + + if (priv->version == WLAN_VERSION_90_D || priv->version == WLAN_VERSION_90_E) { + int i = 0; + wid_req_len = wid_req_len; + pWid_req = &wid_req[wid_req_len]; + + while (i <= priv->scan_ssid_len) { + wid = WID_MEMORY_ADDRESS; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = 0x80 + i; + pWid_req[4] = 0x81; + pWid_req[5] = 0x10; + pWid_req[6] = 0x00; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ACCESS_32BIT; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = priv->scan_ssid[i + 0]; + pWid_req[4] = priv->scan_ssid[i + 1]; + pWid_req[5] = priv->scan_ssid[i + 2]; + pWid_req[6] = priv->scan_ssid[i + 3]; + wid_req_len += 7; + pWid_req += 7; + i += 4; + } + } else if (priv->version == WLAN_VERSION_91 || priv->version == WLAN_VERSION_91_E|| priv->version == WLAN_VERSION_91_F) { + pWid_req = &wid_req[wid_req_len]; + wid = WID_HIDE_SSID; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = priv->scan_ssid_len; + memcpy(pWid_req + 3, priv->scan_ssid, priv->scan_ssid_len); + wid_req_len += 3 + priv->scan_ssid_len; + pWid_req += 3 + priv->scan_ssid_len; + } + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_DEBUG, + "wid_req_len : %d ssid_len:%d \n", wid_req_len, + priv->scan_ssid_len); + + ret = wlan_send_wid_packet(priv, wid_req, wid_req_len, wid_msg_id); + if (ret) { + WLAN_ERRP("wlan_send_wid_packet failed!\n"); + } + LEAVE(); + return ret; +} + +int wlan_start_join(wlan_private * priv) +{ + int ret = 0; + char wid_req[255]; + u16 wid_req_len = 0; + u16 wid = 0; + u8 wid_msg_id = priv->wid_msg_id++; + u16 i = 0; + u8 key_str_len = 0; + u8 key_str[26 + 1], *key, *pWid_req; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_DEBUG, + "%s <<< mode:0x%x authtype:%d ssid:%s\n", __func__, + priv->imode, priv->authtype, priv->assoc_ssid); + + print_mac(priv->assoc_bssid); + + pWid_req = wid_req; + pWid_req[0] = 'W'; + pWid_req[1] = wid_msg_id; + wid_req_len = 4; + pWid_req += 4; + + wid = WID_802_11I_MODE; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 1; + if(priv->imode == 0x9 && (priv->version == WLAN_VERSION_91_E|| priv->version == WLAN_VERSION_91_F)){//huanglei add for wps + wid_req[3] = 0x49; + } + else + pWid_req[3] = (priv->imode == 0x05) ? 0x07 : priv->imode; //for wep104 need set imode 0x07 firmware problem + wid_req_len += 4; + pWid_req += 4; + + wid = WID_AUTH_TYPE; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 1; + pWid_req[3] = priv->authtype; + wid_req_len += 4; + pWid_req += 4; + + wid = WID_NETWORK_INFO_EN; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 1; + pWid_req[3] = 0; + wid_req_len += 4; + pWid_req += 4; + + wid = WID_CURRENT_TX_RATE; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 1; + pWid_req[3] = 1; + wid_req_len += 4; + pWid_req += 4; + + if ((priv->version == WLAN_VERSION_90_D) || (priv->version == WLAN_VERSION_90_E)) { + // bssid + wid = WID_MEMORY_ADDRESS; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = 0xec; + pWid_req[4] = 0x81; + pWid_req[5] = 0x10; + pWid_req[6] = 0x00; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ACCESS_32BIT; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = priv->assoc_bssid[0]; + pWid_req[4] = priv->assoc_bssid[1]; + pWid_req[5] = priv->assoc_bssid[2]; + pWid_req[6] = priv->assoc_bssid[3]; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ADDRESS; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = 0xf0; + pWid_req[4] = 0x81; + pWid_req[5] = 0x10; + pWid_req[6] = 0x00; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ACCESS_32BIT; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = priv->assoc_bssid[4]; + pWid_req[4] = priv->assoc_bssid[5]; + pWid_req[5] = 0; + pWid_req[6] = 0; + wid_req_len += 7; + pWid_req += 7; + } + + if ((priv->version == WLAN_VERSION_90_D) || (priv->version == WLAN_VERSION_90_E)) { + //huanglei add begin + wid = WID_MEMORY_ADDRESS; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = 0x04; + pWid_req[4] = 0x01; + pWid_req[5] = 0x00; + pWid_req[6] = 0x50; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ACCESS_16BIT; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 2; + pWid_req[3] = 0x1;//(cmax << 4) | (cmin) 00010001 + pWid_req[4] = 0x1; + wid_req_len += 5; + pWid_req += 5; + + wid = WID_MEMORY_ADDRESS; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = 0x08; + pWid_req[4] = 0x01; + pWid_req[5] = 0x00; + pWid_req[6] = 0x50; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ACCESS_16BIT; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 2; + pWid_req[3] = 0x1;//(cmax << 4) | (cmin) 00010001 + pWid_req[4] = 0x1; + wid_req_len += 5; + pWid_req += 5; + + wid = WID_MEMORY_ADDRESS; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = 0x0C; + pWid_req[4] = 0x01; + pWid_req[5] = 0x00; + pWid_req[6] = 0x50; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ACCESS_16BIT; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 2; + pWid_req[3] = 0x1;//(cmax << 4) | (cmin) 00010001 + pWid_req[4] = 0x1; + wid_req_len += 5; + pWid_req += 5; + + wid = WID_MEMORY_ADDRESS; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 4; + pWid_req[3] = 0x10; + pWid_req[4] = 0x01; + pWid_req[5] = 0x00; + pWid_req[6] = 0x50; + wid_req_len += 7; + pWid_req += 7; + + wid = WID_MEMORY_ACCESS_16BIT; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 2; + pWid_req[3] = 0x1;//(cmax << 4) | (cmin) 00010001 + pWid_req[4] = 0x1; + wid_req_len += 5; + pWid_req += 5; + //huanglei add end + } + + //bssid + wid = WID_BSSID; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 6; + memcpy(&pWid_req[3], priv->assoc_bssid, 6); + wid_req_len += 9; + pWid_req += 9; + + // ssid + wid = WID_SSID; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = priv->assoc_ssid_len; + memcpy(pWid_req + 3, priv->assoc_ssid, priv->assoc_ssid_len); + wid_req_len += 3 + priv->assoc_ssid_len; + pWid_req += 3 + priv->assoc_ssid_len; + + wid = WID_START_SCAN_REQ; + pWid_req[0] = (char)(wid & 0x00FF); + pWid_req[1] = (char)((wid & 0xFF00) >> 8); + pWid_req[2] = 1; + pWid_req[3] = 0; + wid_req_len += 4; + pWid_req += 4; + + + wid = WID_WEP_KEY_VALUE0; + //write wep key + if (priv->imode == 3 || priv->imode == 5) { + for (i = 0; i < 4; i++) { + key = priv->wep_keys[i].key; + + if (priv->wep_keys[i].len == 0) + continue; + + if (priv->wep_keys[i].len == KEY_LEN_WEP_40) { + sprintf(key_str, "%02x%02x%02x%02x%02x\n", + key[0], key[1], key[2], key[3], key[4]); + key_str_len = 10; + key_str[key_str_len] = '\0'; + } else if (priv->wep_keys[i].len == KEY_LEN_WEP_104) { + sprintf(key_str, "%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x" + "%02x%02x%02x\n", + key[0], key[1], key[2], key[3], key[4], + key[5], key[6], key[7], key[8], key[9], + key[10], key[11], key[12]); + key_str_len = 26; + key_str[key_str_len] = '\0'; + } else + continue; + + pWid_req[0] = (char)((wid + i) & 0x00FF); + pWid_req[1] = (char)(((wid + i) & 0xFF00) >> 8); + + pWid_req[2] = key_str_len; + memcpy(pWid_req + 3, key_str, key_str_len); + + pWid_req += 3 + key_str_len; + wid_req_len += 3 + key_str_len; + } + } + + + + wid_req[2] = (char)(wid_req_len & 0x00FF); + wid_req[3] = (char)((wid_req_len & 0xFF00) >> 8); + + ret = wlan_send_wid_packet(priv, wid_req, wid_req_len, wid_msg_id); + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_DEBUG, + "%s >>> ret = %d req len %d mod:0x%x auth_type:0x%x \n", + __func__, ret, wid_req_len, priv->imode, priv->authtype); + + return ret; +} + +int wlan_disconnect_silent(wlan_private * priv) +{ + int ret = 0; + char null_data[6]; + char wid_req[255], *pWid_req = NULL; + u16 wid_req_len = 0; + u16 wid = 0; + u8 wid_msg_id = priv->wid_msg_id++; + + memset(null_data, 0 , 6); + + wid_req[0] = 'W'; + wid_req[1] = wid_msg_id; + + wid_req_len += 4; + pWid_req = wid_req + 4; + + wid = WID_BSSID; + pWid_req[0] = (char)(wid&0x00FF); + pWid_req[1] = (char)((wid&0xFF00) >> 8); + pWid_req[2] = 6; + memcpy(&pWid_req[3], null_data, 6); + wid_req_len += 9; + pWid_req += 9; + + wid = WID_SSID; + pWid_req[0] = (char)(wid&0x00FF); + pWid_req[1] = (char)((wid&0xFF00) >> 8); + pWid_req[2] = 6; + memcpy(&pWid_req[3], null_data, 6); + wid_req_len += 9; + pWid_req += 9; + + wid_req[2] = (char)(wid_req_len&0x00FF); + wid_req[3] = (char)((wid_req_len&0xFF00) >> 8); + + ret = wlan_send_wid_packet(priv, wid_req, wid_req_len, wid_msg_id); + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_DEBUG, "%s >>> ret = %d \n", __func__, ret); + return ret; +} + +int wlan_set_txrate(wlan_private * priv, u8 mbps) +{ + int ret; + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "wlan_set_txrate <<< \n"); + ret = wlan_generic_set_uchar(priv, WID_CURRENT_TX_RATE, mbps); //O FOR AUTO 1FOR 1MBPS + + if ((priv->version == WLAN_VERSION_90_D) || (priv->version == WLAN_VERSION_90_E)) { + //huanglei add begin + ret = wlan_generic_set_ulong(priv, WID_MEMORY_ADDRESS, 0x50000104); + ret = wlan_generic_set_ushort(priv, WID_MEMORY_ACCESS_16BIT, 0x0101); + ret = wlan_generic_set_ulong(priv, WID_MEMORY_ADDRESS, 0x50000108); + ret = wlan_generic_set_ushort(priv, WID_MEMORY_ACCESS_16BIT, 0x0101); + ret = wlan_generic_set_ulong(priv, WID_MEMORY_ADDRESS, 0x5000010C); + ret = wlan_generic_set_ushort(priv, WID_MEMORY_ACCESS_16BIT, 0x0101); + ret = wlan_generic_set_ulong(priv, WID_MEMORY_ADDRESS, 0x50000110); + ret = wlan_generic_set_ushort(priv, WID_MEMORY_ACCESS_16BIT, 0x0101); + //huanglei add end + } + + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "wlan_set_txrate success >>> \n"); + +out: + return ret; +} + +int wlan_get_fw_ver(wlan_private * priv, u32 * fw_ver) +{ + int ret = wlan_generic_get_ulong(priv, WID_SYS_FW_VER, (u8 *) fw_ver); + + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Get FW_VER 0x%04x\n", *fw_ver); +out: + return ret; +} + +int wlan_get_mac_addr(wlan_private * priv, u8 * mac_addr) +{ + int ret = wlan_generic_get_str(priv, WID_MAC_ADDR, mac_addr, ETH_ALEN, NULL); + + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "STA MAC Address [%02x:%02x:%02x:%02x:%02x:%02x]\n", + mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); +out: + return ret; +} + +int wlan_get_bssid(wlan_private * priv, u8 * bssid) +{ + int ret = 0; + + memcpy(bssid, priv->curbssparams.bssid, ETH_ALEN); + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Get BSSID [%02x:%02x:%02x:%02x:%02x:%02x]\n", + bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); + + return ret; +} + +int wlan_get_channel(wlan_private * priv, u8 * channel) +{ + int ret; + + ret = wlan_generic_get_uchar(priv, WID_CURRENT_CHANNEL, channel); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Get Channel %d\n", *channel); +out: + return ret; +} + +int wlan_get_rssi(wlan_private *priv, u8 *rssi) +{ + int ret = 0; + u8 gRssi = 0; + + ret = wlan_generic_get_uchar(priv, WID_RSSI, &gRssi); + if(!ret) + wlan_update_aver_rssi(priv, priv->curbssparams.bssid, gRssi); + + gRssi = (u8)wlan_get_aver_rssi(priv, priv->curbssparams.bssid); + *rssi = gRssi; + return ret; +} + + +int wlan_set_mac_addr(wlan_private * priv, u8 * mac_addr) +{ + int ret; + + ret = wlan_generic_set_str(priv, WID_MAC_ADDR, mac_addr, ETH_ALEN); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set STA MAC Address [%02x:%02x:%02x:%02x:%02x:%02x]\n", + mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); +out: + return ret; +} + +int wlan_set_preamble(wlan_private * priv, u8 preamble) +{ + int ret; + + ret = wlan_generic_set_uchar(priv, WID_PREAMBLE, preamble); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "wlan_set_preamble \n"); +out: + return ret; +} + +int wlan_set_scan_complete(wlan_private * priv) +{ + int ret; + + ret = wlan_generic_set_uchar(priv, WID_NETWORK_INFO_EN, 0); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + +out: + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "wlan_set_scan_complete ret=%d \n", ret); + return ret; +} + +int wlan_set_ssid(wlan_private * priv, u8 * ssid, u8 ssid_len) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set SSID: %s, len = %d\n", ssid, ssid_len); + + ret = wlan_generic_set_str(priv, WID_SSID, ssid, ssid_len); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set SSID Done\n"); + +out: + return ret; +} + +int wlan_get_ssid(wlan_private * priv, u8 * ssid, u8 * ssid_len) +{ + int ret; + u32 len = 0; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Get SSID \n"); + + ret = wlan_generic_get_str(priv, WID_SSID, ssid, 32, &len); + *ssid_len = len; + if (*ssid_len > 0) + ssid[*ssid_len] = '\0'; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Get SSID Done len:%d %s\n", *ssid_len, + (*ssid_len > 1) ? ssid : (u8 *) "NULL"); + + return ret; +} + +int wlan_set_bssid(wlan_private * priv, u8 * bssid) +{ + int ret; + + ret = wlan_generic_set_str(priv, WID_BSSID, bssid, ETH_ALEN); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set BSSID [%02x:%02x:%02x:%02x:%02x:%02x]\n", + bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); +out: + return ret; +} + +int wlan_disconnect(wlan_private * priv) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "wlan_disconnect \n"); + + wlan_remove_tx_data_queue(priv); + ret = wlan_generic_set_uchar(priv, WID_DISCONNECT, 0); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "wlan_disconnect Done\n"); + +out: + return ret; +} + +int wlan_set_imode(wlan_private * priv, u8 imode) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set IMode 0x%02x\n", imode); + + ret = wlan_generic_set_uchar(priv, WID_802_11I_MODE, imode); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set IMode Done\n"); + +out: + return ret; +} + +int wlan_set_authtype(wlan_private * priv, u8 authtype) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set AuthType 0x%02x\n", authtype); + + ret = wlan_generic_set_uchar(priv, WID_AUTH_TYPE, authtype); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set AuthType Done\n"); + +out: + return ret; +} + +int wlan_set_listen_interval(wlan_private * priv, u8 interval) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set wlan_set_listen_interval 0x%02x\n", interval); + + ret = wlan_generic_set_uchar(priv, WID_LISTEN_INTERVAL, interval); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set wlan_set_listen_interval Done\n"); +out: + return ret; +} + +int wlan_set_link_loss_threshold(wlan_private * priv, u8 threshold) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set wlan_set_link_loss_threshold 0x%02x\n", threshold); + + ret = wlan_generic_set_uchar(priv, WID_LINK_LOSS_THRESHOLD, threshold); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set wlan_set_link_loss_threshold Done\n"); + +out: + return ret; +} + +int wlan_set_power_save(wlan_private * priv) +{ + int ret = 0; + if (priv->version == WLAN_VERSION_91 || priv->version == WLAN_VERSION_91_E|| priv->version == WLAN_VERSION_91_F) { + ret = wlan_generic_set_uchar(priv, WID_POWER_SAVE, 0x30); + if(ret){ + WLAN_ERRP("wlan_generic_set_uchar WID_POWER_SAVE failed! \n"); + } + } + return ret; + +} + +int wlan_set_wepkey(wlan_private * priv, u16 index, u8 * key, u8 key_len) +{ + int ret; + u8 key_str[26 + 1]; // plus 1 for debug print + u8 key_str_len; + + if (key_len == KEY_LEN_WEP_40) { + sprintf(key_str, "%02x%02x%02x%02x%02x\n", + key[0], key[1], key[2], key[3], key[4]); + key_str_len = 10; + key_str[key_str_len] = '\0'; + } else if (key_len == KEY_LEN_WEP_104) { + sprintf(key_str, "%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x" + "%02x%02x%02x\n", + key[0], key[1], key[2], key[3], key[4], + key[5], key[6], key[7], key[8], key[9], + key[10], key[11], key[12]); + key_str_len = 26; + key_str[key_str_len] = '\0'; + } else { + WLAN_ERRP("Error in WEP Key length %d\n", key_len); + ret = -EINVAL; + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set WEP KEY[%d]: %s\n", index, key_str); + + ret = wlan_generic_set_str(priv, + (WID_WEP_KEY_VALUE0 + index), key_str, + key_str_len); + if (ret) { + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set WEP KEY[%d] Done\n", index); + +out: + return ret; +} + +static void dump_key(u8 * key, u8 key_len) +{ + WLAN_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n", + key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]); + WLAN_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n", + key[8], key[9], key[10], key[11], key[12], key[13], key[14], key[15]); + if (key_len > 16) + WLAN_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n", + key[16], key[17], key[18], key[19], key[20], key[21], key[22], key[23]); + if (key_len > 24) + WLAN_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n", + key[24], key[25], key[26], key[27], key[28], key[29], key[30], key[31]); +} + +int wlan_set_ptk(wlan_private * priv, u8 * key, u8 key_len) +{ + int ret; + u8 key_str[32 + ETH_ALEN + 1]; + u8 key_str_len = key_len + ETH_ALEN + 1; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set PTK: len = %d\n", key_len); + + if (WLAN_DBGLA(WLAN_DA_WID, WLAN_DL_VERB)) + dump_key(key, key_len); + + if (priv->connect_status != MAC_CONNECTED) { + WLAN_ERRP("Adding PTK while not connected\n"); + ret = -EINVAL; + goto out; + } + + /*----------------------------------------*/ + /* STA Addr | KeyLength | Key */ + /*----------------------------------------*/ + /* 6 | 1 | KeyLength */ + /*----------------------------------------*/ + + /*---------------------------------------------------------*/ + /* key */ + /*---------------------------------------------------------*/ + /* Temporal Key | Rx Micheal Key | Tx Micheal Key */ + /*---------------------------------------------------------*/ + /* 16 bytes | 8 bytes | 8 bytes */ + /*---------------------------------------------------------*/ + + memcpy(key_str, priv->curbssparams.bssid, ETH_ALEN); + key_str[6] = key_len; + memcpy(key_str + 7, key, 16); + + /* swap TX MIC and RX MIC, wlan need RX MIC to be ahead */ + if (key_len > 16) { + memcpy(key_str + 7 + 16, key + 24, 8); + memcpy(key_str + 7 + 24, key + 16, 8); + } + + if (priv->is_wapi) + ret = wlan_generic_set_str(priv, + WID_ADD_WAPI_PTK, key_str, + key_str_len); + else + ret = wlan_generic_set_str(priv, + WID_ADD_PTK, key_str, key_str_len); + if (ret) { + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set PTK Done\n"); + +out: + return ret; +} + +int wlan_set_gtk(wlan_private * priv, u8 key_id, + u8 * key_rsc, u8 key_rsc_len, u8 * key, u8 key_len) +{ + int ret; + u8 key_str[32 + ETH_ALEN + 8 + 2]; + u8 key_str_len = key_len + ETH_ALEN + 8 + 2; + + /*---------------------------------------------------------*/ + /* STA Addr | KeyRSC | KeyID | KeyLength | Key */ + /*---------------------------------------------------------*/ + /* 6 | 8 | 1 | 1 | KeyLength */ + /*---------------------------------------------------------*/ + + /*-------------------------------------*/ + /* key */ + /*-------------------------------------*/ + /* Temporal Key | Rx Micheal Key */ + /*-------------------------------------*/ + /* 16 bytes | 8 bytes */ + /*-------------------------------------*/ + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set GTK: len = %d\n", key_len); + if (WLAN_DBGLA(WLAN_DA_WID, WLAN_DL_VERB)) + dump_key(key, key_len); + + if (priv->connect_status != MAC_CONNECTED) { + WLAN_ERRP("Adding GTK while not connected\n"); + ret = -EINVAL; + goto out; + } + + memcpy(key_str, priv->curbssparams.bssid, ETH_ALEN); + memcpy(key_str + 6, key_rsc, key_rsc_len); + key_str[14] = key_id; + key_str[15] = key_len; + memcpy(key_str + 16, key, 16); + + /* swap TX MIC and RX MIC, wlan need RX MIC to be ahead */ + if (key_len > 16) { + //memcpy(key_str + 16 + 16, key + 16, key_len - 16); + memcpy(key_str + 16 + 16, key + 24, 8); + memcpy(key_str + 16 + 24, key + 16, 8); + } + + if (priv->is_wapi) + ret = wlan_generic_set_str(priv, + WID_ADD_WAPI_RX_GTK, key_str, + key_str_len); + else + ret = wlan_generic_set_str(priv, + WID_ADD_RX_GTK, key_str, + key_str_len); + if (ret) { + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set GTK Done\n"); +out: + return ret; +} + +int wlan_set_pm_mode(wlan_private * priv, u8 pm_mode) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set PM Mode 0x%02x\n", pm_mode); + + ret = wlan_generic_set_uchar(priv, WID_POWER_MANAGEMENT, pm_mode); + if (ret) { + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set PM Mode Done\n"); + +out: + return ret; +} + +int wlan_set_preasso_sleep(wlan_private * priv, u32 preasso_sleep) +{ + int ret; + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, + "Set Preasso Sleep 0x%08x\n", preasso_sleep); + + ret = wlan_generic_set_ulong(priv, WID_PREASSO_SLEEP, preasso_sleep); + if (ret) { + WLAN_ERRP("failed \n"); + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "Set Preasso Sleep Done\n"); + +out: + return ret; +} + +int rda5890_set_preamble(wlan_private * priv, unsigned char preamble) +{ + int ret; + + ret = wlan_generic_set_uchar(priv, WID_PREAMBLE, preamble); + if (ret) { + goto out; + } + + WLAN_DBGLAP(WLAN_DA_WID, WLAN_DL_TRACE, "rda5890_set_preamble \n"); +out: + return ret; +} + +int wlan_set_pta(wlan_private * priv, struct pta_param_s* param) +{ + int ret; + + ret = wlan_generic_set_bin(priv, WID_PTA_PARAMETER, (u8*)param, sizeof(struct pta_param_s)); + if (ret) { + WLAN_ERRP("set WID_PTA_PARAMETER failed \n"); + } + + return ret; +} |