summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-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/rtl8188E_8192E/hal/rtl8188e/sdio')
-rwxr-xr-xdrivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_led.c124
-rwxr-xr-xdrivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_recv.c852
-rwxr-xr-xdrivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_xmit.c1691
-rwxr-xr-xdrivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_halinit.c4179
-rwxr-xr-xdrivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_ops.c1940
5 files changed, 8786 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_led.c b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_led.c
new file mode 100755
index 00000000..06c90c55
--- /dev/null
+++ b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_led.c
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+#define _RTL8189ES_LED_C_
+
+#include "drv_types.h"
+#include "rtl8188e_hal.h"
+
+//================================================================================
+// LED object.
+//================================================================================
+
+
+//================================================================================
+// Prototype of protected function.
+//================================================================================
+
+//================================================================================
+// LED_819xUsb routines.
+//================================================================================
+
+//
+// Description:
+// Turn on LED according to LedPin specified.
+//
+void
+SwLedOn(
+ _adapter *padapter,
+ PLED_871x pLed
+)
+{
+ u8 LedCfg;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
+ {
+ return;
+ }
+
+ pLed->bLedOn = _TRUE;
+}
+
+
+//
+// Description:
+// Turn off LED according to LedPin specified.
+//
+void
+SwLedOff(
+ _adapter *padapter,
+ PLED_871x pLed
+)
+{
+ u8 LedCfg;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if((padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
+ {
+ goto exit;
+ }
+
+exit:
+ pLed->bLedOn = _FALSE;
+
+}
+
+//================================================================================
+// Default LED behavior.
+//================================================================================
+
+//
+// Description:
+// Initialize all LED_871x objects.
+//
+void
+rtl8188es_InitSwLeds(
+ _adapter *padapter
+ )
+{
+ struct led_priv *pledpriv = &(padapter->ledpriv);
+
+#if 0
+ pledpriv->LedControlHandler = LedControl871x;
+
+ InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0);
+
+ InitLed871x(padapter,&(pledpriv->SwLed1), LED_PIN_LED1);
+#endif
+}
+
+
+//
+// Description:
+// DeInitialize all LED_819xUsb objects.
+//
+void
+rtl8188es_DeInitSwLeds(
+ _adapter *padapter
+ )
+{
+#if 0
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+ DeInitLed871x( &(ledpriv->SwLed0) );
+ DeInitLed871x( &(ledpriv->SwLed1) );
+#endif
+}
+
diff --git a/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_recv.c b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_recv.c
new file mode 100755
index 00000000..06807f97
--- /dev/null
+++ b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_recv.c
@@ -0,0 +1,852 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+#define _RTL8189ES_RECV_C_
+
+#include <drv_conf.h>
+
+#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
+#error "Shall be Linux or Windows, but not both!\n"
+#endif
+
+#include <drv_types.h>
+#include <recv_osdep.h>
+#include <rtl8188e_hal.h>
+
+static void rtl8188es_recv_tasklet(void *priv);
+
+static s32 initrecvbuf(struct recv_buf *precvbuf, PADAPTER padapter)
+{
+ _rtw_init_listhead(&precvbuf->list);
+ _rtw_spinlock_init(&precvbuf->recvbuf_lock);
+
+ precvbuf->adapter = padapter;
+
+ return _SUCCESS;
+}
+
+static void freerecvbuf(struct recv_buf *precvbuf)
+{
+ _rtw_spinlock_free(&precvbuf->recvbuf_lock);
+}
+
+/*
+ * Initialize recv private variable for hardware dependent
+ * 1. recv buf
+ * 2. recv tasklet
+ *
+ */
+s32 rtl8188es_init_recv_priv(PADAPTER padapter)
+{
+ s32 res;
+ u32 i, n;
+ struct recv_priv *precvpriv;
+ struct recv_buf *precvbuf;
+
+
+ res = _SUCCESS;
+ precvpriv = &padapter->recvpriv;
+
+ //3 1. init recv buffer
+ _rtw_init_queue(&precvpriv->free_recv_buf_queue);
+ _rtw_init_queue(&precvpriv->recv_buf_pending_queue);
+
+ n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
+ precvpriv->pallocated_recv_buf = rtw_zmalloc(n);
+ if (precvpriv->pallocated_recv_buf == NULL) {
+ res = _FAIL;
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("alloc recv_buf fail!\n"));
+ goto exit;
+ }
+
+ precvpriv->precv_buf = (u8*)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
+
+ // init each recv buffer
+ precvbuf = (struct recv_buf*)precvpriv->precv_buf;
+ for (i = 0; i < NR_RECVBUFF; i++)
+ {
+ res = initrecvbuf(precvbuf, padapter);
+ if (res == _FAIL)
+ break;
+
+ res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
+ if (res == _FAIL) {
+ freerecvbuf(precvbuf);
+ break;
+ }
+
+#ifdef CONFIG_SDIO_RX_COPY
+ if (precvbuf->pskb == NULL) {
+ SIZE_PTR tmpaddr=0;
+ SIZE_PTR alignment=0;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
+ precvbuf->pskb = __dev_alloc_skb(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL);
+#else
+ precvbuf->pskb = __netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL);
+#endif
+
+ if(precvbuf->pskb)
+ {
+ precvbuf->pskb->dev = padapter->pnetdev;
+
+ tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
+ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+ skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
+
+ precvbuf->phead = precvbuf->pskb->head;
+ precvbuf->pdata = precvbuf->pskb->data;
+ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+ precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+ precvbuf->len = 0;
+ }
+
+ if (precvbuf->pskb == NULL) {
+ DBG_871X("%s: alloc_skb fail!\n", __FUNCTION__);
+ }
+ }
+#endif
+
+ rtw_list_insert_tail(&precvbuf->list, &precvpriv->free_recv_buf_queue.queue);
+
+ precvbuf++;
+ }
+ precvpriv->free_recv_buf_queue_cnt = i;
+
+ if (res == _FAIL)
+ goto initbuferror;
+
+ //3 2. init tasklet
+#ifdef PLATFORM_LINUX
+ tasklet_init(&precvpriv->recv_tasklet,
+ (void(*)(unsigned long))rtl8188es_recv_tasklet,
+ (unsigned long)padapter);
+#endif
+
+ goto exit;
+
+initbuferror:
+ precvbuf = (struct recv_buf*)precvpriv->precv_buf;
+ if (precvbuf) {
+ n = precvpriv->free_recv_buf_queue_cnt;
+ precvpriv->free_recv_buf_queue_cnt = 0;
+ for (i = 0; i < n ; i++)
+ {
+ rtw_list_delete(&precvbuf->list);
+ rtw_os_recvbuf_resource_free(padapter, precvbuf);
+ freerecvbuf(precvbuf);
+ precvbuf++;
+ }
+ precvpriv->precv_buf = NULL;
+ }
+
+ if (precvpriv->pallocated_recv_buf) {
+ n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
+ rtw_mfree(precvpriv->pallocated_recv_buf, n);
+ precvpriv->pallocated_recv_buf = NULL;
+ }
+
+exit:
+ return res;
+}
+
+/*
+ * Free recv private variable of hardware dependent
+ * 1. recv buf
+ * 2. recv tasklet
+ *
+ */
+void rtl8188es_free_recv_priv(PADAPTER padapter)
+{
+ u32 i, n;
+ struct recv_priv *precvpriv;
+ struct recv_buf *precvbuf;
+
+
+ precvpriv = &padapter->recvpriv;
+
+ //3 1. kill tasklet
+#ifdef PLATFORM_LINUX
+ tasklet_kill(&precvpriv->recv_tasklet);
+#endif
+
+ //3 2. free all recv buffers
+ precvbuf = (struct recv_buf*)precvpriv->precv_buf;
+ if (precvbuf) {
+ n = NR_RECVBUFF;
+ precvpriv->free_recv_buf_queue_cnt = 0;
+ for (i = 0; i < n ; i++)
+ {
+ rtw_list_delete(&precvbuf->list);
+ rtw_os_recvbuf_resource_free(padapter, precvbuf);
+ freerecvbuf(precvbuf);
+ precvbuf++;
+ }
+ precvpriv->precv_buf = NULL;
+ }
+
+ if (precvpriv->pallocated_recv_buf) {
+ n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
+ rtw_mfree(precvpriv->pallocated_recv_buf, n);
+ precvpriv->pallocated_recv_buf = NULL;
+ }
+}
+
+#ifdef CONFIG_SDIO_RX_COPY
+static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_buf *precvbuf, struct phy_stat *pphy_status)
+{
+ s32 ret=_SUCCESS;
+#ifdef CONFIG_CONCURRENT_MODE
+ u8 *primary_myid, *secondary_myid, *paddr1;
+ union recv_frame *precvframe_if2 = NULL;
+ _adapter *primary_padapter = precvframe->u.hdr.adapter;
+ _adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
+ struct recv_priv *precvpriv = &primary_padapter->recvpriv;
+ _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(primary_padapter);
+
+ if(!secondary_padapter)
+ return ret;
+
+ paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data);
+
+ if(IS_MCAST(paddr1) == _FALSE)//unicast packets
+ {
+ //primary_myid = myid(&primary_padapter->eeprompriv);
+ secondary_myid = myid(&secondary_padapter->eeprompriv);
+
+ if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN))
+ {
+ //change to secondary interface
+ precvframe->u.hdr.adapter = secondary_padapter;
+ }
+
+ //ret = recv_entry(precvframe);
+
+ }
+ else // Handle BC/MC Packets
+ {
+ //clone/copy to if2
+ _pkt *pkt_copy = NULL;
+ struct rx_pkt_attrib *pattrib = NULL;
+
+ precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);
+
+ if(!precvframe_if2)
+ return _FAIL;
+
+ precvframe_if2->u.hdr.adapter = secondary_padapter;
+ _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
+ pattrib = &precvframe_if2->u.hdr.attrib;
+
+ //driver need to set skb len for skb_copy().
+ //If skb->len is zero, skb_copy() will not copy data from original skb.
+ skb_put(precvframe->u.hdr.pkt, pattrib->pkt_len);
+
+ pkt_copy = skb_copy( precvframe->u.hdr.pkt, GFP_ATOMIC);
+ if (pkt_copy == NULL)
+ {
+ if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
+ {
+ DBG_8192C("pre_recv_entry(): skb_copy fail , drop frag frame \n");
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ return ret;
+ }
+
+ pkt_copy = skb_clone( precvframe->u.hdr.pkt, GFP_ATOMIC);
+ if(pkt_copy == NULL)
+ {
+ DBG_8192C("pre_recv_entry(): skb_clone fail , drop frame\n");
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ return ret;
+ }
+ }
+
+ pkt_copy->dev = secondary_padapter->pnetdev;
+
+ precvframe_if2->u.hdr.pkt = pkt_copy;
+ precvframe_if2->u.hdr.rx_head = pkt_copy->head;
+ precvframe_if2->u.hdr.rx_data = pkt_copy->data;
+ precvframe_if2->u.hdr.rx_tail = skb_tail_pointer(pkt_copy);
+ precvframe_if2->u.hdr.rx_end = skb_end_pointer(pkt_copy);
+ precvframe_if2->u.hdr.len = pkt_copy->len;
+
+ //recvframe_put(precvframe_if2, pattrib->pkt_len);
+
+ if ( pHalData->ReceiveConfig & RCR_APPFCS)
+ recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN);
+
+ if (pattrib->physt)
+ update_recvframe_phyinfo_88e(precvframe_if2, pphy_status);
+
+ if(rtw_recv_entry(precvframe_if2) != _SUCCESS)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+ ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
+ }
+ }
+
+ if (precvframe->u.hdr.attrib.physt)
+ update_recvframe_phyinfo_88e(precvframe, pphy_status);
+ ret = rtw_recv_entry(precvframe);
+
+#endif
+
+ return ret;
+
+}
+
+static void rtl8188es_recv_tasklet(void *priv)
+{
+ PADAPTER padapter;
+ PHAL_DATA_TYPE pHalData;
+ struct recv_priv *precvpriv;
+ struct recv_buf *precvbuf;
+ union recv_frame *precvframe;
+ struct recv_frame_hdr *phdr;
+ struct rx_pkt_attrib *pattrib;
+ _irqL irql;
+ u8 *ptr;
+ u32 pkt_offset, skb_len, alloc_sz;
+ s32 transfer_len;
+ _pkt *pkt_copy = NULL;
+ struct phy_stat *pphy_status = NULL;
+ u8 shift_sz = 0, rx_report_sz = 0;
+
+
+ padapter = (PADAPTER)priv;
+ pHalData = GET_HAL_DATA(padapter);
+ precvpriv = &padapter->recvpriv;
+
+ do {
+ if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
+ {
+ DBG_8192C("recv_tasklet => bDriverStopped or bSurpriseRemoved \n");
+ break;
+ }
+
+ precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
+ if (NULL == precvbuf) break;
+
+ transfer_len = (s32)precvbuf->len;
+ ptr = precvbuf->pdata;
+
+ do {
+ precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
+ if (precvframe == NULL) {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("%s: no enough recv frame!\n",__FUNCTION__));
+ rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
+
+ // The case of can't allocte recvframe should be temporary,
+ // schedule again and hope recvframe is available next time.
+#ifdef PLATFORM_LINUX
+ tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+ return;
+ }
+
+ //rx desc parsing
+ update_recvframe_attrib_88e(precvframe, (struct recv_stat*)ptr);
+
+ pattrib = &precvframe->u.hdr.attrib;
+
+ // fix Hardware RX data error, drop whole recv_buffer
+ if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
+ {
+ #if !(MP_DRIVER==1)
+ DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
+ #endif
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ break;
+ }
+
+ if (pHalData->ReceiveConfig & RCR_APP_BA_SSN)
+ rx_report_sz = RXDESC_SIZE + 4 + pattrib->drvinfo_sz;
+ else
+ rx_report_sz = RXDESC_SIZE + pattrib->drvinfo_sz;
+
+ pkt_offset = rx_report_sz + pattrib->shift_sz + pattrib->pkt_len;
+
+ if ((pattrib->pkt_len==0) || (pkt_offset>transfer_len)) {
+ DBG_8192C("%s()-%d: RX Warning!,pkt_len==0 or pkt_offset(%d)> transfoer_len(%d) \n", __FUNCTION__, __LINE__, pkt_offset, transfer_len);
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ break;
+ }
+
+ if ((pattrib->crc_err) || (pattrib->icv_err))
+ {
+ DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ }
+ else
+ {
+ // Modified by Albert 20101213
+ // For 8 bytes IP header alignment.
+ if (pattrib->qos) // Qos data, wireless lan header length is 26
+ {
+ shift_sz = 6;
+ }
+ else
+ {
+ shift_sz = 0;
+ }
+
+ skb_len = pattrib->pkt_len;
+
+ // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
+ // modify alloc_sz for recvive crc error packet by thomas 2011-06-02
+ if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
+ //alloc_sz = 1664; //1664 is 128 alignment.
+ if(skb_len <= 1650)
+ alloc_sz = 1664;
+ else
+ alloc_sz = skb_len + 14;
+ }
+ else {
+ alloc_sz = skb_len;
+ // 6 is for IP header 8 bytes alignment in QoS packet case.
+ // 8 is for skb->data 4 bytes alignment.
+ alloc_sz += 14;
+ }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
+ pkt_copy = dev_alloc_skb(alloc_sz);
+#else
+ pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
+#endif
+ if(pkt_copy)
+ {
+ pkt_copy->dev = padapter->pnetdev;
+ precvframe->u.hdr.pkt = pkt_copy;
+ skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
+ skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
+ _rtw_memcpy(pkt_copy->data, (ptr + rx_report_sz + pattrib->shift_sz), skb_len);
+ precvframe->u.hdr.rx_head = pkt_copy->head;
+ precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
+ precvframe->u.hdr.rx_end = skb_end_pointer(pkt_copy);
+ }
+ else
+ {
+ if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
+ {
+ DBG_8192C("rtl8188es_recv_tasklet: alloc_skb fail , drop frag frame \n");
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ break;
+ }
+
+ precvframe->u.hdr.pkt = skb_clone(precvbuf->pskb, GFP_ATOMIC);
+ if(precvframe->u.hdr.pkt)
+ {
+ _pkt *pkt_clone = precvframe->u.hdr.pkt;
+
+ pkt_clone->data = ptr + rx_report_sz + pattrib->shift_sz;
+ skb_reset_tail_pointer(pkt_clone);
+ precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail
+ = pkt_clone->data;
+ precvframe->u.hdr.rx_end = pkt_clone->data + skb_len;
+ }
+ else
+ {
+ DBG_8192C("rtl8188es_recv_tasklet: skb_clone fail\n");
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ break;
+ }
+ }
+
+ recvframe_put(precvframe, skb_len);
+ //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
+
+ if (pHalData->ReceiveConfig & RCR_APPFCS)
+ recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);
+
+ // update drv info
+ if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
+ //rtl8723s_update_bassn(padapter, (ptr + RXDESC_SIZE));
+ }
+
+ if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet
+ {
+ pphy_status = (struct phy_stat *)(ptr + (rx_report_sz - pattrib->drvinfo_sz));
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(rtw_buddy_adapter_up(padapter))
+ {
+ if(pre_recv_entry(precvframe, precvbuf, (struct phy_stat*)pphy_status) != _SUCCESS)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+ ("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
+ }
+ }
+ else
+#endif
+ {
+ if (pattrib->physt)
+ update_recvframe_phyinfo_88e(precvframe, (struct phy_stat*)pphy_status);
+
+ if (rtw_recv_entry(precvframe) != _SUCCESS)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",__FUNCTION__));
+ }
+ }
+ }
+ else{ // pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP,HIS_REPORT-USB HISR RTP
+
+ //enqueue recvframe to txrtp queue
+ if(pattrib->pkt_rpt_type == TX_REPORT1){
+ //DBG_8192C("rx CCX \n");
+ //CCX-TXRPT ack for xmit mgmt frames.
+ handle_txrpt_ccx_88e(padapter, precvframe->u.hdr.rx_data);
+ }
+ else if(pattrib->pkt_rpt_type == TX_REPORT2){
+ //printk("rx TX RPT \n");
+ ODM_RA_TxRPT2Handle_8188E(
+ &pHalData->odmpriv,
+ precvframe->u.hdr.rx_data,
+ pattrib->pkt_len,
+ pattrib->MacIDValidEntry[0],
+ pattrib->MacIDValidEntry[1]
+ );
+
+ }
+ /*
+ else if(pattrib->pkt_rpt_type == HIS_REPORT){
+ printk("rx USB HISR \n");
+ }*/
+
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+
+ }
+ }
+
+ // Page size of receive package is 128 bytes alignment =>DMA AGG
+ // refer to _InitTransferPageSize()
+ pkt_offset = _RND128(pkt_offset);
+ transfer_len -= pkt_offset;
+ ptr += pkt_offset;
+ precvframe = NULL;
+ pkt_copy = NULL;
+ }while(transfer_len>0);
+
+ precvbuf->len = 0;
+
+ rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
+ } while (1);
+
+}
+#else
+static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_buf *precvbuf, struct phy_stat *pphy_status)
+{
+ s32 ret=_SUCCESS;
+#ifdef CONFIG_CONCURRENT_MODE
+ u8 *primary_myid, *secondary_myid, *paddr1;
+ union recv_frame *precvframe_if2 = NULL;
+ _adapter *primary_padapter = precvframe->u.hdr.adapter;
+ _adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
+ struct recv_priv *precvpriv = &primary_padapter->recvpriv;
+ _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
+ u8 *pbuf = precvframe->u.hdr.rx_head;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(primary_padapter);
+
+ if(!secondary_padapter)
+ return ret;
+
+ paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data);
+
+ if(IS_MCAST(paddr1) == _FALSE)//unicast packets
+ {
+ //primary_myid = myid(&primary_padapter->eeprompriv);
+ secondary_myid = myid(&secondary_padapter->eeprompriv);
+
+ if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN))
+ {
+ //change to secondary interface
+ precvframe->u.hdr.adapter = secondary_padapter;
+ }
+
+ //ret = recv_entry(precvframe);
+
+ }
+ else // Handle BC/MC Packets
+ {
+ //clone/copy to if2
+ u8 shift_sz = 0;
+ u32 alloc_sz, skb_len;
+ _pkt *pkt_copy = NULL;
+ struct rx_pkt_attrib *pattrib = NULL;
+
+ precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);
+
+ if(!precvframe_if2)
+ return _FAIL;
+
+ precvframe_if2->u.hdr.adapter = secondary_padapter;
+ _rtw_init_listhead(&precvframe_if2->u.hdr.list);
+ precvframe_if2->u.hdr.precvbuf = NULL; //can't access the precvbuf for new arch.
+ precvframe_if2->u.hdr.len=0;
+ _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
+ pattrib = &precvframe_if2->u.hdr.attrib;
+
+ pkt_copy = skb_copy( precvframe->u.hdr.pkt, GFP_ATOMIC);
+ if (pkt_copy == NULL)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_crit_, ("%s: no enough memory to allocate SKB!\n",__FUNCTION__));
+ rtw_free_recvframe(precvframe_if2, &precvpriv->free_recv_queue);
+ rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
+
+ // The case of can't allocte skb is serious and may never be recovered,
+ // once bDriverStopped is enable, this task should be stopped.
+ if (secondary_padapter->bDriverStopped == _FALSE)
+#ifdef PLATFORM_LINUX
+ tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+ return ret;
+ }
+ pkt_copy->dev = secondary_padapter->pnetdev;
+
+
+
+ if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
+ //alloc_sz = 1664; //1664 is 128 alignment.
+ if(skb_len <= 1650)
+ alloc_sz = 1664;
+ else
+ alloc_sz = skb_len + 14;
+ }
+ else {
+ alloc_sz = skb_len;
+ // 6 is for IP header 8 bytes alignment in QoS packet case.
+ // 8 is for skb->data 4 bytes alignment.
+ alloc_sz += 14;
+ }
+
+#if 1
+ precvframe_if2->u.hdr.pkt = pkt_copy;
+ precvframe_if2->u.hdr.rx_head = pkt_copy->head;
+ precvframe_if2->u.hdr.rx_data = precvframe_if2->u.hdr.rx_tail = pkt_copy->data;
+ precvframe_if2->u.hdr.rx_end = pkt_copy->data + alloc_sz;
+#endif
+ recvframe_put(precvframe_if2, pkt_offset);
+ recvframe_pull(precvframe_if2, RXDESC_SIZE + pattrib->drvinfo_sz);
+
+ if ( pHalData->ReceiveConfig & RCR_APPFCS)
+ recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN);
+
+ if (pattrib->physt)
+ update_recvframe_phyinfo_88e(precvframe_if2, pphy_status);
+
+ if(rtw_recv_entry(precvframe_if2) != _SUCCESS)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+ ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
+ }
+ }
+
+ if (precvframe->u.hdr.attrib.physt)
+ update_recvframe_phyinfo_88e(precvframe, (struct phy_stat*)pphy_status);
+ ret = rtw_recv_entry(precvframe);
+
+#endif
+
+ return ret;
+
+}
+
+static void rtl8188es_recv_tasklet(void *priv)
+{
+ PADAPTER padapter;
+ PHAL_DATA_TYPE pHalData;
+ struct recv_priv *precvpriv;
+ struct recv_buf *precvbuf;
+ union recv_frame *precvframe;
+ struct recv_frame_hdr *phdr;
+ struct rx_pkt_attrib *pattrib;
+ u8 *ptr;
+ _pkt *ppkt;
+ u32 pkt_offset;
+ _irqL irql;
+#ifdef CONFIG_CONCURRENT_MODE
+ struct recv_stat *prxstat;
+#endif
+
+ padapter = (PADAPTER)priv;
+ pHalData = GET_HAL_DATA(padapter);
+ precvpriv = &padapter->recvpriv;
+
+ do {
+ precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
+ if (NULL == precvbuf) break;
+
+ ptr = precvbuf->pdata;
+
+ while (ptr < precvbuf->ptail)
+ {
+ precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
+ if (precvframe == NULL) {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("%s: no enough recv frame!\n",__FUNCTION__));
+ rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
+
+ // The case of can't allocte recvframe should be temporary,
+ // schedule again and hope recvframe is available next time.
+#ifdef PLATFORM_LINUX
+ tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+ return;
+ }
+
+ phdr = &precvframe->u.hdr;
+ pattrib = &phdr->attrib;
+
+ //rx desc parsing
+ update_recvframe_attrib_88e(precvframe, (struct recv_stat*)ptr);
+#ifdef CONFIG_CONCURRENT_MODE
+ prxstat = (struct recv_stat*)ptr;
+#endif
+ // fix Hardware RX data error, drop whole recv_buffer
+ if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
+ {
+ //#if !(MP_DRIVER==1)
+ if (padapter->registrypriv.mp_mode == 0)
+ DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
+ //#endif
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ break;
+ }
+
+ pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->pkt_len;
+
+ if ((ptr + pkt_offset) > precvbuf->ptail) {
+ DBG_8192C("%s()-%d: : next pkt len(%p,%d) exceed ptail(%p)!\n", __FUNCTION__, __LINE__, ptr, pkt_offset, precvbuf->ptail);
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ break;
+ }
+
+ if ((pattrib->crc_err) || (pattrib->icv_err))
+ {
+ DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ }
+ else
+ {
+ ppkt = skb_clone(precvbuf->pskb, GFP_ATOMIC);
+ if (ppkt == NULL)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_crit_, ("%s: no enough memory to allocate SKB!\n",__FUNCTION__));
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+ rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
+
+ // The case of can't allocte skb is serious and may never be recovered,
+ // once bDriverStopped is enable, this task should be stopped.
+ if (padapter->bDriverStopped == _FALSE) {
+#ifdef PLATFORM_LINUX
+ tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+ }
+
+ return;
+ }
+
+ phdr->pkt = ppkt;
+ phdr->len = 0;
+ phdr->rx_head = precvbuf->phead;
+ phdr->rx_data = phdr->rx_tail = precvbuf->pdata;
+ phdr->rx_end = precvbuf->pend;
+
+ recvframe_put(precvframe, pkt_offset);
+ recvframe_pull(precvframe, RXDESC_SIZE + pattrib->drvinfo_sz);
+
+ if (pHalData->ReceiveConfig & RCR_APPFCS)
+ recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);
+
+ // move to drv info position
+ ptr += RXDESC_SIZE;
+
+ // update drv info
+ if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
+// rtl8723s_update_bassn(padapter, pdrvinfo);
+ ptr += 4;
+ }
+
+ if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet
+ {
+#ifdef CONFIG_CONCURRENT_MODE
+ if(rtw_buddy_adapter_up(padapter))
+ {
+ if(pre_recv_entry(precvframe, precvbuf, (struct phy_stat*)ptr) != _SUCCESS)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+ ("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
+ }
+ }
+ else
+#endif
+ {
+ if (pattrib->physt)
+ update_recvframe_phyinfo_88e(precvframe, (struct phy_stat*)ptr);
+
+ if (rtw_recv_entry(precvframe) != _SUCCESS)
+ {
+ RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+ ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
+ }
+ }
+ }
+ else{ // pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP,HIS_REPORT-USB HISR RTP
+
+ //enqueue recvframe to txrtp queue
+ if(pattrib->pkt_rpt_type == TX_REPORT1){
+ DBG_8192C("rx CCX \n");
+ }
+ else if(pattrib->pkt_rpt_type == TX_REPORT2){
+ //DBG_8192C("rx TX RPT \n");
+ ODM_RA_TxRPT2Handle_8188E(
+ &pHalData->odmpriv,
+ precvframe->u.hdr.rx_data,
+ pattrib->pkt_len,
+ pattrib->MacIDValidEntry[0],
+ pattrib->MacIDValidEntry[1]
+ );
+
+ }
+ /*
+ else if(pattrib->pkt_rpt_type == HIS_REPORT){
+ DBG_8192C("rx USB HISR \n");
+ }*/
+
+ rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+
+ }
+ }
+
+ // Page size of receive package is 128 bytes alignment =>DMA AGG
+ // refer to _InitTransferPageSize()
+ pkt_offset = _RND128(pkt_offset);
+ precvbuf->pdata += pkt_offset;
+ ptr = precvbuf->pdata;
+
+ }
+
+ dev_kfree_skb_any(precvbuf->pskb);
+ precvbuf->pskb = NULL;
+ rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
+
+ } while (1);
+
+}
+#endif
+
diff --git a/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_xmit.c b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_xmit.c
new file mode 100755
index 00000000..8fe70f10
--- /dev/null
+++ b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/rtl8189es_xmit.c
@@ -0,0 +1,1691 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+#define _RTL8189ES_XMIT_C_
+
+#include <drv_conf.h>
+#include <osdep_service.h>
+#include <drv_types.h>
+#include <sdio_ops.h>
+#include <rtl8188e_hal.h>
+
+static void fill_txdesc_sectype(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
+{
+ if ((pattrib->encrypt > 0) && !pattrib->bswenc)
+ {
+ switch (pattrib->encrypt)
+ {
+ // SEC_TYPE
+ case _WEP40_:
+ case _WEP104_:
+ case _TKIP_:
+ case _TKIP_WTMIC_:
+ ptxdesc->sectype = 1;
+ break;
+#ifdef CONFIG_WAPI_SUPPORT
+ case _SMS4_:
+ ptxdesc->sectype = 2;
+ break;
+#endif
+ case _AES_:
+ ptxdesc->sectype = 3;
+ break;
+
+ case _NO_PRIVACY_:
+ default:
+ break;
+ }
+ }
+}
+
+
+ static void fill_txdesc_vcs(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
+{
+ //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
+
+ switch (pattrib->vcs_mode)
+ {
+ case RTS_CTS:
+ ptxdesc->rtsen = 1;
+ break;
+
+ case CTS_TO_SELF:
+ ptxdesc->cts2self = 1;
+ break;
+
+ case NONE_VCS:
+ default:
+ break;
+ }
+
+ if(pattrib->vcs_mode) {
+ ptxdesc->hw_rts_en = 1; // ENABLE HW RTS
+
+ // Set RTS BW
+ if(pattrib->ht_en)
+ {
+ if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
+ ptxdesc->rts_bw = 1;
+
+ switch (pattrib->ch_offset)
+ {
+ case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
+ ptxdesc->rts_sc = 0;
+ break;
+
+ case HAL_PRIME_CHNL_OFFSET_LOWER:
+ ptxdesc->rts_sc = 1;
+ break;
+
+ case HAL_PRIME_CHNL_OFFSET_UPPER:
+ ptxdesc->rts_sc = 2;
+ break;
+
+ default:
+ ptxdesc->rts_sc = 3; // Duplicate
+ break;
+ }
+ }
+ }
+}
+
+static void fill_txdesc_phy(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
+{
+ //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
+
+ if (pattrib->ht_en)
+ {
+ if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
+ ptxdesc->data_bw = 1;
+
+ switch (pattrib->ch_offset)
+ {
+ case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
+ ptxdesc->data_sc = 0;
+ break;
+
+ case HAL_PRIME_CHNL_OFFSET_LOWER:
+ ptxdesc->data_sc = 1;
+ break;
+
+ case HAL_PRIME_CHNL_OFFSET_UPPER:
+ ptxdesc->data_sc = 2;
+ break;
+
+ default:
+ ptxdesc->data_sc = 3; // Duplicate
+ break;
+ }
+ }
+}
+
+static void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc)
+{
+ u16 *usPtr = (u16*)ptxdesc;
+ u32 count = 16; // (32 bytes / 2 bytes per XOR) => 16 times
+ u32 index;
+ u16 checksum = 0;
+
+
+ // Clear first
+ ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
+
+ for (index = 0; index < count; index++) {
+ checksum ^= le16_to_cpu(*(usPtr + index));
+ }
+
+ ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
+}
+//
+// Description: In normal chip, we should send some packet to Hw which will be used by Fw
+// in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
+// Fw can tell Hw to send these packet derectly.
+//
+void rtl8188e_fill_fake_txdesc(
+ PADAPTER padapter,
+ u8* pDesc,
+ u32 BufferLen,
+ u8 IsPsPoll,
+ u8 IsBTQosNull)
+{
+ struct tx_desc *ptxdesc;
+
+
+ // Clear all status
+ ptxdesc = (struct tx_desc*)pDesc;
+ _rtw_memset(pDesc, 0, TXDESC_SIZE);
+
+ //offset 0
+ ptxdesc->txdw0 |= cpu_to_le32( OWN | FSG | LSG); //own, bFirstSeg, bLastSeg;
+
+ ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000); //32 bytes for TX Desc
+
+ ptxdesc->txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); // Buffer size + command header
+
+ //offset 4
+ ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<<QSEL_SHT)&0x00001f00); // Fixed queue of Mgnt queue
+
+ //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
+ if (IsPsPoll)
+ {
+ ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
+ }
+ else
+ {
+ ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
+ ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
+ }
+
+ if (_TRUE == IsBTQosNull)
+ {
+ ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); // BT NULL
+ }
+
+ //offset 16
+ ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
+ // USB interface drop packet if the checksum of descriptor isn't correct.
+ // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
+ rtl8188e_cal_txdesc_chksum(ptxdesc);
+#endif
+}
+
+
+#define SDIO_TX_AGG_MAX (5)
+//#define CONFIG_FIX_CORE_DUMP ==> have bug
+//#define DBG_EMINFO
+
+#if 0
+void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc)
+{
+ u16 *usPtr = (u16*)ptxdesc;
+ u32 count = 16; // (32 bytes / 2 bytes per XOR) => 16 times
+ u32 index;
+ u16 checksum = 0;
+
+
+ // Clear first
+ ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
+
+ for (index = 0; index < count; index++) {
+ checksum ^= le16_to_cpu(*(usPtr + index));
+ }
+
+ ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
+}
+
+static void fill_txdesc_sectype(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
+{
+ if ((pattrib->encrypt > 0) && !pattrib->bswenc)
+ {
+ switch (pattrib->encrypt)
+ {
+ // SEC_TYPE
+ case _WEP40_:
+ case _WEP104_:
+ case _TKIP_:
+ case _TKIP_WTMIC_:
+ ptxdesc->sectype = 1;
+ break;
+
+ case _AES_:
+ ptxdesc->sectype = 3;
+ break;
+
+ case _NO_PRIVACY_:
+ default:
+ break;
+ }
+ }
+}
+
+static void fill_txdesc_vcs(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
+{
+ //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
+
+ switch (pattrib->vcs_mode)
+ {
+ case RTS_CTS:
+ ptxdesc->rtsen = 1;
+ break;
+
+ case CTS_TO_SELF:
+ ptxdesc->cts2self = 1;
+ break;
+
+ case NONE_VCS:
+ default:
+ break;
+ }
+
+ if (pattrib->vcs_mode)
+ ptxdesc->hw_rts_en = 1; // ENABLE HW RTS
+}
+
+static void fill_txdesc_phy(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
+{
+ //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
+
+ if (pattrib->ht_en)
+ {
+ if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
+ ptxdesc->data_bw = 1;
+
+ switch (pattrib->ch_offset)
+ {
+ case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
+ ptxdesc->data_sc = 0;
+ break;
+
+ case HAL_PRIME_CHNL_OFFSET_LOWER:
+ ptxdesc->data_sc = 1;
+ break;
+
+ case HAL_PRIME_CHNL_OFFSET_UPPER:
+ ptxdesc->data_sc = 2;
+ break;
+
+ default:
+ ptxdesc->data_sc = 3; // Duplicate
+ break;
+ }
+ }
+}
+#endif
+
+void rtl8188es_fill_default_txdesc(
+ struct xmit_frame *pxmitframe,
+ u8 *pbuf)
+{
+ PADAPTER padapter;
+ HAL_DATA_TYPE *pHalData;
+ struct mlme_ext_priv *pmlmeext;
+ struct mlme_ext_info *pmlmeinfo;
+ struct dm_priv *pdmpriv;
+ struct pkt_attrib *pattrib;
+ PTXDESC ptxdesc;
+ s32 bmcst;
+
+
+ padapter = pxmitframe->padapter;
+ pHalData = GET_HAL_DATA(padapter);
+ //pdmpriv = &pHalData->dmpriv;
+ pmlmeext = &padapter->mlmeextpriv;
+ pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ pattrib = &pxmitframe->attrib;
+ bmcst = IS_MCAST(pattrib->ra);
+
+ ptxdesc = (PTXDESC)pbuf;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(rtw_buddy_adapter_up(padapter) && padapter->adapter_type > PRIMARY_ADAPTER)
+ pHalData = GET_HAL_DATA(padapter->pbuddy_adapter);
+#endif //CONFIG_CONCURRENT_MODE
+
+ if (pxmitframe->frame_tag == DATA_FRAMETAG)
+ {
+ ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
+
+ if (pattrib->ampdu_en == _TRUE)
+ ptxdesc->agg_en = 1; // AGG EN
+ else
+ ptxdesc->bk = 1; // AGG BK
+
+ ptxdesc->qsel = pattrib->qsel;
+ ptxdesc->rate_id = pattrib->raid;
+
+ fill_txdesc_sectype(pattrib, ptxdesc);
+
+ ptxdesc->seq = pattrib->seqnum;
+
+ //todo: qos_en
+
+ ptxdesc->userate = 1; // driver uses rate
+
+ if ((pattrib->ether_type != 0x888e) &&
+ (pattrib->ether_type != 0x0806) &&
+ (pattrib->dhcp_pkt != 1))
+ {
+ // Non EAP & ARP & DHCP type data packet
+
+ fill_txdesc_vcs(pattrib, ptxdesc);
+ fill_txdesc_phy(pattrib, ptxdesc);
+
+ ptxdesc->rtsrate = 8; // RTS Rate=24M
+ ptxdesc->data_ratefb_lmt = 0x1F;
+ ptxdesc->rts_ratefb_lmt = 0xF;
+ #if (RATE_ADAPTIVE_SUPPORT == 1)
+ if(pattrib->ht_en){
+ ptxdesc->sgi = ODM_RA_GetShortGI_8188E(&pHalData->odmpriv,pattrib->mac_id);
+ }
+ ptxdesc->datarate = ODM_RA_GetDecisionRate_8188E(&pHalData->odmpriv,pattrib->mac_id);
+
+ //for debug
+ #if 0
+ if(padapter->fix_rate!= 0xFF){
+ ptxdesc->datarate = padapter->fix_rate;
+ }
+ #endif
+ #if (POWER_TRAINING_ACTIVE==1)
+ ptxdesc->pwr_status = ODM_RA_GetHwPwrStatus_8188E(&pHalData->odmpriv,pattrib->mac_id);
+ #endif
+ #else
+ ptxdesc->datarate = 0x13; //MCS7
+ ptxdesc->sgi = 1; // SGI
+ if(padapter->fix_rate!= 0xFF){//modify datat by iwpriv
+ ptxdesc->datarate = padapter->fix_rate;
+ }
+ #endif
+
+
+ }
+ else
+ {
+ // EAP data packet and ARP and DHCP packet.
+ // Use the 1M or 6M data rate to send the EAP/ARP packet.
+ // This will maybe make the handshake smooth.
+
+ ptxdesc->bk = 1; // AGG BK
+
+ if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
+ ptxdesc->data_short = 1;// DATA_SHORT
+
+ ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
+ }
+
+ ptxdesc->usb_txagg_num = pxmitframe->agg_num;
+ }
+ else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
+ {
+// RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__));
+
+ ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
+ ptxdesc->qsel = pattrib->qsel;
+ ptxdesc->rate_id = pattrib->raid; // Rate ID
+ ptxdesc->seq = pattrib->seqnum;
+ ptxdesc->userate = 1; // driver uses rate, 1M
+ ptxdesc->rty_lmt_en = 1; // retry limit enable
+ ptxdesc->data_rt_lmt = 6; // retry limit = 6
+
+#ifdef CONFIG_XMIT_ACK
+ //CCX-TXRPT ack for xmit mgmt frames.
+ if (pxmitframe->ack_report) {
+ #ifdef DBG_CCX
+ static u16 ccx_sw = 0x123;
+ txdesc_set_ccx_sw_88e(ptxdesc, ccx_sw);
+ DBG_871X("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
+ ccx_sw = (ccx_sw+1)%0xfff;
+ #endif
+ ptxdesc->ccx = 1;
+ }
+#endif //CONFIG_XMIT_ACK
+
+#ifdef CONFIG_INTEL_PROXIM
+ if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
+ DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
+ ptxdesc->datarate = pattrib->rate;
+ }
+ else
+#endif
+ {
+ ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
+ }
+ }
+ else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
+ {
+ RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
+ }
+#ifdef CONFIG_MP_INCLUDED
+ else if (pxmitframe->frame_tag == MP_FRAMETAG)
+ {
+ struct tx_desc *pdesc;
+
+ pdesc = (struct tx_desc*)ptxdesc;
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__));
+ fill_txdesc_for_mp(padapter, pdesc);
+
+ pdesc->txdw0 = le32_to_cpu(pdesc->txdw0);
+ pdesc->txdw1 = le32_to_cpu(pdesc->txdw1);
+ pdesc->txdw2 = le32_to_cpu(pdesc->txdw2);
+ pdesc->txdw3 = le32_to_cpu(pdesc->txdw3);
+ pdesc->txdw4 = le32_to_cpu(pdesc->txdw4);
+ pdesc->txdw5 = le32_to_cpu(pdesc->txdw5);
+ pdesc->txdw6 = le32_to_cpu(pdesc->txdw6);
+ pdesc->txdw7 = le32_to_cpu(pdesc->txdw7);
+ }
+#endif // CONFIG_MP_INCLUDED
+ else
+ {
+ RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
+
+ ptxdesc->macid = 4; // CAM_ID(MAC_ID)
+ ptxdesc->rate_id = 6; // Rate ID
+ ptxdesc->seq = pattrib->seqnum;
+ ptxdesc->userate = 1; // driver uses rate
+ ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
+ }
+
+ ptxdesc->pktlen = pattrib->last_txcmdsz;
+ if (pxmitframe->frame_tag == DATA_FRAMETAG){
+ #ifdef CONFIG_TX_EARLY_MODE
+ ptxdesc->offset = TXDESC_SIZE +EARLY_MODE_INFO_SIZE ;
+ ptxdesc->pkt_offset = 0x01;
+ #else
+ ptxdesc->offset = TXDESC_SIZE ;
+ ptxdesc->pkt_offset = 0;
+ #endif
+ }
+ else{
+ ptxdesc->offset = TXDESC_SIZE ;
+ }
+
+ if (bmcst) ptxdesc->bmc = 1;
+ ptxdesc->ls = 1;
+ ptxdesc->fs = 1;
+ ptxdesc->own = 1;
+
+ // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
+ // (1) The sequence number of each non-Qos frame / broadcast / multicast /
+ // mgnt frame should be controled by Hw because Fw will also send null data
+ // which we cannot control when Fw LPS enable.
+ // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
+ // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
+ // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
+ // 2010.06.23. Added by tynli.
+ if (!pattrib->qos_en)
+ {
+ // Hw set sequence number
+ ptxdesc->hwseq_en = 1; // HWSEQ_EN
+ ptxdesc->hwseq_sel = 0; // HWSEQ_SEL
+ }
+
+}
+
+/*
+ * Description:
+ *
+ * Parameters:
+ * pxmitframe xmitframe
+ * pbuf where to fill tx desc
+ */
+void rtl8188es_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
+{
+ struct tx_desc *pdesc;
+
+
+ pdesc = (struct tx_desc*)pbuf;
+ _rtw_memset(pdesc, 0, sizeof(struct tx_desc));
+
+ rtl8188es_fill_default_txdesc(pxmitframe, pbuf);
+
+ pdesc->txdw0 = cpu_to_le32(pdesc->txdw0);
+ pdesc->txdw1 = cpu_to_le32(pdesc->txdw1);
+ pdesc->txdw2 = cpu_to_le32(pdesc->txdw2);
+ pdesc->txdw3 = cpu_to_le32(pdesc->txdw3);
+ pdesc->txdw4 = cpu_to_le32(pdesc->txdw4);
+ pdesc->txdw5 = cpu_to_le32(pdesc->txdw5);
+ pdesc->txdw6 = cpu_to_le32(pdesc->txdw6);
+ pdesc->txdw7 = cpu_to_le32(pdesc->txdw7);
+
+ rtl8188e_cal_txdesc_chksum(pdesc);
+}
+
+static inline u32 ffaddr2deviceId(struct dvobj_priv *pdvobj, u32 addr)
+{
+ return pdvobj->Queue2Pipe[addr];
+}
+
+#ifdef CONFIG_SDIO_REDUCE_TX_POLLING
+static u8 rtl8188es_query_tx_freepage(_adapter *padapter, struct xmit_buf *pxmitbuf)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ u8 TxRequiredPageNum = 0;
+ u8 DedicatedPgNum = 0;
+ u8 RequiredPublicFreePgNum = 0;
+ u8 PageIdx = 0;
+ u8 CheckStep = 0;
+ u8 bResult = _TRUE;
+ u8 bUpdatePageNum = _FALSE;
+ u32 deviceId;
+
+
+ TxRequiredPageNum = pxmitbuf->pg_num;
+
+ deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);
+
+ // translate fifo addr to queue index
+ switch (deviceId) {
+ case WLAN_TX_HIQ_DEVICE_ID:
+ PageIdx = HI_QUEUE_IDX;
+ break;
+
+ case WLAN_TX_MIQ_DEVICE_ID:
+ PageIdx = MID_QUEUE_IDX;
+ break;
+
+ case WLAN_TX_LOQ_DEVICE_ID:
+ PageIdx = LOW_QUEUE_IDX;
+ break;
+ }
+
+ do {
+ if ((padapter->bSurpriseRemoved == _TRUE) || (padapter->bDriverStopped == _TRUE)){
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
+ ("%s: bSurpriseRemoved(update TX FIFO page)\n", __FUNCTION__));
+ break;
+ }
+
+ // The number of page which public page is included is available .
+ if ((pHalData->SdioTxFIFOFreePage[PageIdx]+pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) > (TxRequiredPageNum+1)) {
+ DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx];
+ if (TxRequiredPageNum <= DedicatedPgNum) {
+ pHalData->SdioTxFIFOFreePage[PageIdx] -= TxRequiredPageNum;
+ break;
+ } else {
+ pHalData->SdioTxFIFOFreePage[PageIdx] = 0;
+ RequiredPublicFreePgNum = TxRequiredPageNum - DedicatedPgNum;
+ pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum;
+ break;
+ }
+ } else { // Total number of page is NOT available, so update current FIFO status.
+ if (!bUpdatePageNum) {
+ bResult = HalQueryTxBufferStatus8189ESdio(padapter); // Set to default value.
+ bUpdatePageNum = _TRUE;
+ } else {
+ bResult = _FALSE;
+ }
+ }
+ }while(++CheckStep < 2); // step1: user page variables, step2: physical page number
+
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s(): HIQ(%#x), MIQ(%#x), LOQ(%#x), PUBQ(%#x)\n",
+ __FUNCTION__,
+ pHalData->SdioTxFIFOFreePage[HI_QUEUE_IDX],
+ pHalData->SdioTxFIFOFreePage[MID_QUEUE_IDX],
+ pHalData->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
+ pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
+
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s(): TxRequiredPageNum(%d) is available to send?(%d)\n",
+ __FUNCTION__, TxRequiredPageNum, bResult));
+
+ return bResult;
+}
+#else
+static u8 rtl8188es_query_tx_freepage(_adapter *padapter, struct xmit_buf *pxmitbuf)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ u8 TxRequiredPageNum = 0;
+ u8 DedicatedPgNum = 0;
+ u8 RequiredPublicFreePgNum = 0;
+ u8 PageIdx = 0;
+ u8 bResult = _TRUE;
+ u32 n, deviceId;
+
+ TxRequiredPageNum = pxmitbuf->pg_num;
+
+ deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);
+
+ // translate fifo addr to queue index
+ switch (deviceId) {
+ case WLAN_TX_HIQ_DEVICE_ID:
+ PageIdx = HI_QUEUE_IDX;
+ break;
+
+ case WLAN_TX_MIQ_DEVICE_ID:
+ PageIdx = MID_QUEUE_IDX;
+ break;
+
+ case WLAN_TX_LOQ_DEVICE_ID:
+ PageIdx = LOW_QUEUE_IDX;
+ break;
+ }
+
+ // check if hardware tx fifo page is enough
+ n = 0;
+ do {
+ if ((padapter->bSurpriseRemoved == _TRUE) || (padapter->bDriverStopped == _TRUE)){
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
+ ("%s: bSurpriseRemoved(update TX FIFO page)\n", __FUNCTION__));
+ break;
+ }
+
+ // The number of page which public page is included is available .
+ if ((pHalData->SdioTxFIFOFreePage[PageIdx]+pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) > (TxRequiredPageNum+1)) {
+ DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx];
+ if (TxRequiredPageNum <= DedicatedPgNum) {
+ pHalData->SdioTxFIFOFreePage[PageIdx] -= TxRequiredPageNum;
+ break;
+ } else {
+ pHalData->SdioTxFIFOFreePage[PageIdx] = 0;
+ RequiredPublicFreePgNum = TxRequiredPageNum - DedicatedPgNum;
+ pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum;
+ break;
+ }
+ }
+
+ n++;
+ if ((n % 60) == 0) {//or 80
+ //DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
+ // __func__, n, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]);
+ rtw_msleep_os(10);
+ rtw_yield_os();
+ }
+
+ // Total number of page is NOT available, so update current FIFO status
+ HalQueryTxBufferStatus8189ESdio(padapter);
+ } while (1);
+
+ return bResult;
+}
+#endif
+
+//todo: static
+s32 rtl8188es_dequeue_writeport(PADAPTER padapter, u8 *freePage)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct xmit_buf *pxmitbuf;
+ PADAPTER pri_padapter = padapter;
+ s32 ret = 0;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (padapter->adapter_type > 0)
+ pri_padapter = padapter->pbuddy_adapter;
+
+ if(rtw_buddy_adapter_up(padapter))
+ ret = check_buddy_fwstate( padapter, _FW_UNDER_SURVEY);
+#endif
+
+ ret = ret || check_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
+
+ if (_TRUE == ret)
+ pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
+ else
+ pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
+
+ if (pxmitbuf == NULL)
+ return _TRUE;
+
+query_free_page:
+ // check if hardware tx fifo page is enough
+ if( _FALSE == rtl8188es_query_tx_freepage(pri_padapter, pxmitbuf))
+ {
+ rtw_msleep_os(1);
+ goto query_free_page;
+ }
+
+ if ((padapter->bSurpriseRemoved == _TRUE)
+ || (padapter->bDriverStopped == _TRUE)
+#ifdef CONFIG_CONCURRENT_MODE
+ ||((padapter->pbuddy_adapter)
+ && ((padapter->pbuddy_adapter->bSurpriseRemoved) ||(padapter->pbuddy_adapter->bDriverStopped)))
+#endif
+ ){
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
+ ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__));
+ goto free_xmitbuf;
+ }
+
+ rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, (u8 *)pxmitbuf);
+
+free_xmitbuf:
+ //rtw_free_xmitframe(pxmitpriv, pframe);
+ //pxmitbuf->priv_data = NULL;
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+
+#ifdef CONFIG_SDIO_TX_TASKLET
+ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+#endif
+
+ return _FAIL;
+}
+
+/*
+ * Description
+ * Transmit xmitbuf to hardware tx fifo
+ *
+ * Return
+ * _SUCCESS ok
+ * _FAIL something error
+ */
+s32 rtl8188es_xmit_buf_handler(PADAPTER padapter)
+{
+ struct mlme_priv *pmlmepriv;
+ struct xmit_priv *pxmitpriv;
+ struct xmit_buf *pxmitbuf;
+ struct xmit_frame *pframe;
+ u8 *freePage;
+ u32 requiredPage;
+ u8 PageIdx , queue_empty;
+ _irqL irql;
+ u32 n;
+ s32 ret;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+#ifdef CONFIG_CONCURRENT_MODE
+ s32 buddy_rm_stop = _FAIL;
+#endif
+
+ pmlmepriv = &padapter->mlmepriv;
+ pxmitpriv = &padapter->xmitpriv;
+ freePage = pHalData->SdioTxFIFOFreePage;
+
+ ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
+ if (ret == _FAIL) {
+ RT_TRACE(_module_hal_xmit_c_, _drv_emerg_, ("down SdioXmitBufSema fail!\n"));
+ return _FAIL;
+ }
+
+//#ifdef CONFIG_CONCURRENT_MODE
+// if (padapter->pbuddy_adapter->bup){
+// if ((padapter->pbuddy_adapter->bSurpriseRemoved == _TRUE) ||
+// (padapter->pbuddy_adapter->bDriverStopped == _TRUE))
+// buddy_rm_stop = _TRUE;
+// }
+//#endif
+ if ((padapter->bSurpriseRemoved == _TRUE) ||
+ (padapter->bDriverStopped == _TRUE)
+//#ifdef CONFIG_CONCURRENT_MODE
+// ||(buddy_rm_stop == _TRUE)
+//#endif
+ ) {
+
+#ifdef CONFIG_LPS_LCLK
+ rtw_unregister_tx_alive(padapter);
+#endif
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
+ ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
+ __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
+ return _FAIL;
+ }
+
+#ifdef CONFIG_LPS_LCLK
+ ret = rtw_register_tx_alive(padapter);
+ if (ret != _SUCCESS) return _SUCCESS;
+#endif
+
+ do {
+ queue_empty = rtl8188es_dequeue_writeport(padapter, freePage);
+// dump secondary adapter xmitbuf
+#ifdef CONFIG_CONCURRENT_MODE
+ if(rtw_buddy_adapter_up(padapter))
+ queue_empty &= rtl8188es_dequeue_writeport(padapter->pbuddy_adapter, freePage);
+#endif
+
+ } while ( !queue_empty);
+
+#ifdef CONFIG_LPS_LCLK
+ rtw_unregister_tx_alive(padapter);
+#endif
+ return _SUCCESS;
+}
+
+#if 0
+/*
+ * Description:
+ * Aggregation packets and send to hardware
+ *
+ * Return:
+ * 0 Success
+ * -1 Hardware resource(TX FIFO) not ready
+ * -2 Software resource(xmitbuf) not ready
+ */
+#ifdef CONFIG_TX_EARLY_MODE
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ #define EARLY_MODE_MAX_PKT_NUM 10
+#else
+ #define EARLY_MODE_MAX_PKT_NUM 5
+#endif
+
+
+struct EMInfo{
+ u8 EMPktNum;
+ u16 EMPktLen[EARLY_MODE_MAX_PKT_NUM];
+};
+
+
+void
+InsertEMContent_8188E(
+ struct EMInfo *pEMInfo,
+ IN pu1Byte VirtualAddress)
+{
+
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ u1Byte index=0;
+ u4Byte dwtmp=0;
+#endif
+
+ _rtw_memset(VirtualAddress, 0, EARLY_MODE_INFO_SIZE);
+ if(pEMInfo->EMPktNum==0)
+ return;
+
+ #ifdef DBG_EMINFO
+ {
+ int i;
+ DBG_8192C("\n%s ==> pEMInfo->EMPktNum =%d\n",__FUNCTION__,pEMInfo->EMPktNum);
+ for(i=0;i< EARLY_MODE_MAX_PKT_NUM;i++){
+ DBG_8192C("%s ==> pEMInfo->EMPktLen[%d] =%d\n",__FUNCTION__,i,pEMInfo->EMPktLen[i]);
+ }
+
+ }
+ #endif
+
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
+
+ if(pEMInfo->EMPktNum == 1){
+ dwtmp = pEMInfo->EMPktLen[0];
+ }else{
+ dwtmp = pEMInfo->EMPktLen[0];
+ dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+ dwtmp += pEMInfo->EMPktLen[1];
+ }
+ SET_EARLYMODE_LEN0(VirtualAddress, dwtmp);
+ if(pEMInfo->EMPktNum <= 3){
+ dwtmp = pEMInfo->EMPktLen[2];
+ }else{
+ dwtmp = pEMInfo->EMPktLen[2];
+ dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+ dwtmp += pEMInfo->EMPktLen[3];
+ }
+ SET_EARLYMODE_LEN1(VirtualAddress, dwtmp);
+ if(pEMInfo->EMPktNum <= 5){
+ dwtmp = pEMInfo->EMPktLen[4];
+ }else{
+ dwtmp = pEMInfo->EMPktLen[4];
+ dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+ dwtmp += pEMInfo->EMPktLen[5];
+ }
+ SET_EARLYMODE_LEN2_1(VirtualAddress, dwtmp&0xF);
+ SET_EARLYMODE_LEN2_2(VirtualAddress, dwtmp>>4);
+ if(pEMInfo->EMPktNum <= 7){
+ dwtmp = pEMInfo->EMPktLen[6];
+ }else{
+ dwtmp = pEMInfo->EMPktLen[6];
+ dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+ dwtmp += pEMInfo->EMPktLen[7];
+ }
+ SET_EARLYMODE_LEN3(VirtualAddress, dwtmp);
+ if(pEMInfo->EMPktNum <= 9){
+ dwtmp = pEMInfo->EMPktLen[8];
+ }else{
+ dwtmp = pEMInfo->EMPktLen[8];
+ dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+ dwtmp += pEMInfo->EMPktLen[9];
+ }
+ SET_EARLYMODE_LEN4(VirtualAddress, dwtmp);
+#else
+ SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
+ SET_EARLYMODE_LEN0(VirtualAddress, pEMInfo->EMPktLen[0]);
+ SET_EARLYMODE_LEN1(VirtualAddress, pEMInfo->EMPktLen[1]);
+ SET_EARLYMODE_LEN2_1(VirtualAddress, pEMInfo->EMPktLen[2]&0xF);
+ SET_EARLYMODE_LEN2_2(VirtualAddress, pEMInfo->EMPktLen[2]>>4);
+ SET_EARLYMODE_LEN3(VirtualAddress, pEMInfo->EMPktLen[3]);
+ SET_EARLYMODE_LEN4(VirtualAddress, pEMInfo->EMPktLen[4]);
+#endif
+ //RT_PRINT_DATA(COMP_SEND, DBG_LOUD, "EMHdr:", VirtualAddress, 8);
+
+}
+
+
+
+void UpdateEarlyModeInfo8188E(struct xmit_priv *pxmitpriv,struct xmit_buf *pxmitbuf )
+{
+ //_adapter *padapter, struct xmit_frame *pxmitframe,struct tx_servq *ptxservq
+ int index,j;
+ u16 offset,pktlen;
+ PTXDESC ptxdesc;
+
+ u8 *pmem,*pEMInfo_mem;
+ s8 node_num_0=0,node_num_1=0;
+ struct EMInfo eminfo;
+ struct agg_pkt_info *paggpkt;
+ struct xmit_frame *pframe = (struct xmit_frame*)pxmitbuf->priv_data;
+ pmem= pframe->buf_addr;
+
+ #ifdef DBG_EMINFO
+ DBG_8192C("\n%s ==> agg_num:%d\n",__FUNCTION__, pframe->agg_num);
+ for(index=0;index<pframe->agg_num;index++){
+ offset = pxmitpriv->agg_pkt[index].offset;
+ pktlen = pxmitpriv->agg_pkt[index].pkt_len;
+ DBG_8192C("%s ==> agg_pkt[%d].offset=%d\n",__FUNCTION__,index,offset);
+ DBG_8192C("%s ==> agg_pkt[%d].pkt_len=%d\n",__FUNCTION__,index,pktlen);
+ }
+ #endif
+
+ if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM)
+ {
+ node_num_0 = pframe->agg_num;
+ node_num_1= EARLY_MODE_MAX_PKT_NUM-1;
+ }
+
+ for(index=0;index<pframe->agg_num;index++){
+ offset = pxmitpriv->agg_pkt[index].offset;
+ pktlen = pxmitpriv->agg_pkt[index].pkt_len;
+
+ _rtw_memset(&eminfo,0,sizeof(struct EMInfo));
+ if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM){
+ if(node_num_0 > EARLY_MODE_MAX_PKT_NUM){
+ eminfo.EMPktNum = EARLY_MODE_MAX_PKT_NUM;
+ node_num_0--;
+ }
+ else{
+ eminfo.EMPktNum = node_num_1;
+ node_num_1--;
+ }
+ }
+ else{
+ eminfo.EMPktNum = pframe->agg_num-(index+1);
+ }
+ for(j=0;j< eminfo.EMPktNum ;j++){
+ eminfo.EMPktLen[j] = pxmitpriv->agg_pkt[index+1+j].pkt_len+4;//CRC
+ }
+
+ if(pmem){
+ ptxdesc = (PTXDESC)(pmem+offset);
+ pEMInfo_mem = pmem+offset+TXDESC_SIZE;
+ #ifdef DBG_EMINFO
+ DBG_8192C("%s ==> desc.pkt_len=%d\n",__FUNCTION__,ptxdesc->pktlen);
+ #endif
+ InsertEMContent_8188E(&eminfo,pEMInfo_mem);
+ }
+
+
+ }
+ _rtw_memset(pxmitpriv->agg_pkt,0,sizeof(struct agg_pkt_info)*MAX_AGG_PKT_NUM);
+
+}
+#endif
+
+#endif
+
+#ifdef CONFIG_SDIO_TX_TASKLET
+static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv)
+{
+ s32 ret;
+ _irqL irqL;
+ struct xmit_buf *pxmitbuf;
+ struct hw_xmit *phwxmit = pxmitpriv->hwxmits;
+ struct tx_servq *ptxservq = NULL;
+ _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
+ struct xmit_frame *pxmitframe = NULL, *pfirstframe = NULL;
+ u32 pbuf = 0; // next pkt address
+ u32 pbuf_tail = 0; // last pkt tail
+ u32 txlen = 0; //packet length, except TXDESC_SIZE and PKT_OFFSET
+ u32 total_len = 0;
+ u8 ac_index = 0;
+ u8 bfirst = _TRUE;//first aggregation xmitframe
+ u8 bulkstart = _FALSE;
+#ifdef CONFIG_TX_EARLY_MODE
+ u8 pkt_index=0;
+#endif
+
+ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
+ if (pxmitbuf == NULL) {
+ RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: xmit_buf is not enough!\n", __FUNCTION__));
+ return _FALSE;
+ }
+
+ do {
+ //3 1. pick up first frame
+ if(bfirst)
+ {
+ pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
+ if (pxmitframe == NULL) {
+ // no more xmit frame, release xmit buffer
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+ return _FALSE;
+ }
+
+ pxmitframe->pxmitbuf = pxmitbuf;
+ pxmitframe->buf_addr = pxmitbuf->pbuf;
+ pxmitbuf->priv_data = pxmitframe;
+ pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
+
+ pfirstframe = pxmitframe;
+
+ _enter_critical_bh(&pxmitpriv->lock, &irqL);
+ ptxservq = rtw_get_sta_pending(padapter, pfirstframe->attrib.psta, pfirstframe->attrib.priority, (u8 *)(&ac_index));
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);
+ }
+ //3 2. aggregate same priority and same DA(AP or STA) frames
+ else
+ {
+ // dequeue same priority packet from station tx queue
+ _enter_critical_bh(&pxmitpriv->lock, &irqL);
+
+ if (_rtw_queue_empty(&ptxservq->sta_pending) == _FALSE)
+ {
+ xmitframe_phead = get_list_head(&ptxservq->sta_pending);
+ xmitframe_plist = get_next(xmitframe_phead);
+
+ pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
+
+ // check xmit_buf size enough or not
+ txlen = TXDESC_SIZE +
+ #ifdef CONFIG_TX_EARLY_MODE
+ EARLY_MODE_INFO_SIZE +
+ #endif
+ rtw_wlan_pkt_size(pxmitframe);
+
+ if (pbuf + _RND8(txlen) > MAX_XMITBUF_SZ)
+ {
+ bulkstart = _TRUE;
+ }
+ else
+ {
+ rtw_list_delete(&pxmitframe->list);
+ ptxservq->qcnt--;
+ phwxmit[ac_index].accnt--;
+
+ //Remove sta node when there is no pending packets.
+ if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
+ rtw_list_delete(&ptxservq->tx_pending);
+ }
+ }
+ else
+ {
+ bulkstart = _TRUE;
+ }
+
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);
+
+ if(bulkstart)
+ {
+ break;
+ }
+
+ pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
+
+ pxmitframe->agg_num = 0; // not first frame of aggregation
+ }
+
+ ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
+ if (ret == _FAIL) {
+ DBG_871X("%s: coalesce FAIL!", __FUNCTION__);
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ continue;
+ }
+
+ // always return ndis_packet after rtw_xmitframe_coalesce
+ //rtw_os_xmit_complete(padapter, pxmitframe);
+
+#ifdef CONFIG_TX_EARLY_MODE
+ pxmitpriv->agg_pkt[pkt_index].pkt_len = pxmitframe->attrib.last_txcmdsz; //get from rtw_xmitframe_coalesce
+ pxmitpriv->agg_pkt[pkt_index].offset = _RND8(pxmitframe->attrib.last_txcmdsz+ TXDESC_SIZE+EARLY_MODE_INFO_SIZE);
+ pkt_index++;
+#endif
+
+ if(bfirst)
+ {
+ txlen = TXDESC_SIZE +
+ #ifdef CONFIG_TX_EARLY_MODE
+ EARLY_MODE_INFO_SIZE +
+ #endif
+ pxmitframe->attrib.last_txcmdsz;
+
+ total_len = txlen;
+
+ pxmitframe->pg_num = (txlen + 127)/128;
+ pxmitbuf->pg_num = (txlen + 127)/128;
+ pbuf_tail = txlen;
+ pbuf = _RND8(pbuf_tail);
+ bfirst = _FALSE;
+ }
+ else
+ {
+ rtl8188es_update_txdesc(pxmitframe, pxmitframe->buf_addr);
+
+ // don't need xmitframe any more
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ pxmitframe->pg_num = (txlen + 127)/128;
+ //pfirstframe->pg_num += pxmitframe->pg_num;
+ pxmitbuf->pg_num += (txlen + 127)/128;
+
+ total_len += txlen;
+
+ // handle pointer and stop condition
+ pbuf_tail = pbuf + txlen;
+ pbuf = _RND8(pbuf_tail);
+
+ pfirstframe->agg_num++;
+ #ifdef SDIO_TX_AGG_MAX
+ if(pfirstframe->agg_num >= SDIO_TX_AGG_MAX)
+ break;
+ #endif
+ }
+ }while(1);
+
+ //3 3. update first frame txdesc
+ rtl8188es_update_txdesc(pfirstframe, pfirstframe->buf_addr);
+#ifdef CONFIG_TX_EARLY_MODE
+ UpdateEarlyModeInfo8188E(pxmitpriv,pxmitbuf );
+#endif
+
+ //
+ pxmitbuf->agg_num = pfirstframe->agg_num;
+ pxmitbuf->priv_data = NULL;
+
+ //3 4. write xmit buffer to USB FIFO
+ pxmitbuf->len = pbuf_tail;
+ enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+
+ //3 5. update statisitc
+ rtw_count_tx_stats(padapter, pfirstframe, total_len);
+
+ rtw_free_xmitframe(pxmitpriv, pfirstframe);
+
+ //rtw_yield_os();
+
+ return _TRUE;
+}
+
+void rtl8188es_xmit_tasklet(void *priv)
+{
+ int ret = _FALSE;
+ _adapter *padapter = (_adapter*)priv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ while(1)
+ {
+ if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE) || (padapter->bWritePortCancel == _TRUE))
+ {
+ DBG_871X("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
+ break;
+ }
+
+ ret = xmit_xmitframes(padapter, pxmitpriv);
+ if(ret==_FALSE)
+ break;
+
+ }
+}
+#else
+static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv)
+{
+ u32 err, agg_num=0;
+ u8 pkt_index=0;
+ struct hw_xmit *hwxmits, *phwxmit;
+ u8 idx, hwentry;
+ _irqL irql;
+ struct tx_servq *ptxservq;
+ _list *sta_plist, *sta_phead, *frame_plist, *frame_phead;
+ struct xmit_frame *pxmitframe;
+ _queue *pframe_queue;
+ struct xmit_buf *pxmitbuf;
+ u32 txlen;
+ s32 ret;
+ int inx[4];
+
+
+ err = 0;
+ hwxmits = pxmitpriv->hwxmits;
+ hwentry = pxmitpriv->hwxmit_entry;
+ ptxservq = NULL;
+ pxmitframe = NULL;
+ pframe_queue = NULL;
+ pxmitbuf = NULL;
+
+ if (padapter->registrypriv.wifi_spec == 1) {
+ for(idx=0; idx<4; idx++)
+ inx[idx] = pxmitpriv->wmm_para_seq[idx];
+ } else {
+ inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
+ }
+
+ // 0(VO), 1(VI), 2(BE), 3(BK)
+ for (idx = 0; idx < hwentry; idx++)
+ {
+ phwxmit = hwxmits + inx[idx];
+
+// _enter_critical(&hwxmits->sta_queue->lock, &irqL0);
+ _enter_critical_bh(&pxmitpriv->lock, &irql);
+
+ sta_phead = get_list_head(phwxmit->sta_queue);
+ sta_plist = get_next(sta_phead);
+
+ while (rtw_end_of_queue_search(sta_phead, sta_plist) == _FALSE)
+ {
+ ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
+
+ sta_plist = get_next(sta_plist);
+
+ pframe_queue = &ptxservq->sta_pending;
+
+// _enter_critical(&pframe_queue->lock, &irqL1);
+ //_enter_critical_bh(&pxmitpriv->lock, &irql);
+
+ frame_phead = get_list_head(pframe_queue);
+ frame_plist = get_next(frame_phead);
+
+ while (rtw_end_of_queue_search(frame_phead, frame_plist) == _FALSE)
+ {
+ pxmitframe = LIST_CONTAINOR(frame_plist, struct xmit_frame, list);
+ // check xmit_buf size enough or not
+ #ifdef CONFIG_TX_EARLY_MODE
+ txlen = TXDESC_SIZE +EARLY_MODE_INFO_SIZE+ rtw_wlan_pkt_size(pxmitframe);
+ #else
+ txlen = TXDESC_SIZE + rtw_wlan_pkt_size(pxmitframe);
+ #endif
+ if ((NULL == pxmitbuf) ||
+ ((pxmitbuf->ptail + txlen) > pxmitbuf->pend)
+ #ifdef SDIO_TX_AGG_MAX
+ || (agg_num>= SDIO_TX_AGG_MAX)
+ #endif
+ )
+ {
+ if (pxmitbuf) {
+ struct xmit_frame *pframe;
+ pframe = (struct xmit_frame*)pxmitbuf->priv_data;
+ pframe->agg_num = agg_num;
+ pxmitbuf->agg_num = agg_num;
+ //DBG_8192C("==> agg_num:%d\n",agg_num);
+ rtl8188es_update_txdesc(pframe, pframe->buf_addr);
+ #ifdef CONFIG_TX_EARLY_MODE
+ UpdateEarlyModeInfo8188E(pxmitpriv, pxmitbuf);
+ #endif
+ rtw_free_xmitframe(pxmitpriv, pframe);
+ pxmitbuf->priv_data = NULL;
+ enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+ //rtw_yield_os();
+ }
+
+ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
+ if (pxmitbuf == NULL) {
+ RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: xmit_buf is not enough!\n", __FUNCTION__));
+ err = -2;
+ break;
+ }
+ agg_num = 0;
+ pkt_index =0;
+ }
+
+ // ok to send, remove frame from queue
+
+
+ frame_plist = get_next(frame_plist);
+ rtw_list_delete(&pxmitframe->list);
+ ptxservq->qcnt--;
+ phwxmit->accnt--;
+
+
+ if (agg_num == 0) {
+ pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
+ pxmitbuf->priv_data = (u8*)pxmitframe;
+ }
+
+ // coalesce the xmitframe to xmitbuf
+ pxmitframe->pxmitbuf = pxmitbuf;
+ pxmitframe->buf_addr = pxmitbuf->ptail;
+
+ ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
+ if (ret == _FAIL) {
+ RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: coalesce FAIL!", __FUNCTION__));
+ // Todo: error handler
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ } else {
+ agg_num++;
+ if (agg_num != 1)
+ rtl8188es_update_txdesc(pxmitframe, pxmitframe->buf_addr);
+ rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz);
+ #ifdef CONFIG_TX_EARLY_MODE
+ txlen = TXDESC_SIZE+ EARLY_MODE_INFO_SIZE+ pxmitframe->attrib.last_txcmdsz;
+ #else
+ txlen = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
+ #endif
+ pxmitframe->pg_num = (txlen + 127)/128;
+ pxmitbuf->pg_num += (txlen + 127)/128;
+ //if (agg_num != 1)
+ //((struct xmit_frame*)pxmitbuf->priv_data)->pg_num += pxmitframe->pg_num;
+
+ #ifdef CONFIG_TX_EARLY_MODE
+ pxmitpriv->agg_pkt[pkt_index].pkt_len = pxmitframe->attrib.last_txcmdsz; //get from rtw_xmitframe_coalesce
+ pxmitpriv->agg_pkt[pkt_index].offset = _RND8(pxmitframe->attrib.last_txcmdsz+ TXDESC_SIZE+EARLY_MODE_INFO_SIZE);
+ #endif
+
+ pkt_index++;
+ pxmitbuf->ptail += _RND(txlen, 8); // round to 8 bytes alignment
+ pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen;
+ }
+
+ if (agg_num != 1)
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ pxmitframe = NULL;
+ }
+
+ if (_rtw_queue_empty(pframe_queue)) {
+ rtw_list_delete(&ptxservq->tx_pending);
+ }
+
+// _exit_critical(&pframe_queue->lock, &irqL1);
+ //_exit_critical_bh(&pxmitpriv->lock, &irql);
+
+ }
+
+// _exit_critical(&hwxmits->sta_queue->lock, &irqL0);
+ _exit_critical_bh(&pxmitpriv->lock, &irql);
+
+ // dump xmit_buf to hw tx fifo
+ if (pxmitbuf)
+ {
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("pxmitbuf->len=%d enqueue\n",pxmitbuf->len));
+
+ if (pxmitbuf->len > 0) {
+ struct xmit_frame *pframe;
+ pframe = (struct xmit_frame*)pxmitbuf->priv_data;
+ pframe->agg_num = agg_num;
+ pxmitbuf->agg_num = agg_num;
+ rtl8188es_update_txdesc(pframe, pframe->buf_addr);
+ #ifdef CONFIG_TX_EARLY_MODE
+ UpdateEarlyModeInfo8188E(pxmitpriv,pxmitbuf );
+ #endif
+ rtw_free_xmitframe(pxmitpriv, pframe);
+ pxmitbuf->priv_data = NULL;
+ enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+ rtw_yield_os();
+ }
+ else
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+
+ pxmitbuf = NULL;
+
+ }
+
+ }
+
+ return err;
+
+}
+
+/*
+ * Description
+ * Transmit xmitframe from queue
+ *
+ * Return
+ * _SUCCESS ok
+ * _FAIL something error
+ */
+s32 rtl8188es_xmit_handler(PADAPTER padapter)
+{
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv ;
+ s32 ret;
+ _irqL irql;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+//#ifdef CONFIG_CONCURRENT_MODE
+// s32 buddy_rm_stop = _FAIL;
+//#endif
+
+
+wait:
+ ret = _rtw_down_sema(&pHalData->SdioXmitSema);
+ if (_FAIL == ret) {
+ RT_TRACE(_module_hal_xmit_c_, _drv_emerg_, ("%s: down sema fail!\n", __FUNCTION__));
+ return _FAIL;
+ }
+
+next:
+//#ifdef CONFIG_CONCURRENT_MODE
+// if (padapter->pbuddy_adapter){
+// if ((padapter->pbuddy_adapter->bSurpriseRemoved == _TRUE) ||
+// (padapter->pbuddy_adapter->bDriverStopped == _TRUE))
+// buddy_rm_stop = _TRUE;
+// }
+//#endif
+ if ((padapter->bSurpriseRemoved == _TRUE) ||
+ (padapter->bDriverStopped == _TRUE)
+//#ifdef CONFIG_CONCURRENT_MODE
+// ||(buddy_rm_stop == _TRUE)
+//#endif
+ ) {
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
+ ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
+ __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
+ return _FAIL;
+ }
+ _enter_critical_bh(&pxmitpriv->lock, &irql);
+ ret = rtw_txframes_pending(padapter);
+ _exit_critical_bh(&pxmitpriv->lock, &irql);
+ if (ret == 0) {
+ return _SUCCESS;
+ }
+ // dequeue frame and write to hardware
+
+ ret = xmit_xmitframes(padapter, pxmitpriv);
+ if (ret == -2) {
+ rtw_msleep_os(1);
+ goto next;
+ }
+ _enter_critical_bh(&pxmitpriv->lock, &irql);
+ ret = rtw_txframes_pending(padapter);
+ _exit_critical_bh(&pxmitpriv->lock, &irql);
+ if (ret == 1) {
+ rtw_msleep_os(1);
+ goto next;
+ }
+
+ return _SUCCESS;
+}
+
+thread_return rtl8188es_xmit_thread(thread_context context)
+{
+ s32 ret;
+ PADAPTER padapter= (PADAPTER)context;
+ struct xmit_priv *pxmitpriv= &padapter->xmitpriv;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ ret = _SUCCESS;
+
+ thread_enter("RTWHALXT");
+
+ DBG_871X("start %s\n", __FUNCTION__);
+
+ do {
+ ret = rtl8188es_xmit_handler(padapter);
+ if (signal_pending(current)) {
+ flush_signals(current);
+ }
+ } while (_SUCCESS == ret);
+
+ _rtw_up_sema(&pHalData->SdioXmitTerminateSema);
+
+ RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("-%s\n", __FUNCTION__));
+ DBG_871X("exit %s\n", __FUNCTION__);
+
+ thread_exit();
+}
+#endif
+
+#ifdef CONFIG_IOL_IOREG_CFG_DBG
+#include <rtw_iol.h>
+#endif
+s32 rtl8188es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe)
+{
+ s32 ret = _SUCCESS;
+ struct pkt_attrib *pattrib;
+ struct xmit_buf *pxmitbuf;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ u8 pattrib_subtype;
+
+ RT_TRACE(_module_hal_xmit_c_, _drv_info_, ("+%s\n", __FUNCTION__));
+
+ pattrib = &pmgntframe->attrib;
+ pxmitbuf = pmgntframe->pxmitbuf;
+
+ rtl8188es_update_txdesc(pmgntframe, pmgntframe->buf_addr);
+
+ pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
+ //pmgntframe->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size
+ pxmitbuf->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size
+ pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len;
+ pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe);
+
+ rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz);
+ pattrib_subtype = pattrib->subtype;
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+
+ pxmitbuf->priv_data = NULL;
+
+ if((pattrib_subtype == WIFI_BEACON) || (GetFrameSubType(pframe)==WIFI_BEACON)) //dump beacon directly
+ {
+#ifdef CONFIG_IOL_IOREG_CFG_DBG
+ rtw_IOL_cmd_buf_dump(padapter,pxmitbuf->len,pxmitbuf->pdata);
+#endif
+
+ rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, (u8 *)pxmitbuf);
+
+ //rtw_free_xmitframe(pxmitpriv, pmgntframe);
+
+ //pxmitbuf->priv_data = NULL;
+
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+ }
+ else
+ {
+ enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+ }
+
+ if (ret != _SUCCESS)
+ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
+
+ return ret;
+}
+
+/*
+ * Description:
+ * Handle xmitframe(packet) come from rtw_xmit()
+ *
+ * Return:
+ * _TRUE dump packet directly ok
+ * _FALSE enqueue, temporary can't transmit packets to hardware
+ */
+s32 rtl8188es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe)
+{
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ _irqL irql;
+ s32 err;
+
+ //pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
+
+#ifdef CONFIG_80211N_HT
+ if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
+ (pxmitframe->attrib.ether_type != 0x0806) &&
+ (pxmitframe->attrib.ether_type != 0x888e) &&
+ (pxmitframe->attrib.dhcp_pkt != 1))
+ {
+ if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
+ rtw_issue_addbareq_cmd(padapter, pxmitframe);
+ }
+#endif
+
+ _enter_critical_bh(&pxmitpriv->lock, &irql);
+ err = rtw_xmitframe_enqueue(padapter, pxmitframe);
+ _exit_critical_bh(&pxmitpriv->lock, &irql);
+ if (err != _SUCCESS) {
+ RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: enqueue xmitframe fail\n",__FUNCTION__));
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ // Trick, make the statistics correct
+ pxmitpriv->tx_pkts--;
+ pxmitpriv->tx_drop++;
+ return _TRUE;
+ }
+
+#ifdef CONFIG_SDIO_TX_TASKLET
+ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+#else
+ _rtw_up_sema(&pHalData->SdioXmitSema);
+#endif
+
+ return _FALSE;
+}
+
+s32 rtl8188es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ s32 err;
+
+ if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
+ {
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ // Trick, make the statistics correct
+ pxmitpriv->tx_pkts--;
+ pxmitpriv->tx_drop++;
+ }
+ else
+ {
+#ifdef CONFIG_SDIO_TX_TASKLET
+ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+#else
+ _rtw_up_sema(&pHalData->SdioXmitSema);
+#endif
+ }
+
+ return err;
+
+}
+
+
+/*
+ * Return
+ * _SUCCESS start thread ok
+ * _FAIL start thread fail
+ *
+ */
+s32 rtl8188es_init_xmit_priv(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+#ifdef CONFIG_SDIO_TX_TASKLET
+#ifdef PLATFORM_LINUX
+ tasklet_init(&pxmitpriv->xmit_tasklet,
+ (void(*)(unsigned long))rtl8188es_xmit_tasklet,
+ (unsigned long)padapter);
+#endif
+#else //CONFIG_SDIO_TX_TASKLET
+
+ _rtw_init_sema(&pHalData->SdioXmitSema, 0);
+ _rtw_init_sema(&pHalData->SdioXmitTerminateSema, 0);
+#endif //CONFIG_SDIO_TX_TASKLET
+
+ _rtw_spinlock_init(&pHalData->SdioTxFIFOFreePageLock);
+
+#ifdef CONFIG_TX_EARLY_MODE
+ pHalData->bEarlyModeEnable = padapter->registrypriv.early_mode;
+#endif
+
+ return _SUCCESS;
+}
+
+void rtl8188es_free_xmit_priv(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ _rtw_spinlock_free(&pHalData->SdioTxFIFOFreePageLock);
+}
+
diff --git a/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_halinit.c b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_halinit.c
new file mode 100755
index 00000000..4a607a59
--- /dev/null
+++ b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_halinit.c
@@ -0,0 +1,4179 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+#define _SDIO_HALINIT_C_
+
+#include <drv_conf.h>
+#include <osdep_service.h>
+#include <drv_types.h>
+
+#ifndef CONFIG_SDIO_HCI
+#error "CONFIG_SDIO_HCI shall be on!\n"
+#endif
+
+#include <rtw_efuse.h>
+#include <rtl8188e_hal.h>
+#include <rtl8188e_led.h>
+#include <HalPwrSeqCmd.h>
+#include <Hal8188EPwrSeq.h>
+#include <sdio_ops.h>
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#endif //CONFIG_EFUSE_CONFIG_FILE
+
+
+/*
+ * Description:
+ * Call this function to make sure power on successfully
+ *
+ * Return:
+ * _SUCCESS enable success
+ * _FAIL enable fail
+ */
+
+static int PowerOnCheck(PADAPTER padapter)
+{
+ u32 val_offset0, val_offset1, val_offset2, val_offset3;
+ u32 val_mix = 0;
+ u32 res = 0;
+ u8 ret = _FAIL;
+ int index = 0;
+
+ val_offset0 = rtw_read8(padapter, REG_CR);
+ val_offset1 = rtw_read8(padapter, REG_CR+1);
+ val_offset2 = rtw_read8(padapter, REG_CR+2);
+ val_offset3 = rtw_read8(padapter, REG_CR+3);
+
+ if (val_offset0 == 0xEA || val_offset1 == 0xEA ||
+ val_offset2 == 0xEA || val_offset3 ==0xEA) {
+ DBG_871X("%s: power on fail, do Power on again\n", __func__);
+ return ret;
+ }
+
+ val_mix = val_offset3 << 24 | val_mix;
+ val_mix = val_offset2 << 16 | val_mix;
+ val_mix = val_offset1 << 8 | val_mix;
+ val_mix = val_offset0 | val_mix;
+
+ res = rtw_read32(padapter, REG_CR);
+
+ DBG_871X("%s: val_mix:0x%08x, res:0x%08x\n", __func__, val_mix, res);
+
+ while(index < 100) {
+ if (res == val_mix) {
+ DBG_871X("%s: 0x100 the result of cmd52 and cmd53 is the same.\n", __func__);
+ ret = _SUCCESS;
+ break;
+ } else {
+ DBG_871X("%s: 0x100 cmd52 and cmd53 is not the same(index:%d).\n", __func__, index);
+ res = rtw_read32(padapter, REG_CR);
+ index ++;
+ ret = _FAIL;
+ }
+ }
+
+ if (ret) {
+ index = 0;
+ while(index < 100) {
+ rtw_write32(padapter, 0x1B8, 0x12345678);
+ res = rtw_read32(padapter, 0x1B8);
+ if (res == 0x12345678) {
+ DBG_871X("%s: 0x1B8 test Pass.\n", __func__);
+ ret = _SUCCESS;
+ break;
+ } else {
+ index ++;
+ DBG_871X("%s: 0x1B8 test Fail(index: %d).\n", __func__, index);
+ ret = _FAIL;
+ }
+ }
+ } else {
+ DBG_871X("%s: fail at cmd52, cmd53.\n", __func__);
+ }
+ return ret;
+}
+
+#ifdef CONFIG_EXT_CLK
+void EnableGpio5ClockReq(PADAPTER Adapter, u8 in_interrupt, u32 Enable)
+{
+ u32 value32;
+ HAL_DATA_TYPE *pHalData;
+
+ pHalData = GET_HAL_DATA(Adapter);
+ if(IS_D_CUT(pHalData->VersionID))
+ return;
+
+ //dbgdump("%s Enable:%x time:%d", __RTL_FUNC__, Enable, rtw_get_current_time());
+
+ if(in_interrupt)
+ value32 = _sdio_read32(Adapter, REG_GPIO_PIN_CTRL);
+ else
+ value32 = rtw_read32(Adapter, REG_GPIO_PIN_CTRL);
+
+ //open GPIO 5
+ if (Enable)
+ value32 |= BIT(13);//5+8
+ else
+ value32 &= ~BIT(13);
+
+ //GPIO 5 out put
+ value32 |= BIT(21);//5+16
+
+ //if (Enable)
+ // rtw_write8(Adapter, REG_GPIO_PIN_CTRL + 1, 0x20);
+ //else
+ // rtw_write8(Adapter, REG_GPIO_PIN_CTRL + 1, 0x00);
+
+ if(in_interrupt)
+ _sdio_write32(Adapter, REG_GPIO_PIN_CTRL, value32);
+ else
+ rtw_write32(Adapter, REG_GPIO_PIN_CTRL, value32);
+
+} //end of _rtl8192cs_disable_gpio()
+
+void _InitClockTo26MHz(
+ IN PADAPTER Adapter
+ )
+{
+ u8 u1temp = 0;
+ HAL_DATA_TYPE *pHalData;
+
+ pHalData = GET_HAL_DATA(Adapter);
+
+ if(IS_D_CUT(pHalData->VersionID)) {
+ //FW special init
+ u1temp = rtw_read8(Adapter, REG_XCK_OUT_CTRL);
+ u1temp |= 0x18;
+ rtw_write8(Adapter, REG_XCK_OUT_CTRL, u1temp);
+ MSG_8192C("D cut version\n");
+ }
+
+ EnableGpio5ClockReq(Adapter, _FALSE, 1);
+
+ //0x2c[3:0] = 5 will set clock to 26MHz
+ u1temp = rtw_read8(Adapter, REG_APE_PLL_CTRL_EXT);
+ u1temp = (u1temp & 0xF0) | 0x05;
+ rtw_write8(Adapter, REG_APE_PLL_CTRL_EXT, u1temp);
+}
+#endif
+
+
+static void rtl8188es_interface_configure(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ BOOLEAN bWiFiConfig = pregistrypriv->wifi_spec;
+
+
+ pdvobjpriv->RtOutPipe[0] = WLAN_TX_HIQ_DEVICE_ID;
+ pdvobjpriv->RtOutPipe[1] = WLAN_TX_MIQ_DEVICE_ID;
+ pdvobjpriv->RtOutPipe[2] = WLAN_TX_LOQ_DEVICE_ID;
+
+ if (bWiFiConfig)
+ pHalData->OutEpNumber = 2;
+ else
+ pHalData->OutEpNumber = SDIO_MAX_TX_QUEUE;
+
+ switch(pHalData->OutEpNumber){
+ case 3:
+ pHalData->OutEpQueueSel=TX_SELE_HQ| TX_SELE_LQ|TX_SELE_NQ;
+ break;
+ case 2:
+ pHalData->OutEpQueueSel=TX_SELE_HQ| TX_SELE_NQ;
+ break;
+ case 1:
+ pHalData->OutEpQueueSel=TX_SELE_HQ;
+ break;
+ default:
+ break;
+ }
+
+ Hal_MappingOutPipe(padapter, pHalData->OutEpNumber);
+}
+
+/*
+ * Description:
+ * Call power on sequence to enable card
+ *
+ * Return:
+ * _SUCCESS enable success
+ * _FAIL enable fail
+ */
+static u8 _CardEnable(PADAPTER padapter)
+{
+ u8 bMacPwrCtrlOn;
+ u8 ret;
+
+ DBG_871X("=>%s\n", __FUNCTION__);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (bMacPwrCtrlOn == _FALSE)
+ {
+#ifdef CONFIG_PLATFORM_SPRD
+ u8 val8;
+#endif // CONFIG_PLATFORM_SPRD
+
+ // RSV_CTRL 0x1C[7:0] = 0x00
+ // unlock ISO/CLK/Power control register
+ rtw_write8(padapter, REG_RSV_CTRL, 0x0);
+
+#ifdef CONFIG_PLATFORM_SPRD
+#ifdef CONFIG_EXT_CLK
+ _InitClockTo26MHz(padapter);
+#endif //CONFIG_EXT_CLK
+
+ val8 = rtw_read8(padapter, 0x4);
+ val8 = val8 & ~BIT(5);
+ rtw_write8(padapter, 0x4, val8);
+#endif // CONFIG_PLATFORM_SPRD
+
+ ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, Rtl8188E_NIC_ENABLE_FLOW);
+ if (ret == _SUCCESS) {
+ u8 bMacPwrCtrlOn = _TRUE;
+ rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ }
+ else
+ {
+ DBG_871X(KERN_ERR "%s: run power on flow fail\n", __func__);
+ return _FAIL;
+ }
+
+ }
+ else
+ {
+ ret = _SUCCESS;
+ }
+
+ DBG_871X("<=%s\n", __FUNCTION__);
+
+ return ret;
+
+}
+
+static u32 rtl8188es_InitPowerOn(PADAPTER padapter)
+{
+ u8 value8;
+ u16 value16;
+ u32 value32;
+ u8 ret;
+
+ DBG_871X("=>%s\n", __FUNCTION__);
+
+ ret = _CardEnable(padapter);
+ if (ret == _FAIL) {
+ return ret;
+ }
+
+/*
+ // Radio-Off Pin Trigger
+ value8 = rtw_read8(padapter, REG_GPIO_INTM+1);
+ value8 |= BIT(1); // Enable falling edge triggering interrupt
+ rtw_write8(padapter, REG_GPIO_INTM+1, value8);
+ value8 = rtw_read8(padapter, REG_GPIO_IO_SEL_2+1);
+ value8 |= BIT(1);
+ rtw_write8(padapter, REG_GPIO_IO_SEL_2+1, value8);
+*/
+
+ // Enable power down and GPIO interrupt
+ value16 = rtw_read16(padapter, REG_APS_FSMCO);
+ value16 |= EnPDN; // Enable HW power down and RF on
+ rtw_write16(padapter, REG_APS_FSMCO, value16);
+
+
+ // Enable MAC DMA/WMAC/SCHEDULE/SEC block
+ value16 = rtw_read16(padapter, REG_CR);
+ value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
+ | PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
+ // for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31.
+
+ rtw_write16(padapter, REG_CR, value16);
+
+
+
+ // Enable CMD53 R/W Operation
+// bMacPwrCtrlOn = TRUE;
+// rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, (pu8)(&bMacPwrCtrlOn));
+
+ DBG_871X("<=%s\n", __FUNCTION__);
+
+ return _SUCCESS;
+
+}
+
+static void _InitQueueReservedPage(PADAPTER padapter)
+{
+#ifdef RTL8188ES_MAC_LOOPBACK
+
+//#define MAC_LOOPBACK_PAGE_NUM_PUBQ 0x26
+//#define MAC_LOOPBACK_PAGE_NUM_HPQ 0x0b
+//#define MAC_LOOPBACK_PAGE_NUM_LPQ 0x0b
+//#define MAC_LOOPBACK_PAGE_NUM_NPQ 0x0b // 71 pages=>9088 bytes, 8.875k
+
+ rtw_write16(padapter, REG_RQPN_NPQ, 0x0b0b);
+ rtw_write32(padapter, REG_RQPN, 0x80260b0b);
+
+#else //TX_PAGE_BOUNDARY_LOOPBACK_MODE
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ u32 outEPNum = (u32)pHalData->OutEpNumber;
+ u32 numHQ = 0;
+ u32 numLQ = 0;
+ u32 numNQ = 0;
+ u32 numPubQ;
+ u32 value32;
+ u8 value8;
+ BOOLEAN bWiFiConfig = pregistrypriv->wifi_spec;
+
+ if(bWiFiConfig)
+ {
+ if (pHalData->OutEpQueueSel & TX_SELE_HQ)
+ {
+ numHQ = 0x29;
+ }
+
+ if (pHalData->OutEpQueueSel & TX_SELE_LQ)
+ {
+ numLQ = 0x1C;
+ }
+
+ // NOTE: This step shall be proceed before writting REG_RQPN.
+ if (pHalData->OutEpQueueSel & TX_SELE_NQ) {
+ numNQ = 0x1C;
+ }
+ value8 = (u8)_NPQ(numNQ);
+ rtw_write8(padapter, REG_RQPN_NPQ, value8);
+
+ numPubQ = 0xA9 - numHQ - numLQ - numNQ;
+
+ // TX DMA
+ value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
+ rtw_write32(padapter, REG_RQPN, value32);
+ }
+ else
+ {
+ rtw_write16(padapter, REG_RQPN_NPQ, 0x0000);
+ rtw_write32(padapter,REG_RQPN, 0x80a00900);
+ }
+#endif
+ return;
+}
+
+static void _InitTxBufferBoundary(PADAPTER padapter, u8 txpktbuf_bndy)
+{
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ //u16 txdmactrl;
+
+ rtw_write8(padapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
+ rtw_write8(padapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
+ rtw_write8(padapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
+ rtw_write8(padapter, REG_TRXFF_BNDY, txpktbuf_bndy);
+ rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
+
+}
+
+static VOID
+_InitNormalChipRegPriority(
+ IN PADAPTER Adapter,
+ IN u16 beQ,
+ IN u16 bkQ,
+ IN u16 viQ,
+ IN u16 voQ,
+ IN u16 mgtQ,
+ IN u16 hiQ
+ )
+{
+ u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+
+ value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
+ _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
+ _TXDMA_MGQ_MAP(mgtQ)| _TXDMA_HIQ_MAP(hiQ);
+
+ rtw_write16(Adapter, REG_TRXDMA_CTRL, value16);
+}
+
+static VOID
+_InitNormalChipOneOutEpPriority(
+ IN PADAPTER Adapter
+ )
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ u16 value = 0;
+ switch(pHalData->OutEpQueueSel)
+ {
+ case TX_SELE_HQ:
+ value = QUEUE_HIGH;
+ break;
+ case TX_SELE_LQ:
+ value = QUEUE_LOW;
+ break;
+ case TX_SELE_NQ:
+ value = QUEUE_NORMAL;
+ break;
+ default:
+ //RT_ASSERT(FALSE,("Shall not reach here!\n"));
+ break;
+ }
+
+ _InitNormalChipRegPriority(Adapter,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value
+ );
+
+}
+
+static VOID
+_InitNormalChipTwoOutEpPriority(
+ IN PADAPTER Adapter
+ )
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+ u16 beQ,bkQ,viQ,voQ,mgtQ,hiQ;
+
+
+ u16 valueHi = 0;
+ u16 valueLow = 0;
+
+ switch(pHalData->OutEpQueueSel)
+ {
+ case (TX_SELE_HQ | TX_SELE_LQ):
+ valueHi = QUEUE_HIGH;
+ valueLow = QUEUE_LOW;
+ break;
+ case (TX_SELE_NQ | TX_SELE_LQ):
+ valueHi = QUEUE_NORMAL;
+ valueLow = QUEUE_LOW;
+ break;
+ case (TX_SELE_HQ | TX_SELE_NQ):
+ valueHi = QUEUE_HIGH;
+ valueLow = QUEUE_NORMAL;
+ break;
+ default:
+ //RT_ASSERT(FALSE,("Shall not reach here!\n"));
+ break;
+ }
+
+ if(!pregistrypriv->wifi_spec ){
+ beQ = valueLow;
+ bkQ = valueLow;
+ viQ = valueHi;
+ voQ = valueHi;
+ mgtQ = valueHi;
+ hiQ = valueHi;
+ }
+ else{//for WMM ,CONFIG_OUT_EP_WIFI_MODE
+ beQ = valueLow;
+ bkQ = valueHi;
+ viQ = valueHi;
+ voQ = valueLow;
+ mgtQ = valueHi;
+ hiQ = valueHi;
+ }
+
+ _InitNormalChipRegPriority(Adapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ);
+
+}
+
+static VOID
+_InitNormalChipThreeOutEpPriority(
+ IN PADAPTER padapter
+ )
+{
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
+
+ if (!pregistrypriv->wifi_spec){// typical setting
+ beQ = QUEUE_LOW;
+ bkQ = QUEUE_LOW;
+ viQ = QUEUE_NORMAL;
+ voQ = QUEUE_HIGH;
+ mgtQ = QUEUE_HIGH;
+ hiQ = QUEUE_HIGH;
+ }
+ else {// for WMM
+ beQ = QUEUE_LOW;
+ bkQ = QUEUE_NORMAL;
+ viQ = QUEUE_NORMAL;
+ voQ = QUEUE_HIGH;
+ mgtQ = QUEUE_HIGH;
+ hiQ = QUEUE_HIGH;
+ }
+ _InitNormalChipRegPriority(padapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ);
+}
+
+static VOID
+_InitNormalChipQueuePriority(
+ IN PADAPTER Adapter
+ )
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ switch(pHalData->OutEpNumber)
+ {
+ case 1:
+ _InitNormalChipOneOutEpPriority(Adapter);
+ break;
+ case 2:
+ _InitNormalChipTwoOutEpPriority(Adapter);
+ break;
+ case 3:
+ _InitNormalChipThreeOutEpPriority(Adapter);
+ break;
+ default:
+ //RT_ASSERT(FALSE,("Shall not reach here!\n"));
+ break;
+ }
+
+
+}
+
+
+static void _InitQueuePriority(PADAPTER padapter)
+{
+ _InitNormalChipQueuePriority(padapter);
+}
+
+static void _InitPageBoundary(PADAPTER padapter)
+{
+ // RX Page Boundary
+ u16 rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E-1;
+
+ rtw_write16(padapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+
+}
+
+static void _InitTransferPageSize(PADAPTER padapter)
+{
+ // Tx page size is always 128.
+
+ u8 value8;
+ value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
+ rtw_write8(padapter, REG_PBP, value8);
+}
+
+void _InitDriverInfoSize(PADAPTER padapter, u8 drvInfoSize)
+{
+ rtw_write8(padapter, REG_RX_DRVINFO_SZ, drvInfoSize);
+}
+
+void _InitNetworkType(PADAPTER padapter)
+{
+ u32 value32;
+
+ value32 = rtw_read32(padapter, REG_CR);
+
+ // TODO: use the other function to set network type
+// value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AD_HOC);
+ value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
+
+ rtw_write32(padapter, REG_CR, value32);
+}
+
+void _InitWMACSetting(PADAPTER padapter)
+{
+ u16 value16;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+
+ //pHalData->ReceiveConfig = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA | RCR_CBSSID_BCN | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_PHYSTS | RCR_APP_ICV | RCR_APP_MIC;
+ // don't turn on AAP, it will allow all packets to driver
+ pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA | RCR_CBSSID_BCN | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_PHYST_RXFF | RCR_APP_ICV | RCR_APP_MIC;
+
+ rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig);
+
+ // Accept all data frames
+ value16 = 0xFFFF;
+ rtw_write16(padapter, REG_RXFLTMAP2, value16);
+
+ // 2010.09.08 hpfan
+ // Since ADF is removed from RCR, ps-poll will not be indicate to driver,
+ // RxFilterMap should mask ps-poll to gurantee AP mode can rx ps-poll.
+ value16 = 0x400;
+ rtw_write16(padapter, REG_RXFLTMAP1, value16);
+
+ // Accept all management frames
+ value16 = 0xFFFF;
+ rtw_write16(padapter, REG_RXFLTMAP0, value16);
+
+}
+
+void _InitAdaptiveCtrl(PADAPTER padapter)
+{
+ u16 value16;
+ u32 value32;
+
+ // Response Rate Set
+ value32 = rtw_read32(padapter, REG_RRSR);
+ value32 &= ~RATE_BITMAP_ALL;
+ value32 |= RATE_RRSR_CCK_ONLY_1M;
+ rtw_write32(padapter, REG_RRSR, value32);
+
+ // CF-END Threshold
+ //m_spIoBase->rtw_write8(REG_CFEND_TH, 0x1);
+
+ // SIFS (used in NAV)
+ value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
+ rtw_write16(padapter, REG_SPEC_SIFS, value16);
+
+ // Retry Limit
+ value16 = _LRL(0x30) | _SRL(0x30);
+ rtw_write16(padapter, REG_RL, value16);
+}
+
+void _InitEDCA(PADAPTER padapter)
+{
+ // Set Spec SIFS (used in NAV)
+ rtw_write16(padapter, REG_SPEC_SIFS, 0x100a);
+ rtw_write16(padapter, REG_MAC_SPEC_SIFS, 0x100a);
+
+ // Set SIFS for CCK
+ rtw_write16(padapter, REG_SIFS_CTX, 0x100a);
+
+ // Set SIFS for OFDM
+ rtw_write16(padapter, REG_SIFS_TRX, 0x100a);
+
+ // TXOP
+ rtw_write32(padapter, REG_EDCA_BE_PARAM, 0x005EA42B);
+ rtw_write32(padapter, REG_EDCA_BK_PARAM, 0x0000A44F);
+ rtw_write32(padapter, REG_EDCA_VI_PARAM, 0x005EA324);
+ rtw_write32(padapter, REG_EDCA_VO_PARAM, 0x002FA226);
+}
+
+void _InitRateFallback(PADAPTER padapter)
+{
+ // Set Data Auto Rate Fallback Retry Count register.
+ rtw_write32(padapter, REG_DARFRC, 0x00000000);
+ rtw_write32(padapter, REG_DARFRC+4, 0x10080404);
+ rtw_write32(padapter, REG_RARFRC, 0x04030201);
+ rtw_write32(padapter, REG_RARFRC+4, 0x08070605);
+
+}
+
+void _InitRetryFunction(PADAPTER padapter)
+{
+ u8 value8;
+
+ value8 = rtw_read8(padapter, REG_FWHW_TXQ_CTRL);
+ value8 |= EN_AMPDU_RTY_NEW;
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL, value8);
+
+ // Set ACK timeout
+ rtw_write8(padapter, REG_ACKTO, 0x40);
+}
+
+static void HalRxAggr8188ESdio(PADAPTER padapter)
+{
+#if 1
+ struct registry_priv *pregistrypriv;
+ u8 valueDMATimeout;
+ u8 valueDMAPageCount;
+
+
+ pregistrypriv = &padapter->registrypriv;
+
+ if (pregistrypriv->wifi_spec)
+ {
+ // 2010.04.27 hpfan
+ // Adjust RxAggrTimeout to close to zero disable RxAggr, suggested by designer
+ // Timeout value is calculated by 34 / (2^n)
+ valueDMATimeout = 0x0f;
+ valueDMAPageCount = 0x01;
+ }
+ else
+ {
+ valueDMATimeout = 0x06;
+ //valueDMAPageCount = 0x0F;
+ //valueDMATimeout = 0x0a;
+ valueDMAPageCount = 0x24;
+ }
+
+ rtw_write8(padapter, REG_RXDMA_AGG_PG_TH+1, valueDMATimeout);
+ rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, valueDMAPageCount);
+#endif
+}
+
+void sdio_AggSettingRxUpdate(PADAPTER padapter)
+{
+#if 1
+ //HAL_DATA_TYPE *pHalData;
+ u8 valueDMA;
+
+
+ //pHalData = GET_HAL_DATA(padapter);
+
+ valueDMA = rtw_read8(padapter, REG_TRXDMA_CTRL);
+ valueDMA |= RXDMA_AGG_EN;
+ rtw_write8(padapter, REG_TRXDMA_CTRL, valueDMA);
+
+#if 0
+ switch (RX_PAGE_SIZE_REG_VALUE)
+ {
+ case PBP_64:
+ pHalData->HwRxPageSize = 64;
+ break;
+ case PBP_128:
+ pHalData->HwRxPageSize = 128;
+ break;
+ case PBP_256:
+ pHalData->HwRxPageSize = 256;
+ break;
+ case PBP_512:
+ pHalData->HwRxPageSize = 512;
+ break;
+ case PBP_1024:
+ pHalData->HwRxPageSize = 1024;
+ break;
+ default:
+ RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
+ ("%s: RX_PAGE_SIZE_REG_VALUE definition is incorrect!\n", __FUNCTION__));
+ break;
+ }
+#endif
+#endif
+}
+
+void _initSdioAggregationSetting(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ // Tx aggregation setting
+ //sdio_AggSettingTxUpdate(padapter);
+
+ // Rx aggregation setting
+ HalRxAggr8188ESdio(padapter);
+ sdio_AggSettingRxUpdate(padapter);
+
+ // 201/12/10 MH Add for USB agg mode dynamic switch.
+ pHalData->UsbRxHighSpeedMode = _FALSE;
+}
+
+
+void _InitOperationMode(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+ struct mlme_ext_priv *pmlmeext;
+ u8 regBwOpMode = 0;
+ u32 regRATR = 0, regRRSR = 0;
+ u8 MinSpaceCfg;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+ pmlmeext = &padapter->mlmeextpriv;
+
+ //1 This part need to modified according to the rate set we filtered!!
+ //
+ // Set RRSR, RATR, and REG_BWOPMODE registers
+ //
+ switch(pmlmeext->cur_wireless_mode)
+ {
+ case WIRELESS_MODE_B:
+ regBwOpMode = BW_OPMODE_20MHZ;
+ regRATR = RATE_ALL_CCK;
+ regRRSR = RATE_ALL_CCK;
+ break;
+ case WIRELESS_MODE_A:
+// RT_ASSERT(FALSE,("Error wireless a mode\n"));
+#if 0
+ regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
+ regRATR = RATE_ALL_OFDM_AG;
+ regRRSR = RATE_ALL_OFDM_AG;
+#endif
+ break;
+ case WIRELESS_MODE_G:
+ regBwOpMode = BW_OPMODE_20MHZ;
+ regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+ regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+ break;
+ case WIRELESS_MODE_AUTO:
+#if 0
+ if (padapter->bInHctTest)
+ {
+ regBwOpMode = BW_OPMODE_20MHZ;
+ regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+ regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+ }
+ else
+#endif
+ {
+ regBwOpMode = BW_OPMODE_20MHZ;
+ regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+ regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+ }
+ break;
+ case WIRELESS_MODE_N_24G:
+ // It support CCK rate by default.
+ // CCK rate will be filtered out only when associated AP does not support it.
+ regBwOpMode = BW_OPMODE_20MHZ;
+ regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+ regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+ break;
+ case WIRELESS_MODE_N_5G:
+// RT_ASSERT(FALSE,("Error wireless mode"));
+#if 0
+ regBwOpMode = BW_OPMODE_5G;
+ regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+ regRRSR = RATE_ALL_OFDM_AG;
+#endif
+ break;
+
+ default: //for MacOSX compiler warning.
+ break;
+ }
+
+ rtw_write8(padapter, REG_BWOPMODE, regBwOpMode);
+
+ // For Min Spacing configuration.
+ switch(pHalData->rf_type)
+ {
+ case RF_1T2R:
+ case RF_1T1R:
+ RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter: RF_Type%s\n", (pHalData->rf_type==RF_1T1R? "(1T1R)":"(1T2R)")));
+// padapter->MgntInfo.MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3);
+ MinSpaceCfg = (MAX_MSS_DENSITY_1T << 3);
+ break;
+ case RF_2T2R:
+ case RF_2T2R_GREEN:
+ RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter:RF_Type(2T2R)\n"));
+// padapter->MgntInfo.MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3);
+ MinSpaceCfg = (MAX_MSS_DENSITY_2T << 3);
+ break;
+ }
+
+// rtw_write8(padapter, REG_AMPDU_MIN_SPACE, padapter->MgntInfo.MinSpaceCfg);
+ rtw_write8(padapter, REG_AMPDU_MIN_SPACE, MinSpaceCfg);
+}
+
+
+void _InitBeaconParameters(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+
+ rtw_write16(padapter, REG_BCN_CTRL, 0x1010);
+
+ // TODO: Remove these magic number
+ rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);// ms
+ rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);//ms
+ rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
+
+ // Suggested by designer timchen. Change beacon AIFS to the largest number
+ // beacause test chip does not contension before sending beacon. by tynli. 2009.11.03
+ rtw_write16(padapter, REG_BCNTCFG, 0x660F);
+
+
+ pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
+ pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE);
+ pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);
+ pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT+2);
+ pHalData->RegCR_1 = rtw_read8(padapter, REG_CR+1);
+
+}
+
+void _InitBeaconMaxError(PADAPTER padapter, BOOLEAN InfraMode)
+{
+#ifdef RTL8192CU_ADHOC_WORKAROUND_SETTING
+ rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
+#endif
+}
+
+void _InitInterrupt(PADAPTER padapter)
+{
+
+ //HISR write one to clear
+ rtw_write32(padapter, REG_HISR_88E, 0xFFFFFFFF);
+
+ // HIMR - turn all off
+ rtw_write32(padapter, REG_HIMR_88E, 0);
+
+ //
+ // Initialize and enable SDIO Host Interrupt.
+ //
+ InitInterrupt8188ESdio(padapter);
+
+
+ //
+ // Initialize and enable system Host Interrupt.
+ //
+ //InitSysInterrupt8188ESdio(Adapter);//TODO:
+
+ //
+ // Enable SDIO Host Interrupt.
+ //
+ //EnableInterrupt8188ESdio(padapter);//Move to sd_intf_start()/stop
+
+}
+
+void _InitRDGSetting(PADAPTER padapter)
+{
+ rtw_write8(padapter, REG_RD_CTRL, 0xFF);
+ rtw_write16(padapter, REG_RD_NAV_NXT, 0x200);
+ rtw_write8(padapter, REG_RD_RESP_PKT_TH, 0x05);
+}
+
+
+static void _InitRxSetting(PADAPTER padapter)
+{
+ rtw_write32(padapter, REG_MACID, 0x87654321);
+ rtw_write32(padapter, 0x0700, 0x87654321);
+}
+
+
+static void _InitRFType(PADAPTER padapter)
+{
+ struct registry_priv *pregpriv = &padapter->registrypriv;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ //BOOLEAN is92CU = IS_92C_SERIAL(pHalData->VersionID);
+ BOOLEAN is2T2R = IS_2T2R(pHalData->VersionID);
+
+#if DISABLE_BB_RF
+ pHalData->rf_chip = RF_PSEUDO_11N;
+ return;
+#endif
+
+ pHalData->rf_chip = RF_6052;
+
+ //if (_FALSE == is92CU) {
+ if(_FALSE == is2T2R){
+ pHalData->rf_type = RF_1T1R;
+ DBG_8192C("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n");
+ return;
+ }
+
+ // TODO: Consider that EEPROM set 92CU to 1T1R later.
+ // Force to overwrite setting according to chip version. Ignore EEPROM setting.
+ //pHalData->RF_Type = is92CU ? RF_2T2R : RF_1T1R;
+ MSG_8192C("Set RF Chip ID to RF_6052 and RF type to %d.\n", pHalData->rf_type);
+}
+
+// Set CCK and OFDM Block "ON"
+static void _BBTurnOnBlock(PADAPTER padapter)
+{
+#if (DISABLE_BB_RF)
+ return;
+#endif
+
+ PHY_SetBBReg(padapter, rFPGA0_RFMOD, bCCKEn, 0x1);
+ PHY_SetBBReg(padapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
+}
+
+#if 0
+static void _InitAntenna_Selection(PADAPTER padapter)
+{
+ rtw_write8(padapter, REG_LEDCFG2, 0x82);
+}
+#endif
+
+static void _InitPABias(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 pa_setting;
+ BOOLEAN is92C = IS_92C_SERIAL(pHalData->VersionID);
+
+ //FIXED PA current issue
+ //efuse_one_byte_read(padapter, 0x1FA, &pa_setting);
+ pa_setting = EFUSE_Read1Byte(padapter, 0x1FA);
+
+ //RT_TRACE(COMP_INIT, DBG_LOUD, ("_InitPABias 0x1FA 0x%x \n",pa_setting));
+
+ if(!(pa_setting & BIT0))
+ {
+ PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x0F406);
+ PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x4F406);
+ PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x8F406);
+ PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0xCF406);
+ //RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path A\n"));
+ }
+
+ if(!(pa_setting & BIT1) && is92C)
+ {
+ PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0x0F406);
+ PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0x4F406);
+ PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0x8F406);
+ PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0xCF406);
+ //RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path B\n"));
+ }
+
+ if(!(pa_setting & BIT4))
+ {
+ pa_setting = rtw_read8(padapter, 0x16);
+ pa_setting &= 0x0F;
+ rtw_write8(padapter, 0x16, pa_setting | 0x80);
+ rtw_write8(padapter, 0x16, pa_setting | 0x90);
+ }
+}
+
+#if 0
+VOID
+_InitRDGSetting_8188E(
+ IN PADAPTER Adapter
+ )
+{
+ PlatformEFIOWrite1Byte(Adapter,REG_RD_CTRL,0xFF);
+ PlatformEFIOWrite2Byte(Adapter, REG_RD_NAV_NXT, 0x200);
+ PlatformEFIOWrite1Byte(Adapter,REG_RD_RESP_PKT_TH,0x05);
+}
+#endif
+
+static u32 rtl8188es_hal_init(PADAPTER padapter)
+{
+ s32 ret;
+ u8 txpktbuf_bndy;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ u8 is92C = IS_92C_SERIAL(pHalData->VersionID);
+ rt_rf_power_state eRfPowerStateToSet;
+ u8 value8;
+ u16 value16;
+
+ u32 init_start_time = rtw_get_current_time();
+
+#ifdef DBG_HAL_INIT_PROFILING
+ enum HAL_INIT_STAGES {
+ HAL_INIT_STAGES_BEGIN = 0,
+ HAL_INIT_STAGES_INIT_PW_ON,
+ HAL_INIT_STAGES_MISC01,
+ HAL_INIT_STAGES_DOWNLOAD_FW,
+ HAL_INIT_STAGES_MAC,
+ HAL_INIT_STAGES_BB,
+ HAL_INIT_STAGES_RF,
+ HAL_INIT_STAGES_EFUSE_PATCH,
+ HAL_INIT_STAGES_INIT_LLTT,
+
+ HAL_INIT_STAGES_MISC02,
+ HAL_INIT_STAGES_TURN_ON_BLOCK,
+ HAL_INIT_STAGES_INIT_SECURITY,
+ HAL_INIT_STAGES_MISC11,
+ HAL_INIT_STAGES_INIT_HAL_DM,
+ //HAL_INIT_STAGES_RF_PS,
+ HAL_INIT_STAGES_IQK,
+ HAL_INIT_STAGES_PW_TRACK,
+ HAL_INIT_STAGES_LCK,
+ //HAL_INIT_STAGES_MISC21,
+ HAL_INIT_STAGES_INIT_PABIAS,
+ //HAL_INIT_STAGES_ANTENNA_SEL,
+ HAL_INIT_STAGES_MISC31,
+ HAL_INIT_STAGES_END,
+ HAL_INIT_STAGES_NUM
+ };
+
+ char * hal_init_stages_str[] = {
+ "HAL_INIT_STAGES_BEGIN",
+ "HAL_INIT_STAGES_INIT_PW_ON",
+ "HAL_INIT_STAGES_MISC01",
+ "HAL_INIT_STAGES_DOWNLOAD_FW",
+ "HAL_INIT_STAGES_MAC",
+ "HAL_INIT_STAGES_BB",
+ "HAL_INIT_STAGES_RF",
+ "HAL_INIT_STAGES_EFUSE_PATCH",
+ "HAL_INIT_STAGES_INIT_LLTT",
+ "HAL_INIT_STAGES_MISC02",
+ "HAL_INIT_STAGES_TURN_ON_BLOCK",
+ "HAL_INIT_STAGES_INIT_SECURITY",
+ "HAL_INIT_STAGES_MISC11",
+ "HAL_INIT_STAGES_INIT_HAL_DM",
+ //"HAL_INIT_STAGES_RF_PS",
+ "HAL_INIT_STAGES_IQK",
+ "HAL_INIT_STAGES_PW_TRACK",
+ "HAL_INIT_STAGES_LCK",
+ //"HAL_INIT_STAGES_MISC21",
+ "HAL_INIT_STAGES_INIT_PABIAS"
+ //"HAL_INIT_STAGES_ANTENNA_SEL",
+ "HAL_INIT_STAGES_MISC31",
+ "HAL_INIT_STAGES_END",
+ };
+
+
+ int hal_init_profiling_i;
+ u32 hal_init_stages_timestamp[HAL_INIT_STAGES_NUM]; //used to record the time of each stage's starting point
+
+ for(hal_init_profiling_i=0;hal_init_profiling_i<HAL_INIT_STAGES_NUM;hal_init_profiling_i++)
+ hal_init_stages_timestamp[hal_init_profiling_i]=0;
+
+ #define HAL_INIT_PROFILE_TAG(stage) hal_init_stages_timestamp[(stage)]=rtw_get_current_time();
+#else
+ #define HAL_INIT_PROFILE_TAG(stage) do {} while(0)
+#endif //DBG_HAL_INIT_PROFILING
+
+ DBG_8192C("+rtl8188es_hal_init\n");
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BEGIN);
+ // Disable Interrupt first.
+// rtw_hal_disable_interrupt(padapter);
+// DisableInterrupt8188ESdio(padapter);
+
+#ifdef CONFIG_WOWLAN
+ if(rtw_read8(padapter, REG_MCUFWDL)&BIT7 &&
+ (padapter->pwrctrlpriv.wowlan_wake_reason & FWDecisionDisconnect)) {
+ u8 reg_val=0;
+ DBG_8192C("+Reset Entry+\n");
+ rtw_write8(padapter, REG_MCUFWDL, 0x00);
+ _8051Reset88E(padapter);
+ //reset BB
+ reg_val = rtw_read8(padapter, REG_SYS_FUNC_EN);
+ reg_val &= ~(BIT(0) | BIT(1));
+ rtw_write8(padapter, REG_SYS_FUNC_EN, reg_val);
+ //reset RF
+ rtw_write8(padapter, REG_RF_CTRL, 0);
+ //reset TRX path
+ rtw_write16(padapter, REG_CR, 0);
+ //reset MAC, Digital Core
+ reg_val = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+ reg_val &= ~(BIT(4) | BIT(7));
+ rtw_write8(padapter, REG_SYS_FUNC_EN+1, reg_val);
+ reg_val = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+ reg_val |= BIT(4) | BIT(7);
+ rtw_write8(padapter, REG_SYS_FUNC_EN+1, reg_val);
+ DBG_8192C("-Reset Entry-\n");
+ }
+#endif //CONFIG_WOWLAN
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON);
+ ret = rtl8188es_InitPowerOn(padapter);
+ if (_FAIL == ret) {
+ RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init Power On!\n"));
+ goto exit;
+ }
+
+ ret = PowerOnCheck(padapter);
+ if (_FAIL == ret ) {
+ DBG_871X("Power on Fail! do it again\n");
+ ret = rtl8188es_InitPowerOn(padapter);
+ if (_FAIL == ret) {
+ DBG_871X("Failed to init Power On!\n");
+ goto exit;
+ }
+ }
+ DBG_871X("Power on ok!\n");
+
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC01);
+ if (!pregistrypriv->wifi_spec) {
+ txpktbuf_bndy = TX_PAGE_BOUNDARY_88E;
+ } else {
+ // for WMM
+ txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY_88E;
+ }
+ _InitQueueReservedPage(padapter);
+ _InitQueuePriority(padapter);
+ _InitPageBoundary(padapter);
+ _InitTransferPageSize(padapter);
+#ifdef CONFIG_IOL_IOREG_CFG
+ _InitTxBufferBoundary(padapter, 0);
+#endif
+ //
+ // Configure SDIO TxRx Control to enable Rx DMA timer masking.
+ // 2010.02.24.
+ //
+ value8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_TX_CTRL);
+ SdioLocalCmd52Write1Byte(padapter, SDIO_REG_TX_CTRL, 0x02);
+
+ rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, 0);
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_DOWNLOAD_FW);
+#if (MP_DRIVER == 1)
+ if (padapter->registrypriv.mp_mode == 1)
+ {
+ _InitRxSetting(padapter);
+ }
+#endif //MP_DRIVER == 1
+ {
+#if 0
+ padapter->bFWReady = _FALSE; //because no fw for test chip
+ pHalData->fw_ractrl = _FALSE;
+#else
+#ifdef CONFIG_WOWLAN
+ ret = rtl8188e_FirmwareDownload(padapter, _FALSE);
+#else
+ ret = rtl8188e_FirmwareDownload(padapter);
+#endif //CONFIG_WOWLAN
+
+ if (ret != _SUCCESS) {
+ DBG_871X("%s: Download Firmware failed!!\n", __FUNCTION__);
+ padapter->bFWReady = _FALSE;
+ pHalData->fw_ractrl = _FALSE;
+ goto exit;
+ } else {
+ RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Download Firmware Success!!\n"));
+ padapter->bFWReady = _TRUE;
+ pHalData->fw_ractrl = _FALSE;
+ }
+#endif
+ }
+
+ rtl8188e_InitializeFirmwareVars(padapter);
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MAC);
+#if (HAL_MAC_ENABLE == 1)
+ ret = PHY_MACConfig8188E(padapter);
+ if(ret != _SUCCESS){
+// RT_TRACE(COMP_INIT, DBG_LOUD, ("Initializepadapter8192CSdio(): Fail to configure MAC!!\n"));
+ goto exit;
+ }
+#endif
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB);
+ //
+ //d. Initialize BB related configurations.
+ //
+#if (HAL_BB_ENABLE == 1)
+ ret = PHY_BBConfig8188E(padapter);
+ if(ret != _SUCCESS){
+// RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Initializepadapter8192CSdio(): Fail to configure BB!!\n"));
+ goto exit;
+ }
+#endif
+
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_RF);
+
+#if (HAL_RF_ENABLE == 1)
+ ret = PHY_RFConfig8188E(padapter);
+
+ if(ret != _SUCCESS){
+// RT_TRACE(COMP_INIT, DBG_LOUD, ("Initializepadapter8192CSdio(): Fail to configure RF!!\n"));
+ goto exit;
+ }
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_EFUSE_PATCH);
+#if defined(CONFIG_IOL_EFUSE_PATCH)
+ ret = rtl8188e_iol_efuse_patch(padapter);
+ if(ret != _SUCCESS){
+ DBG_871X("%s rtl8188e_iol_efuse_patch failed \n",__FUNCTION__);
+ goto exit;
+ }
+#endif
+ _InitTxBufferBoundary(padapter, txpktbuf_bndy);
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_LLTT);
+ ret = InitLLTTable(padapter, txpktbuf_bndy);
+ if (_SUCCESS != ret) {
+ RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init LLT Table!\n"));
+ goto exit;
+ }
+
+#if (RATE_ADAPTIVE_SUPPORT==1)
+ {//Enable TX Report
+ //Enable Tx Report Timer
+ value8 = rtw_read8(padapter, REG_TX_RPT_CTRL);
+ rtw_write8(padapter, REG_TX_RPT_CTRL, (value8|BIT1|BIT0));
+ //Set MAX RPT MACID
+ rtw_write8(padapter, REG_TX_RPT_CTRL+1, 2);//FOR sta mode ,0: bc/mc ,1:AP
+ //Tx RPT Timer. Unit: 32us
+ rtw_write16(padapter, REG_TX_RPT_TIME, 0xCdf0);
+ }
+#endif
+
+#if 0
+ if(pHTInfo->bRDGEnable){
+ _InitRDGSetting_8188E(Adapter);
+ }
+#endif
+
+#ifdef CONFIG_TX_EARLY_MODE
+ if( pHalData->bEarlyModeEnable)
+ {
+ RT_TRACE(_module_hci_hal_init_c_, _drv_info_,("EarlyMode Enabled!!!\n"));
+
+ value8 = rtw_read8(padapter, REG_EARLY_MODE_CONTROL);
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ value8 = value8|0x1f;
+#else
+ value8 = value8|0xf;
+#endif
+ rtw_write8(padapter, REG_EARLY_MODE_CONTROL, value8);
+
+ rtw_write8(padapter, REG_EARLY_MODE_CONTROL+3, 0x80);
+
+ value8 = rtw_read8(padapter, REG_TCR+1);
+ value8 = value8|0x40;
+ rtw_write8(padapter,REG_TCR+1, value8);
+ }
+ else
+#endif
+ {
+ rtw_write8(padapter, REG_EARLY_MODE_CONTROL, 0);
+ }
+
+
+#if(SIC_ENABLE == 1)
+ SIC_Init(padapter);
+#endif
+
+
+ if (pwrctrlpriv->reg_rfoff == _TRUE) {
+ pwrctrlpriv->rf_pwrstate = rf_off;
+ }
+
+ // 2010/08/09 MH We need to check if we need to turnon or off RF after detecting
+ // HW GPIO pin. Before PHY_RFConfig8192C.
+ HalDetectPwrDownMode88E(padapter);
+
+
+ // Set RF type for BB/RF configuration
+ _InitRFType(padapter);
+
+ // Save target channel
+ // <Roger_Notes> Current Channel will be updated again later.
+ pHalData->CurrentChannel = 1;
+
+
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC02);
+ // Get Rx PHY status in order to report RSSI and others.
+ _InitDriverInfoSize(padapter, 4);
+ hal_init_macaddr(padapter);
+ _InitNetworkType(padapter);
+ _InitWMACSetting(padapter);
+ _InitAdaptiveCtrl(padapter);
+ _InitEDCA(padapter);
+ _InitRateFallback(padapter);
+ _InitRetryFunction(padapter);
+ _initSdioAggregationSetting(padapter);
+ _InitOperationMode(padapter);
+ _InitBeaconParameters(padapter);
+ _InitBeaconMaxError(padapter, _TRUE);
+ _InitInterrupt(padapter);
+
+ // Enable MACTXEN/MACRXEN block
+ value16 = rtw_read16(padapter, REG_CR);
+ value16 |= (MACTXEN | MACRXEN);
+ rtw_write8(padapter, REG_CR, value16);
+
+#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_TX_MCAST2UNI)
+
+#ifdef CONFIG_CHECK_AC_LIFETIME
+ // Enable lifetime check for the four ACs
+ rtw_write8(padapter, REG_LIFETIME_EN, 0x0F);
+#endif // CONFIG_CHECK_AC_LIFETIME
+
+#ifdef CONFIG_TX_MCAST2UNI
+ rtw_write16(padapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); // unit: 256us. 256ms
+ rtw_write16(padapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); // unit: 256us. 256ms
+#else // CONFIG_TX_MCAST2UNI
+ rtw_write16(padapter, REG_PKT_VO_VI_LIFE_TIME, 0x3000); // unit: 256us. 3s
+ rtw_write16(padapter, REG_PKT_BE_BK_LIFE_TIME, 0x3000); // unit: 256us. 3s
+#endif // CONFIG_TX_MCAST2UNI
+#endif // CONFIG_CONCURRENT_MODE || CONFIG_TX_MCAST2UNI
+
+
+
+
+#endif //HAL_RF_ENABLE == 1
+
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK);
+ _BBTurnOnBlock(padapter);
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY);
+#if 1
+ invalidate_cam_all(padapter);
+#else
+ CamResetAllEntry(padapter);
+ padapter->HalFunc.EnableHWSecCfgHandler(padapter);
+#endif
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11);
+ // 2010/12/17 MH We need to set TX power according to EFUSE content at first.
+ PHY_SetTxPowerLevel8188E(padapter, pHalData->CurrentChannel);
+ // Record original value for template. This is arough data, we can only use the data
+ // for power adjust. The value can not be adjustde according to different power!!!
+// pHalData->OriginalCckTxPwrIdx = pHalData->CurrentCckTxPwrIdx;
+// pHalData->OriginalOfdm24GTxPwrIdx = pHalData->CurrentOfdm24GTxPwrIdx;
+
+// Move by Neo for USB SS to below setp
+//_RfPowerSave(padapter);
+#if 0 //ANTENNA_SELECTION_STATIC_SETTING
+#if 0
+ if (!IS_92C_SERIAL( pHalData->VersionID) && (pHalData->AntDivCfg!=0))
+#else
+ if (IS_1T1R( pHalData->VersionID) && (pHalData->AntDivCfg!=0))
+#endif
+ { //for 88CU ,1T1R
+ _InitAntenna_Selection(padapter);
+ }
+#endif
+
+ //
+ // Disable BAR, suggested by Scott
+ // 2010.04.09 add by hpfan
+ //
+ rtw_write32(padapter, REG_BAR_MODE_CTRL, 0x0201ffff);
+
+ // HW SEQ CTRL
+ // set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM.
+ rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF);
+
+
+#ifdef RTL8188ES_MAC_LOOPBACK
+ value8 = rtw_read8(padapter, REG_SYS_FUNC_EN);
+ value8 &= ~(FEN_BBRSTB|FEN_BB_GLB_RSTn);
+ rtw_write8(padapter, REG_SYS_FUNC_EN, value8);//disable BB, CCK/OFDM
+
+ rtw_write8(padapter, REG_RD_CTRL, 0x0F);
+ rtw_write8(padapter, REG_RD_CTRL+1, 0xCF);
+ //rtw_write8(padapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, 0x80);//to check _InitPageBoundary()
+ rtw_write32(padapter, REG_CR, 0x0b0202ff);//0x100[28:24]=0x01011, enable mac loopback, no HW Security Eng.
+#endif
+
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM);
+ // InitHalDm(padapter);
+ rtl8188e_InitHalDm(padapter);
+
+
+#if (MP_DRIVER == 1)
+ if (padapter->registrypriv.mp_mode == 1)
+ {
+ padapter->mppriv.channel = pHalData->CurrentChannel;
+ MPT_InitializeAdapter(padapter, padapter->mppriv.channel);
+ }
+ else
+#endif //(MP_DRIVER == 1)
+ {
+ //
+ // 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status
+ // and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not
+ // call init_adapter. May cause some problem??
+ //
+ // Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed
+ // in MgntActSet_RF_State() after wake up, because the value of pHalData->eRFPowerState
+ // is the same as eRfOff, we should change it to eRfOn after we config RF parameters.
+ // Added by tynli. 2010.03.30.
+ pwrctrlpriv->rf_pwrstate = rf_on;
+ RT_CLEAR_PS_LEVEL(pwrctrlpriv, RT_RF_OFF_LEVL_HALT_NIC);
+
+ // 20100326 Joseph: Copy from GPIOChangeRFWorkItemCallBack() function to check HW radio on/off.
+ // 20100329 Joseph: Revise and integrate the HW/SW radio off code in initialization.
+// pHalData->bHwRadioOff = _FALSE;
+ pwrctrlpriv->b_hw_radio_off = _FALSE;
+ eRfPowerStateToSet = rf_on;
+
+ // 2010/-8/09 MH For power down module, we need to enable register block contrl reg at 0x1c.
+ // Then enable power down control bit of register 0x04 BIT4 and BIT15 as 1.
+ if(pHalData->pwrdown && eRfPowerStateToSet == rf_off)
+ {
+ // Enable register area 0x0-0xc.
+ rtw_write8(padapter, REG_RSV_CTRL, 0x0);
+
+ //
+ // <Roger_Notes> We should configure HW PDn source for WiFi ONLY, and then
+ // our HW will be set in power-down mode if PDn source from all functions are configured.
+ // 2010.10.06.
+ //
+ if(IS_HARDWARE_TYPE_8723AS(padapter))
+ {
+ value8 = rtw_read8(padapter, REG_MULTI_FUNC_CTRL);
+ rtw_write8(padapter, REG_MULTI_FUNC_CTRL, (value8|WL_HWPDN_EN));
+ }
+ else
+ {
+ rtw_write16(padapter, REG_APS_FSMCO, 0x8812);
+ }
+ }
+ //DrvIFIndicateCurrentPhyStatus(padapter); // 2010/08/17 MH Disable to prevent BSOD.
+
+ // 2010/08/26 MH Merge from 8192CE.
+ if(pwrctrlpriv->rf_pwrstate == rf_on)
+ {
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
+ if(pHalData->odmpriv.RFCalibrateInfo.bIQKInitialized){
+// PHY_IQCalibrate(padapter, _TRUE);
+ PHY_IQCalibrate_8188E(padapter,_TRUE);
+ }
+ else
+ {
+// PHY_IQCalibrate(padapter, _FALSE);
+ PHY_IQCalibrate_8188E(padapter,_FALSE);
+ pHalData->odmpriv.RFCalibrateInfo.bIQKInitialized = _TRUE;
+ }
+
+// dm_CheckTXPowerTracking(padapter);
+// PHY_LCCalibrate(padapter);
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK);
+ ODM_TXPowerTrackingCheck(&pHalData->odmpriv );
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK);
+ PHY_LCCalibrate_8188E(padapter);
+
+
+ }
+}
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS);
+ //if(pHalData->eRFPowerState == eRfOn)
+ {
+ _InitPABias(padapter);
+ }
+
+ // Init BT hw config.
+// HALBT_InitHwConfig(padapter);
+
+
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC31);
+ // 2010/05/20 MH We need to init timer after update setting. Otherwise, we can not get correct inf setting.
+ // 2010/05/18 MH For SE series only now. Init GPIO detect time
+#if 0
+ if(pDevice->RegUsbSS)
+ {
+ RT_TRACE(COMP_INIT, DBG_LOUD, (" call GpioDetectTimerStart\n"));
+ GpioDetectTimerStart(padapter); // Disable temporarily
+ }
+#endif
+
+ // 2010/08/23 MH According to Alfred's suggestion, we need to to prevent HW enter
+ // suspend mode automatically.
+ //HwSuspendModeEnable92Cu(padapter, FALSE);
+
+ // 2010/12/17 MH For TX power level OID modification from UI.
+// padapter->HalFunc.GetTxPowerLevelHandler( padapter, &pHalData->DefaultTxPwrDbm );
+ //DbgPrint("pHalData->DefaultTxPwrDbm = %d\n", pHalData->DefaultTxPwrDbm);
+
+// if(pHalData->SwBeaconType < HAL92CSDIO_DEFAULT_BEACON_TYPE) // The lowest Beacon Type that HW can support
+// pHalData->SwBeaconType = HAL92CSDIO_DEFAULT_BEACON_TYPE;
+
+ //
+ // Update current Tx FIFO page status.
+ //
+ HalQueryTxBufferStatus8189ESdio(padapter);
+
+
+ if(pregistrypriv->wifi_spec)
+ rtw_write16(padapter,REG_FAST_EDCA_CTRL ,0);
+
+
+ //TODO:Setting HW_VAR_NAV_UPPER !!!!!!!!!!!!!!!!!!!!
+ //rtw_hal_set_hwreg(Adapter, HW_VAR_NAV_UPPER, ((pu1Byte)&NavUpper));
+
+ if(IS_HARDWARE_TYPE_8188ES(padapter))
+ {
+ value8= rtw_read8(padapter, 0x4d3);
+ rtw_write8(padapter, 0x4d3, (value8|0x1));
+ }
+
+ //pHalData->PreRpwmVal = PlatformEFSdioLocalCmd52Read1Byte(Adapter, SDIO_REG_HRPWM1)&0x80;
+
+
+ // enable Tx report.
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL+1, 0x0F);
+/*
+ // Suggested by SD1 pisa. Added by tynli. 2011.10.21.
+ PlatformEFIOWrite1Byte(Adapter, REG_EARLY_MODE_CONTROL+3, 0x01);
+
+*/ //tynli_test_tx_report.
+ rtw_write16(padapter, REG_TX_RPT_TIME, 0x3DF0);
+ //RT_TRACE(COMP_INIT, DBG_TRACE, ("InitializeAdapter8188EUsb() <====\n"));
+
+
+ //enable tx DMA to drop the redundate data of packet
+ rtw_write16(padapter,REG_TXDMA_OFFSET_CHK, (rtw_read16(padapter,REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+
+//#debug print for checking compile flags
+ //DBG_8192C("RTL8188E_FPGA_TRUE_PHY_VERIFICATION=%d\n", RTL8188E_FPGA_TRUE_PHY_VERIFICATION);
+ DBG_8192C("DISABLE_BB_RF=%d\n", DISABLE_BB_RF);
+ DBG_8192C("IS_HARDWARE_TYPE_8188ES=%d\n", IS_HARDWARE_TYPE_8188ES(padapter));
+//#
+
+#ifdef CONFIG_PLATFORM_SPRD
+ // For Power Consumption, set all GPIO pin to ouput mode
+ //0x44~0x47 (GPIO 0~7), Note:GPIO5 is enabled for controlling external 26MHz request
+ rtw_write8(padapter, GPIO_IO_SEL, 0xFF);//Reg0x46, set to o/p mode
+
+ //0x42~0x43 (GPIO 8~11)
+ value8 = rtw_read8(padapter, REG_GPIO_IO_SEL);
+ rtw_write8(padapter, REG_GPIO_IO_SEL, (value8<<4)|value8);
+ value8 = rtw_read8(padapter, REG_GPIO_IO_SEL+1);
+ rtw_write8(padapter, REG_GPIO_IO_SEL+1, value8|0x0F);//Reg0x43
+#endif //CONFIG_PLATFORM_SPRD
+
+
+#ifdef CONFIG_XMIT_ACK
+ //ack for xmit mgmt frames.
+ rtw_write32(padapter, REG_FWHW_TXQ_CTRL, rtw_read32(padapter, REG_FWHW_TXQ_CTRL)|BIT(12));
+#endif //CONFIG_XMIT_ACK
+
+
+
+ //RT_TRACE(COMP_INIT, DBG_LOUD, ("<---Initializepadapter8192CSdio()\n"));
+ DBG_8192C("-rtl8188es_hal_init\n");
+
+exit:
+HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
+
+ DBG_871X("%s in %dms\n", __FUNCTION__, rtw_get_passing_time_ms(init_start_time));
+
+ #ifdef DBG_HAL_INIT_PROFILING
+ hal_init_stages_timestamp[HAL_INIT_STAGES_END]=rtw_get_current_time();
+
+ for(hal_init_profiling_i=0;hal_init_profiling_i<HAL_INIT_STAGES_NUM-1;hal_init_profiling_i++) {
+ DBG_871X("DBG_HAL_INIT_PROFILING: %35s, %u, %5u, %5u\n"
+ , hal_init_stages_str[hal_init_profiling_i]
+ , hal_init_stages_timestamp[hal_init_profiling_i]
+ , (hal_init_stages_timestamp[hal_init_profiling_i+1]-hal_init_stages_timestamp[hal_init_profiling_i])
+ , rtw_get_time_interval_ms(hal_init_stages_timestamp[hal_init_profiling_i], hal_init_stages_timestamp[hal_init_profiling_i+1])
+ );
+ }
+ #endif
+
+ return ret;
+
+}
+
+static void CardDisableRTL8188ESdio(PADAPTER padapter)
+{
+ u8 u1bTmp;
+ u16 u2bTmp;
+ u32 u4bTmp;
+ u8 bMacPwrCtrlOn;
+ u8 ret;
+#ifdef CONFIG_PLATFORM_SPRD
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+#endif //CONFIG_PLATFORM_SPRD
+
+ DBG_871X("=>%s\n", __FUNCTION__);
+
+
+ //Stop Tx Report Timer. 0x4EC[Bit1]=b'0
+ u1bTmp = rtw_read8(padapter, REG_TX_RPT_CTRL);
+ rtw_write8(padapter, REG_TX_RPT_CTRL, u1bTmp&(~BIT1));
+
+ // stop rx
+ rtw_write8(padapter,REG_CR, 0x0);
+
+
+#ifdef CONFIG_EXT_CLK //for sprd For Power Consumption.
+ EnableGpio5ClockReq(padapter, _FALSE, 0);
+#endif //CONFIG_EXT_CLK
+
+#if 1
+ // For Power Consumption.
+ u1bTmp = rtw_read8(padapter, GPIO_IN);
+ rtw_write8(padapter, GPIO_OUT, u1bTmp);
+ rtw_write8(padapter, GPIO_IO_SEL, 0xFF);//Reg0x46
+
+ u1bTmp = rtw_read8(padapter, REG_GPIO_IO_SEL);
+ rtw_write8(padapter, REG_GPIO_IO_SEL, (u1bTmp<<4)|u1bTmp);
+ u1bTmp = rtw_read8(padapter, REG_GPIO_IO_SEL+1);
+ rtw_write8(padapter, REG_GPIO_IO_SEL+1, u1bTmp|0x0F);//Reg0x43
+#endif
+
+
+ // Run LPS WL RFOFF flow
+ ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, Rtl8188E_NIC_LPS_ENTER_FLOW);
+ if (ret == _FALSE) {
+ DBG_871X("%s: run RF OFF flow fail!\n", __func__);
+ }
+
+ // ==== Reset digital sequence ======
+
+ u1bTmp = rtw_read8(padapter, REG_MCUFWDL);
+ if ((u1bTmp & RAM_DL_SEL) && padapter->bFWReady) //8051 RAM code
+ {
+ //rtl8723a_FirmwareSelfReset(padapter);
+ //_8051Reset88E(padapter);
+
+ // Reset MCU 0x2[10]=0.
+ u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+ u1bTmp &= ~BIT(2); // 0x2[10], FEN_CPUEN
+ rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp);
+ }
+
+ //u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+ //u1bTmp &= ~BIT(2); // 0x2[10], FEN_CPUEN
+ //rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp);
+
+ // MCUFWDL 0x80[1:0]=0
+ // reset MCU ready status
+ rtw_write8(padapter, REG_MCUFWDL, 0);
+
+ //==== Reset digital sequence end ======
+
+
+ bMacPwrCtrlOn = _FALSE; // Disable CMD53 R/W
+ rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+
+
+/*
+ if((pMgntInfo->RfOffReason & RF_CHANGE_BY_HW) && pHalData->pwrdown)
+ {// Power Down
+
+ // Card disable power action flow
+ ret = HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, Rtl8188E_NIC_PDN_FLOW);
+ }
+ else
+*/
+#ifdef CONFIG_PLATFORM_SPRD
+ // for sprd, it will enable power down mode when enter suspend and remove driver, so needn't call card disable flow.
+ //if(pwrpriv->bInSuspend != _TRUE)
+ if(pwrpriv->bpower_saving == _TRUE) // when bpower_saving == _TRUE at this moment is only indicate driver is going to IPS Mode.
+#endif //CONFIG_PLATFORM_SPRD
+ { // Non-Power Down
+
+ // Card disable power action flow
+ ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, Rtl8188E_NIC_DISABLE_FLOW);
+
+
+ if (ret == _FALSE) {
+ DBG_871X("%s: run CARD DISABLE flow fail!\n", __func__);
+ }
+ }
+
+
+/*
+ // Reset MCU IO Wrapper, added by Roger, 2011.08.30
+ u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
+ u1bTmp &= ~BIT(0);
+ rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp);
+ u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
+ u1bTmp |= BIT(0);
+ rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp);
+*/
+
+
+ // RSV_CTRL 0x1C[7:0]=0x0E
+ // lock ISO/CLK/Power control register
+ rtw_write8(padapter, REG_RSV_CTRL, 0x0E);
+
+ padapter->bFWReady = _FALSE;
+ DBG_871X("<=%s\n", __FUNCTION__);
+
+}
+
+static u32 rtl8188es_hal_deinit(PADAPTER padapter)
+{
+ DBG_871X("=>%s\n", __FUNCTION__);
+
+ if (padapter->hw_init_completed == _TRUE)
+ CardDisableRTL8188ESdio(padapter);
+
+ DBG_871X("<=%s\n", __FUNCTION__);
+
+ return _SUCCESS;
+}
+
+static u32 rtl8188es_inirp_init(PADAPTER padapter)
+{
+ u32 status;
+
+_func_enter_;
+
+ status = _SUCCESS;
+
+_func_exit_;
+
+ return status;
+}
+
+static u32 rtl8188es_inirp_deinit(PADAPTER padapter)
+{
+ RT_TRACE(_module_hci_hal_init_c_,_drv_info_,("+rtl8188es_inirp_deinit\n"));
+
+ RT_TRACE(_module_hci_hal_init_c_,_drv_info_,("-rtl8188es_inirp_deinit\n"));
+
+ return _SUCCESS;
+}
+
+static void rtl8188es_init_default_value(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+ struct pwrctrl_priv *pwrctrlpriv;
+ struct dm_priv *pdmpriv;
+ u8 i;
+
+ pHalData = GET_HAL_DATA(padapter);
+ pwrctrlpriv = &padapter->pwrctrlpriv;
+ pdmpriv = &pHalData->dmpriv;
+
+
+ //init default value
+ pHalData->fw_ractrl = _FALSE;
+ if(!pwrctrlpriv->bkeepfwalive)
+ pHalData->LastHMEBoxNum = 0;
+
+ //init dm default value
+ pHalData->odmpriv.RFCalibrateInfo.bIQKInitialized = _FALSE;
+ pHalData->odmpriv.RFCalibrateInfo.TM_Trigger = 0;//for IQK
+ //pdmpriv->binitialized = _FALSE;
+// pdmpriv->prv_traffic_idx = 3;
+// pdmpriv->initialize = 0;
+ pHalData->pwrGroupCnt = 0;
+ pHalData->PGMaxGroup= 13;
+ pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP_index = 0;
+ for(i = 0; i < HP_THERMAL_NUM; i++)
+ pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0;
+
+ // interface related variable
+ pHalData->SdioRxFIFOCnt = 0;
+}
+
+//
+// Description:
+// We should set Efuse cell selection to WiFi cell in default.
+//
+// Assumption:
+// PASSIVE_LEVEL
+//
+// Added by Roger, 2010.11.23.
+//
+static void _EfuseCellSel(
+ IN PADAPTER padapter
+ )
+{
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ u32 value32;
+
+ //if(INCLUDE_MULTI_FUNC_BT(padapter))
+ {
+ value32 = rtw_read32(padapter, EFUSE_TEST);
+ value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
+ rtw_write32(padapter, EFUSE_TEST, value32);
+ }
+}
+
+static VOID
+_ReadRFType(
+ IN PADAPTER Adapter
+ )
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+#if DISABLE_BB_RF
+ pHalData->rf_chip = RF_PSEUDO_11N;
+#else
+ pHalData->rf_chip = RF_6052;
+#endif
+}
+
+static void
+Hal_EfuseParsePIDVID_8188ES(
+ IN PADAPTER pAdapter,
+ IN u8* hwinfo,
+ IN BOOLEAN AutoLoadFail
+ )
+{
+// HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ //
+ // <Roger_Notes> The PID/VID info was parsed from CISTPL_MANFID Tuple in CIS area before.
+ // VID is parsed from Manufacture code field and PID is parsed from Manufacture information field.
+ // 2011.04.01.
+ //
+
+// RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM VID = 0x%4x\n", pHalData->EEPROMVID));
+// RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM PID = 0x%4x\n", pHalData->EEPROMPID));
+}
+
+static void
+Hal_EfuseParseMACAddr_8188ES(
+ IN PADAPTER padapter,
+ IN u8* hwinfo,
+ IN BOOLEAN AutoLoadFail
+ )
+{
+ u16 i, usValue;
+ u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x88, 0x77};
+ EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+
+ if (AutoLoadFail)
+ {
+// sMacAddr[5] = (u1Byte)GetRandomNumber(1, 254);
+ for (i=0; i<6; i++)
+ pEEPROM->mac_addr[i] = sMacAddr[i];
+ }
+ else
+ {
+ //Read Permanent MAC address
+ _rtw_memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_88ES], ETH_ALEN);
+
+ }
+// NicIFSetMacAddress(pAdapter, pAdapter->PermanentAddress);
+
+ DBG_871X("Hal_EfuseParseMACAddr_8188ES: Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
+ pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
+ pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
+ pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]);
+}
+
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+static u32 Hal_readPGDataFromConfigFile(
+ PADAPTER padapter)
+{
+ u32 i;
+ struct file *fp;
+ mm_segment_t fs;
+ u8 temp[3];
+ loff_t pos = 0;
+ EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+ u8 *PROMContent = pEEPROM->efuse_eeprom_data;
+
+
+ temp[2] = 0; // add end of string '\0'
+
+ fp = filp_open("/system/etc/wifi/wifi_efuse.map", O_RDWR, 0644);
+ if (IS_ERR(fp)) {
+ pEEPROM->bloadfile_fail_flag = _TRUE;
+ DBG_871X("Error, Efuse configure file doesn't exist.\n");
+ return _FAIL;
+ }
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ DBG_871X("Efuse configure file:\n");
+ for (i=0; i<HWSET_MAX_SIZE_88E; i++) {
+ vfs_read(fp, temp, 2, &pos);
+ PROMContent[i] = simple_strtoul(temp, NULL, 16 );
+ pos += 1; // Filter the space character
+ DBG_871X("%02X \n", PROMContent[i]);
+ }
+ DBG_871X("\n");
+ set_fs(fs);
+
+ filp_close(fp, NULL);
+ pEEPROM->bloadfile_fail_flag = _FALSE;
+ return _SUCCESS;
+}
+
+static void
+Hal_ReadMACAddrFromFile_8188ES(
+ PADAPTER padapter
+ )
+{
+ u32 i;
+ struct file *fp;
+ mm_segment_t fs;
+ u8 source_addr[18];
+ loff_t pos = 0;
+ u32 curtime = rtw_get_current_time();
+ EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+ u8 *head, *end;
+
+ u8 null_mac_addr[ETH_ALEN] = {0, 0, 0,0, 0, 0};
+ u8 multi_mac_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ _rtw_memset(source_addr, 0, 18);
+ _rtw_memset(pEEPROM->mac_addr, 0, ETH_ALEN);
+
+ fp = filp_open("/data/wifimac.txt", O_RDWR, 0644);
+ if (IS_ERR(fp)) {
+ pEEPROM->bloadmac_fail_flag = _TRUE;
+ DBG_871X("Error, wifi mac address file doesn't exist.\n");
+ } else {
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ DBG_871X("wifi mac address:\n");
+ vfs_read(fp, source_addr, 18, &pos);
+ source_addr[17] = ':';
+
+ head = end = source_addr;
+ for (i=0; i<ETH_ALEN; i++) {
+ while (end && (*end != ':') )
+ end++;
+
+ if (end && (*end == ':') )
+ *end = '\0';
+
+ pEEPROM->mac_addr[i] = simple_strtoul(head, NULL, 16 );
+
+ if (end) {
+ end++;
+ head = end;
+ }
+ DBG_871X("%02x \n", pEEPROM->mac_addr[i]);
+ }
+ DBG_871X("\n");
+ set_fs(fs);
+ pEEPROM->bloadmac_fail_flag = _FALSE;
+ filp_close(fp, NULL);
+ }
+
+ if ( (_rtw_memcmp(pEEPROM->mac_addr, null_mac_addr, ETH_ALEN)) ||
+ (_rtw_memcmp(pEEPROM->mac_addr, multi_mac_addr, ETH_ALEN)) ) {
+ pEEPROM->mac_addr[0] = 0x00;
+ pEEPROM->mac_addr[1] = 0xe0;
+ pEEPROM->mac_addr[2] = 0x4c;
+ pEEPROM->mac_addr[3] = (u8)(curtime & 0xff) ;
+ pEEPROM->mac_addr[4] = (u8)((curtime>>8) & 0xff) ;
+ pEEPROM->mac_addr[5] = (u8)((curtime>>16) & 0xff) ;
+ }
+
+ DBG_871X("Hal_ReadMACAddrFromFile_8188ES: Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
+ pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
+ pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
+ pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]);
+}
+#endif //CONFIG_EFUSE_CONFIG_FILE
+
+static VOID
+readAdapterInfo_8188ES(
+ IN PADAPTER padapter
+ )
+{
+ EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+
+ /* parse the eeprom/efuse content */
+ Hal_EfuseParseIDCode88E(padapter, pEEPROM->efuse_eeprom_data);
+ Hal_EfuseParsePIDVID_8188ES(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+ Hal_ReadMACAddrFromFile_8188ES(padapter);
+#else //CONFIG_EFUSE_CONFIG_FILE
+ Hal_EfuseParseMACAddr_8188ES(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+#endif //CONFIG_EFUSE_CONFIG_FILE
+
+ Hal_ReadPowerSavingMode88E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ Hal_ReadTxPowerInfo88E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ Hal_EfuseParseEEPROMVer88E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ rtl8188e_EfuseParseChnlPlan(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ Hal_EfuseParseXtal_8188E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ Hal_EfuseParseCustomerID88E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ //Hal_ReadAntennaDiversity88E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ Hal_EfuseParseBoardType88E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ Hal_ReadThermalMeter_88E(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+ //
+ // The following part initialize some vars by PG info.
+ //
+ Hal_InitChannelPlan(padapter);
+#ifdef CONFIG_WOWLAN
+ Hal_DetectWoWMode(padapter);
+#endif //CONFIG_WOWLAN
+#ifdef CONFIG_RF_GAIN_OFFSET
+ Hal_ReadRFGainOffset(padapter, pEEPROM->efuse_eeprom_data, pEEPROM->bautoload_fail_flag);
+#endif //CONFIG_RF_GAIN_OFFSET
+}
+
+static void _ReadPROMContent(
+ IN PADAPTER padapter
+ )
+{
+ EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+ u8 eeValue;
+
+ /* check system boot selection */
+ eeValue = rtw_read8(padapter, REG_9346CR);
+ pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? _TRUE : _FALSE;
+ pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? _FALSE : _TRUE;
+
+ DBG_871X("%s: 9346CR=0x%02X, Boot from %s, Autoload %s\n",
+ __FUNCTION__, eeValue,
+ (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"),
+ (pEEPROM->bautoload_fail_flag ? "Fail" : "OK"));
+
+// pHalData->EEType = IS_BOOT_FROM_EEPROM(Adapter) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE;
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+ Hal_readPGDataFromConfigFile(padapter);
+#else //CONFIG_EFUSE_CONFIG_FILE
+ Hal_InitPGData88E(padapter);
+#endif //CONFIG_EFUSE_CONFIG_FILE
+ readAdapterInfo_8188ES(padapter);
+}
+
+static VOID
+_InitOtherVariable(
+ IN PADAPTER Adapter
+ )
+{
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+
+ //if(Adapter->bInHctTest){
+ // pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
+ // pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
+ // pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
+ // pMgntInfo->keepAliveLevel = 0;
+ //}
+
+
+}
+
+//
+// Description:
+// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
+//
+// Assumption:
+// PASSIVE_LEVEL (SDIO interface)
+//
+//
+static s32 _ReadAdapterInfo8188ES(PADAPTER padapter)
+{
+ u32 start;
+
+
+ RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+_ReadAdapterInfo8188ES\n"));
+
+ // before access eFuse, make sure card enable has been called
+ if(_CardEnable(padapter) == _FAIL)
+ {
+ DBG_871X(KERN_ERR "%s: run power on flow fail\n", __func__);
+ return _FAIL;
+ }
+
+ start = rtw_get_current_time();
+
+// Efuse_InitSomeVar(Adapter);
+// pHalData->VersionID = ReadChipVersion(Adapter);
+// _EfuseCellSel(padapter);
+
+ _ReadRFType(padapter);//rf_chip -> _InitRFType()
+ _ReadPROMContent(padapter);
+
+ // 2010/10/25 MH THe function must be called after borad_type & IC-Version recognize.
+ //ReadSilmComboMode(Adapter);
+ _InitOtherVariable(padapter);
+
+
+ //MSG_8192C("%s()(done), rf_chip=0x%x, rf_type=0x%x\n", __FUNCTION__, pHalData->rf_chip, pHalData->rf_type);
+ MSG_8192C("<==== ReadAdapterInfo8188ES in %d ms\n", rtw_get_passing_time_ms(start));
+
+ return _SUCCESS;
+}
+
+static void ReadAdapterInfo8188ES(PADAPTER padapter)
+{
+ // Read EEPROM size before call any EEPROM function
+ padapter->EepromAddressSize = GetEEPROMSize8188E(padapter);
+
+ _ReadAdapterInfo8188ES(padapter);
+}
+
+static void ResumeTxBeacon(PADAPTER padapter)
+{
+ HAL_DATA_TYPE* pHalData = GET_HAL_DATA(padapter);
+
+ // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
+ // which should be read from register to a global variable.
+
+ RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
+
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) | BIT6);
+ pHalData->RegFwHwTxQCtrl |= BIT6;
+ rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
+ pHalData->RegReg542 |= BIT0;
+ rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
+}
+
+static void StopTxBeacon(PADAPTER padapter)
+{
+ HAL_DATA_TYPE* pHalData = GET_HAL_DATA(padapter);
+
+ // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
+ // which should be read from register to a global variable.
+
+ RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
+
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) & (~BIT6));
+ pHalData->RegFwHwTxQCtrl &= (~BIT6);
+ rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
+ pHalData->RegReg542 &= ~(BIT0);
+ rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
+
+ CheckFwRsvdPageContent(padapter); // 2010.06.23. Added by tynli.
+}
+
+// todo static
+void hw_var_set_opmode(PADAPTER Adapter, u8 variable, u8* val)
+{
+ u8 val8;
+ u8 mode = *((u8 *)val);
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(Adapter->iface_type == IFACE_PORT1)
+ {
+ // disable Port1 TSF update
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4));
+
+ // set net_type
+ val8 = rtw_read8(Adapter, MSR)&0x03;
+ val8 |= (mode<<2);
+ rtw_write8(Adapter, MSR, val8);
+
+ DBG_871X("%s()-%d mode = %d\n", __FUNCTION__, __LINE__, mode);
+
+ if((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
+ {
+ if(!check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE))
+ {
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN
+
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ rtw_write8(Adapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms
+ UpdateInterruptMask8188ESdio(Adapter, 0, SDIO_HIMR_BCNERLY_INT_MSK);
+ #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188ESdio(Adapter, 0, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK));
+ #endif// CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+
+ #endif //CONFIG_INTERRUPT_BASED_TXBCN
+
+
+ StopTxBeacon(Adapter);
+ }
+
+ rtw_write8(Adapter,REG_BCN_CTRL_1, 0x19);//disable atim wnd
+ //rtw_write8(Adapter,REG_BCN_CTRL_1, 0x18);
+ }
+ else if((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
+ {
+ ResumeTxBeacon(Adapter);
+ rtw_write8(Adapter,REG_BCN_CTRL_1, 0x1a);
+ }
+ else if(mode == _HW_STATE_AP_)
+ {
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ UpdateInterruptMask8188ESdio(Adapter, SDIO_HIMR_BCNERLY_INT_MSK, 0);
+ #endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188ESdio(Adapter, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK), 0);
+ #endif//CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+
+#endif //CONFIG_INTERRUPT_BASED_TXBCN
+
+ ResumeTxBeacon(Adapter);
+
+ rtw_write8(Adapter, REG_BCN_CTRL_1, 0x12);
+
+ //enable SW Beacon
+ rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR)|BIT(8));
+
+ //Set RCR
+ //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
+ rtw_write32(Adapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,Reject ICV_ERROR packets
+
+ //enable to rx data frame
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ //enable to rx ps-poll
+ rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
+
+ //Beacon Control related register for first time
+ rtw_write8(Adapter, REG_BCNDMATIM, 0x02); // 2ms
+
+ //rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);
+ rtw_write8(Adapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
+ rtw_write16(Adapter, REG_BCNTCFG, 0x00);
+ rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
+ rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
+
+ //reset TSF2
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));
+
+
+ //BIT4 - If set 0, hw will clr bcnq when tx becon ok/fail or port 1
+ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM)|BIT(3)|BIT(4));
+ //enable BCN1 Function for if2
+ //don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received)
+ rtw_write8(Adapter, REG_BCN_CTRL_1, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | EN_TXBCN_RPT|BIT(1)));
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(check_buddy_fwstate(Adapter, WIFI_FW_NULL_STATE))
+ rtw_write8(Adapter, REG_BCN_CTRL,
+ rtw_read8(Adapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION);
+#endif
+ //BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked
+ //rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(5));
+ //rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(3));
+
+ //dis BCN0 ATIM WND if if1 is station
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(0));
+
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+ // Reset TSF for STA+AP concurrent mode
+ if ( check_buddy_fwstate(Adapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) {
+ if (reset_tsf(Adapter, IFACE_PORT1) == _FALSE)
+ DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
+ __FUNCTION__, __LINE__);
+ }
+#endif // CONFIG_TSF_RESET_OFFLOAD
+ }
+ }
+ else
+#endif //CONFIG_CONCURRENT_MODE
+ {
+ // disable Port0 TSF update
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+
+ // set net_type
+ val8 = rtw_read8(Adapter, MSR)&0x0c;
+ val8 |= mode;
+ rtw_write8(Adapter, MSR, val8);
+
+ DBG_871X("%s()-%d mode = %d\n", __FUNCTION__, __LINE__, mode);
+
+ if((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
+ {
+#ifdef CONFIG_CONCURRENT_MODE
+ if(!check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE))
+#endif //CONFIG_CONCURRENT_MODE
+ {
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ rtw_write8(Adapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms
+ UpdateInterruptMask8188ESdio(Adapter, 0, SDIO_HIMR_BCNERLY_INT_MSK);
+ #endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188ESdio(Adapter, 0, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK));
+ #endif //CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ #endif //CONFIG_INTERRUPT_BASED_TXBCN
+ StopTxBeacon(Adapter);
+ }
+
+ rtw_write8(Adapter,REG_BCN_CTRL, 0x19);//disable atim wnd
+ //rtw_write8(Adapter,REG_BCN_CTRL, 0x18);
+ }
+ else if((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
+ {
+ ResumeTxBeacon(Adapter);
+ rtw_write8(Adapter,REG_BCN_CTRL, 0x1a);
+ }
+ else if(mode == _HW_STATE_AP_)
+ {
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ UpdateInterruptMask8188ESdio(Adapter, SDIO_HIMR_BCNERLY_INT_MSK, 0);
+ #endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188ESdio(Adapter, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK), 0);
+ #endif//CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+#endif //CONFIG_INTERRUPT_BASED_TXBCN
+
+
+ ResumeTxBeacon(Adapter);
+
+ rtw_write8(Adapter, REG_BCN_CTRL, 0x12);
+
+ //enable SW Beacon
+ rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR)|BIT(8));
+
+ //Set RCR
+ //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
+ rtw_write32(Adapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
+ //enable to rx data frame
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ //enable to rx ps-poll
+ rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
+
+ //Beacon Control related register for first time
+ rtw_write8(Adapter, REG_BCNDMATIM, 0x02); // 2ms
+
+ //rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);
+ rtw_write8(Adapter, REG_ATIMWND, 0x0a); // 10ms
+ rtw_write16(Adapter, REG_BCNTCFG, 0x00);
+ rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
+ rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
+
+ //reset TSF
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
+
+ //BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0
+ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM)|BIT(3)|BIT(4));
+
+ //enable BCN0 Function for if1
+ //don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received)
+ rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | EN_TXBCN_RPT|BIT(1)));
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(check_buddy_fwstate(Adapter, WIFI_FW_NULL_STATE))
+ rtw_write8(Adapter, REG_BCN_CTRL_1,
+ rtw_read8(Adapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION);
+#endif
+
+ //dis BCN1 ATIM WND if if2 is station
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(0));
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+ // Reset TSF for STA+AP concurrent mode
+ if ( check_buddy_fwstate(Adapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) {
+ if (reset_tsf(Adapter, IFACE_PORT0) == _FALSE)
+ DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
+ __FUNCTION__, __LINE__);
+ }
+#endif // CONFIG_TSF_RESET_OFFLOAD
+ }
+ }
+
+}
+
+static void hw_var_set_macaddr(PADAPTER Adapter, u8 variable, u8* val)
+{
+ u8 idx = 0;
+ u32 reg_macid;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(Adapter->iface_type == IFACE_PORT1)
+ {
+ reg_macid = REG_MACID1;
+ }
+ else
+#endif
+ {
+ reg_macid = REG_MACID;
+ }
+
+ for(idx = 0 ; idx < 6; idx++)
+ {
+ rtw_write8(Adapter, (reg_macid+idx), val[idx]);
+ }
+
+}
+
+static void hw_var_set_bssid(PADAPTER Adapter, u8 variable, u8* val)
+{
+ u8 idx = 0;
+ u32 reg_bssid;
+
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(Adapter->iface_type == IFACE_PORT1)
+ {
+ reg_bssid = REG_BSSID1;
+ }
+ else
+#endif
+ {
+ reg_bssid = REG_BSSID;
+ }
+
+printk("hw_var_set_bssid reg=%x \n", reg_bssid);
+
+ for(idx = 0 ; idx < 6; idx++)
+ {
+ rtw_write8(Adapter, (reg_bssid+idx), val[idx]);
+ }
+
+}
+
+static void hw_var_set_bcn_func(PADAPTER Adapter, u8 variable, u8* val)
+{
+ u32 bcn_ctrl_reg;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(Adapter->iface_type == IFACE_PORT1)
+ {
+ bcn_ctrl_reg = REG_BCN_CTRL_1;
+ }
+ else
+#endif
+ {
+ bcn_ctrl_reg = REG_BCN_CTRL;
+ }
+
+ if(*((u8 *)val))
+ {
+ rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
+ }
+ else
+ {
+ rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ }
+
+
+}
+
+static void hw_var_set_correct_tsf(PADAPTER Adapter, u8 variable, u8* val)
+{
+#ifdef CONFIG_CONCURRENT_MODE
+ u64 tsf;
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
+
+ //tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) -1024; //us
+ tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us
+
+ if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
+ {
+ //pHalData->RegTxPause |= STOP_BCNQ;BIT(6)
+ //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6)));
+ StopTxBeacon(Adapter);
+ }
+
+ if(Adapter->iface_type == IFACE_PORT1)
+ {
+ //disable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3)));
+
+ rtw_write32(Adapter, REG_TSFTR1, tsf);
+ rtw_write32(Adapter, REG_TSFTR1+4, tsf>>32);
+ //enable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(3));
+ // Update buddy port's TSF if it is SoftAP for beacon TX issue!
+ if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
+ && check_buddy_fwstate(Adapter, WIFI_AP_STATE)
+ ) {
+ //disable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3)));
+
+ rtw_write32(Adapter, REG_TSFTR, tsf);
+ rtw_write32(Adapter, REG_TSFTR+4, tsf>>32);
+
+ //enable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3));
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+ // Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue!
+ if (reset_tsf(Adapter, IFACE_PORT0) == _FALSE)
+ DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
+ __FUNCTION__, __LINE__);
+
+#endif // CONFIG_TSF_RESET_OFFLOAD
+ }
+
+ }
+ else
+ {
+ //disable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3)));
+
+ rtw_write32(Adapter, REG_TSFTR, tsf);
+ rtw_write32(Adapter, REG_TSFTR+4, tsf>>32);
+
+ //enable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3));
+ // Update buddy port's TSF if it is SoftAP for beacon TX issue!
+ if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
+ && check_buddy_fwstate(Adapter, WIFI_AP_STATE)
+ ) {
+ //disable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3)));
+
+ rtw_write32(Adapter, REG_TSFTR1, tsf);
+ rtw_write32(Adapter, REG_TSFTR1+4, tsf>>32);
+
+ //enable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(3));
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+ // Update buddy port's TSF if it is SoftAP for beacon TX issue!
+ if (reset_tsf(Adapter, IFACE_PORT1) == _FALSE)
+ DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
+ __FUNCTION__, __LINE__);
+#endif // CONFIG_TSF_RESET_OFFLOAD
+ }
+ }
+
+
+ if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
+ {
+ //pHalData->RegTxPause &= (~STOP_BCNQ);
+ //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)&(~BIT(6))));
+ ResumeTxBeacon(Adapter);
+ }
+#endif
+}
+
+static void hw_var_set_mlme_disconnect(PADAPTER Adapter, u8 variable, u8* val)
+{
+#ifdef CONFIG_CONCURRENT_MODE
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
+
+
+ if(check_buddy_mlmeinfo_state(Adapter, _HW_STATE_NOLINK_))
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
+
+
+ if(Adapter->iface_type == IFACE_PORT1)
+ {
+ //reset TSF1
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));
+
+ //disable update TSF1
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4));
+ }
+ else
+ {
+ //reset TSF
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
+
+ //disable update TSF
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+ }
+#endif
+}
+
+static void hw_var_set_mlme_sitesurvey(PADAPTER Adapter, u8 variable, u8* val)
+{
+#ifdef CONFIG_CONCURRENT_MODE
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ if(*((u8 *)val))//under sitesurvey
+ {
+ //config RCR to receive different BSSID & not to receive data frame
+ u32 v = rtw_read32(Adapter, REG_RCR);
+ v &= ~(RCR_CBSSID_BCN);
+ rtw_write32(Adapter, REG_RCR, v);
+
+ //disable update TSF
+ if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
+ {
+ if(Adapter->iface_type == IFACE_PORT1)
+ {
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4));
+ }
+ else
+ {
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+ }
+ }
+
+ if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
+ check_buddy_fwstate(Adapter, _FW_LINKED))
+ {
+ StopTxBeacon(Adapter);
+ }
+
+ }
+ else//sitesurvey done
+ {
+ //enable to rx data frame
+ //write32(Adapter, REG_RCR, read32(padapter, REG_RCR)|RCR_ADF);
+ rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF);
+
+ //enable update TSF
+ if(Adapter->iface_type == IFACE_PORT1)
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(4)));
+ else
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
+
+ if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
+ check_buddy_fwstate(Adapter, _FW_LINKED))
+ {
+ ResumeTxBeacon(Adapter);
+ }
+
+ }
+#endif
+}
+
+static void hw_var_set_mlme_join(PADAPTER Adapter, u8 variable, u8* val)
+{
+#ifdef CONFIG_CONCURRENT_MODE
+ u8 RetryLimit = 0x30;
+ u8 type = *((u8 *)val);
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+
+ if(type == 0) // prepare to join
+ {
+ if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
+ check_buddy_fwstate(Adapter, _FW_LINKED))
+ {
+ StopTxBeacon(Adapter);
+ }
+
+ //enable to rx data frame.Accept all data frame
+ //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
+ rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF);
+
+ if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE))
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
+ else
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
+
+ if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
+ {
+ RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
+ }
+ else // Ad-hoc Mode
+ {
+ RetryLimit = 0x7;
+ }
+ }
+ else if(type == 1) //joinbss_event call back when join res < 0
+ {
+ if(check_buddy_mlmeinfo_state(Adapter, _HW_STATE_NOLINK_))
+ rtw_write16(Adapter, REG_RXFLTMAP2,0x00);
+
+ if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
+ check_buddy_fwstate(Adapter, _FW_LINKED))
+ {
+ ResumeTxBeacon(Adapter);
+
+ //reset TSF 1/2 after ResumeTxBeacon
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
+
+ }
+ }
+ else if(type == 2) //sta add event call back
+ {
+
+ //enable update TSF
+ if(Adapter->iface_type == IFACE_PORT1)
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(4)));
+ else
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+
+
+ if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
+ {
+ //fixed beacon issue for 8191su...........
+ rtw_write8(Adapter,0x542 ,0x02);
+ RetryLimit = 0x7;
+ }
+
+
+ if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
+ check_buddy_fwstate(Adapter, _FW_LINKED))
+ {
+ ResumeTxBeacon(Adapter);
+
+ //reset TSF 1/2 after ResumeTxBeacon
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
+ }
+
+ }
+
+ rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+
+#endif
+}
+static void SetHwReg8188ES(PADAPTER Adapter, u8 variable, u8* val)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct dm_priv *pdmpriv = &pHalData->dmpriv;
+ DM_ODM_T *podmpriv = &pHalData->odmpriv;
+_func_enter_;
+
+ switch(variable)
+ {
+ case HW_VAR_MEDIA_STATUS:
+ {
+ u8 val8;
+
+ val8 = rtw_read8(Adapter, MSR)&0x0c;
+ val8 |= *((u8 *)val);
+ rtw_write8(Adapter, MSR, val8);
+ }
+ break;
+ case HW_VAR_MEDIA_STATUS1:
+ {
+ u8 val8;
+
+ val8 = rtw_read8(Adapter, MSR)&0x03;
+ val8 |= *((u8 *)val) <<2;
+ rtw_write8(Adapter, MSR, val8);
+ }
+ break;
+ case HW_VAR_SET_OPMODE:
+ hw_var_set_opmode(Adapter, variable, val);
+ break;
+ case HW_VAR_MAC_ADDR:
+ hw_var_set_macaddr(Adapter, variable, val);
+ break;
+ case HW_VAR_BSSID:
+ hw_var_set_bssid(Adapter, variable, val);
+ break;
+ case HW_VAR_BASIC_RATE:
+ {
+ u16 BrateCfg = 0;
+ u8 RateIndex = 0;
+
+ // 2007.01.16, by Emily
+ // Select RRSR (in Legacy-OFDM and CCK)
+ // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
+ // We do not use other rates.
+ HalSetBrateCfg( Adapter, val, &BrateCfg );
+ DBG_8192C("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg);
+
+ //2011.03.30 add by Luke Lee
+ //CCK 2M ACK should be disabled for some BCM and Atheros AP IOT
+ //because CCK 2M has poor TXEVM
+ //CCK 5.5M & 11M ACK should be enabled for better performance
+
+ pHalData->BasicRateSet = BrateCfg = (BrateCfg |0xd) & 0x15d;
+
+ BrateCfg |= 0x01; // default enable 1M ACK rate
+ // Set RRSR rate table.
+ rtw_write8(Adapter, REG_RRSR, BrateCfg&0xff);
+ rtw_write8(Adapter, REG_RRSR+1, (BrateCfg>>8)&0xff);
+ rtw_write8(Adapter, REG_RRSR+2, rtw_read8(Adapter, REG_RRSR+2)&0xf0);
+
+ // Set RTS initial rate
+ while(BrateCfg > 0x1)
+ {
+ BrateCfg = (BrateCfg>> 1);
+ RateIndex++;
+ }
+ // Ziv - Check
+ rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex);
+ }
+ break;
+ case HW_VAR_TXPAUSE:
+ rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val));
+ break;
+ case HW_VAR_BCN_FUNC:
+ hw_var_set_bcn_func(Adapter, variable, val);
+ break;
+ case HW_VAR_CORRECT_TSF:
+#ifdef CONFIG_CONCURRENT_MODE
+ hw_var_set_correct_tsf(Adapter, variable, val);
+#else
+ {
+ u64 tsf;
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ //f = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) -1024; //us
+ tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) - 1024; //us
+
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
+ ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
+ {
+ //pHalData->RegTxPause |= STOP_BCNQ;BIT(6)
+ //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6)));
+ StopTxBeacon(Adapter);
+ }
+
+ // disable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3)));
+
+ rtw_write32(Adapter, REG_TSFTR, tsf);
+ rtw_write32(Adapter, REG_TSFTR+4, tsf>>32);
+
+ // enable related TSF function
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3));
+
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
+ ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
+ {
+ //pHalData->RegTxPause &= (~STOP_BCNQ);
+ //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)&(~BIT(6))));
+ ResumeTxBeacon(Adapter);
+ }
+ }
+#endif
+ break;
+ case HW_VAR_CHECK_BSSID:
+ if(*((u8 *)val))
+ {
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
+ }
+ else
+ {
+ u32 val32;
+
+ val32 = rtw_read32(Adapter, REG_RCR);
+
+ val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+
+ rtw_write32(Adapter, REG_RCR, val32);
+ }
+ break;
+ case HW_VAR_MLME_DISCONNECT:
+#ifdef CONFIG_CONCURRENT_MODE
+ hw_var_set_mlme_disconnect(Adapter, variable, val);
+#else
+ {
+ //Set RCR to not to receive data frame when NO LINK state
+ //rtw_write32(Adapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
+ //reject all data frames
+ rtw_write16(Adapter, REG_RXFLTMAP2,0x00);
+
+ //reset TSF
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1)));
+
+ //disable update TSF
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+ }
+#endif
+ break;
+ case HW_VAR_MLME_SITESURVEY:
+#ifdef CONFIG_CONCURRENT_MODE
+ hw_var_set_mlme_sitesurvey(Adapter, variable, val);
+#else
+ if(*((u8 *)val))//under sitesurvey
+ {
+ //config RCR to receive different BSSID & not to receive data frame
+ u32 v = rtw_read32(Adapter, REG_RCR);
+ v &= ~(RCR_CBSSID_BCN);
+ rtw_write32(Adapter, REG_RCR, v);
+ //reject all data frame
+ rtw_write16(Adapter, REG_RXFLTMAP2,0x00);
+
+ //disable update TSF
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+ }
+ else//sitesurvey done
+ {
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ if ((is_client_associated_to_ap(Adapter) == _TRUE) ||
+ ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) )
+ {
+ //enable to rx data frame
+ //rtw_write32(Adapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
+ rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF);
+
+ //enable update TSF
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+ }
+ else if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
+ {
+ //rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_ADF);
+ rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF);
+
+ //enable update TSF
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+ }
+
+ if(Adapter->in_cta_test)
+ {
+ if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
+ {
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
+ }
+ else
+ {
+ u32 v = rtw_read32(Adapter, REG_RCR);
+ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
+ rtw_write32(Adapter, REG_RCR, v);
+ }
+ }
+ else
+ {
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
+ }
+ }
+#endif
+ break;
+ case HW_VAR_MLME_JOIN:
+#ifdef CONFIG_CONCURRENT_MODE
+ hw_var_set_mlme_join(Adapter, variable, val);
+#else
+ {
+ u8 RetryLimit = 0x30;
+ u8 type = *((u8 *)val);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+
+ if(type == 0) // prepare to join
+ {
+ //enable to rx data frame.Accept all data frame
+ //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
+ rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF);
+ if(Adapter->in_cta_test)
+ {
+ u32 v = rtw_read32(Adapter, REG_RCR);
+ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
+ rtw_write32(Adapter, REG_RCR, v);
+ }
+ else
+ {
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
+ }
+ if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
+ {
+ RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
+ }
+ else // Ad-hoc Mode
+ {
+ RetryLimit = 0x7;
+ }
+ }
+ else if(type == 1) //joinbss_event call back when join res < 0
+ {
+ rtw_write16(Adapter, REG_RXFLTMAP2,0x00);
+ }
+ else if(type == 2) //sta add event call back
+ {
+ // enable update TSF
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+
+ if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
+ {
+ RetryLimit = 0x7;
+ }
+ }
+
+ rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+ }
+#endif
+ break;
+ case HW_VAR_ON_RCR_AM:
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_AM);
+ DBG_871X("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(Adapter, REG_RCR));
+ break;
+ case HW_VAR_OFF_RCR_AM:
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)& (~RCR_AM));
+ DBG_871X("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(Adapter, REG_RCR));
+ break;
+ case HW_VAR_BEACON_INTERVAL:
+ rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val));
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ {
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ u16 bcn_interval = *((u16 *)val);
+ if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE){
+ DBG_8192C("%s==> bcn_interval:%d, eraly_int:%d \n",__FUNCTION__,bcn_interval,bcn_interval>>1);
+ rtw_write8(Adapter, REG_DRVERLYINT, bcn_interval>>1);// 50ms for sdio
+ }
+ else{
+
+ }
+ }
+#endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+ break;
+ case HW_VAR_SLOT_TIME:
+ {
+ u8 u1bAIFS, aSifsTime;
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ rtw_write8(Adapter, REG_SLOT, val[0]);
+
+ if(pmlmeinfo->WMM_enable == 0)
+ {
+ if( pmlmeext->cur_wireless_mode == WIRELESS_11B)
+ aSifsTime = 10;
+ else
+ aSifsTime = 16;
+
+ u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
+
+ // <Roger_EXP> Temporary removed, 2008.06.20.
+ rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS);
+ rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS);
+ rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS);
+ rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS);
+ }
+ }
+ break;
+ case HW_VAR_RESP_SIFS:
+ {
+#if 0
+ // SIFS for OFDM Data ACK
+ rtw_write8(Adapter, REG_SIFS_CTX+1, val[0]);
+ // SIFS for OFDM consecutive tx like CTS data!
+ rtw_write8(Adapter, REG_SIFS_TRX+1, val[1]);
+
+ rtw_write8(Adapter,REG_SPEC_SIFS+1, val[0]);
+ rtw_write8(Adapter,REG_MAC_SPEC_SIFS+1, val[0]);
+
+ // 20100719 Joseph: Revise SIFS setting due to Hardware register definition change.
+ rtw_write8(Adapter, REG_R2T_SIFS+1, val[0]);
+ rtw_write8(Adapter, REG_T2T_SIFS+1, val[0]);
+#else
+ //SIFS_Timer = 0x0a0a0808;
+ //RESP_SIFS for CCK
+ rtw_write8(Adapter, REG_R2T_SIFS, val[0]); // SIFS_T2T_CCK (0x08)
+ rtw_write8(Adapter, REG_R2T_SIFS+1, val[1]); //SIFS_R2T_CCK(0x08)
+ //RESP_SIFS for OFDM
+ rtw_write8(Adapter, REG_T2T_SIFS, val[2]); //SIFS_T2T_OFDM (0x0a)
+ rtw_write8(Adapter, REG_T2T_SIFS+1, val[3]); //SIFS_R2T_OFDM(0x0a)
+#endif
+ }
+ break;
+ case HW_VAR_ACK_PREAMBLE:
+ {
+ u8 regTmp;
+ u8 bShortPreamble = *( (PBOOLEAN)val );
+ // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
+ regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
+ //regTmp = 0;
+ if(bShortPreamble)
+ regTmp |= 0x80;
+
+ rtw_write8(Adapter, REG_RRSR+2, regTmp);
+ }
+ break;
+ case HW_VAR_SEC_CFG:
+#ifdef CONFIG_CONCURRENT_MODE
+ rtw_write8(Adapter, REG_SECCFG, 0x0c|BIT(5));// enable tx enc and rx dec engine, and no key search for MC/BC
+#else
+ rtw_write8(Adapter, REG_SECCFG, *((u8 *)val));
+#endif
+ break;
+ case HW_VAR_DM_FLAG:
+ podmpriv->SupportAbility = *((u8 *)val);
+ break;
+ case HW_VAR_DM_FUNC_OP:
+ if(val[0])
+ {// save dm flag
+ podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
+ }
+ else
+ {// restore dm flag
+ podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
+ }
+ break;
+ case HW_VAR_DM_FUNC_SET:
+ if(*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE){
+ pdmpriv->DMFlag = pdmpriv->InitDMFlag;
+ podmpriv->SupportAbility = pdmpriv->InitODMFlag;
+ }
+ else{
+ podmpriv->SupportAbility |= *((u32 *)val);
+ }
+ break;
+ case HW_VAR_DM_FUNC_CLR:
+ podmpriv->SupportAbility &= *((u32 *)val);
+ break;
+ case HW_VAR_CAM_EMPTY_ENTRY:
+ {
+ u8 ucIndex = *((u8 *)val);
+ u8 i;
+ u32 ulCommand=0;
+ u32 ulContent=0;
+ u32 ulEncAlgo=CAM_AES;
+
+ for(i=0;i<CAM_CONTENT_COUNT;i++)
+ {
+ // filled id in CAM config 2 byte
+ if( i == 0)
+ {
+ ulContent |=(ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
+ //ulContent |= CAM_VALID;
+ }
+ else
+ {
+ ulContent = 0;
+ }
+ // polling bit, and No Write enable, and address
+ ulCommand= CAM_CONTENT_COUNT*ucIndex+i;
+ ulCommand= ulCommand | CAM_POLLINIG|CAM_WRITE;
+ // write content 0 is equall to mark invalid
+ rtw_write32(Adapter, WCAMI, ulContent); //delay_ms(40);
+ //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx \n",ulContent));
+ rtw_write32(Adapter, RWCAM, ulCommand); //delay_ms(40);
+ //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx \n",ulCommand));
+ }
+ }
+ break;
+ case HW_VAR_CAM_INVALID_ALL:
+ rtw_write32(Adapter, RWCAM, BIT(31)|BIT(30));
+ break;
+ case HW_VAR_CAM_WRITE:
+ {
+ u32 cmd;
+ u32 *cam_val = (u32 *)val;
+ rtw_write32(Adapter, WCAMI, cam_val[0]);
+
+ cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
+ rtw_write32(Adapter, RWCAM, cmd);
+ }
+ break;
+ case HW_VAR_AC_PARAM_VO:
+ rtw_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_AC_PARAM_VI:
+ rtw_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_AC_PARAM_BE:
+ pHalData->AcParam_BE = ((u32 *)(val))[0];
+ rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_AC_PARAM_BK:
+ rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_AMPDU_MIN_SPACE:
+ {
+ u8 MinSpacingToSet;
+ u8 SecMinSpace;
+
+ MinSpacingToSet = *((u8 *)val);
+ if(MinSpacingToSet <= 7)
+ {
+ switch(Adapter->securitypriv.dot11PrivacyAlgrthm)
+ {
+ case _NO_PRIVACY_:
+ case _AES_:
+ SecMinSpace = 0;
+ break;
+
+ case _WEP40_:
+ case _WEP104_:
+ case _TKIP_:
+ case _TKIP_WTMIC_:
+ SecMinSpace = 6;
+ break;
+ default:
+ SecMinSpace = 7;
+ break;
+ }
+
+ if(MinSpacingToSet < SecMinSpace){
+ MinSpacingToSet = SecMinSpace;
+ }
+
+ //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", Adapter->MgntInfo.MinSpaceCfg));
+ rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+ }
+ }
+ break;
+ case HW_VAR_AMPDU_FACTOR:
+ {
+ u8 RegToSet_Normal[4]={0x41,0xa8,0x72, 0xb9};
+ u8 RegToSet_BT[4]={0x31,0x74,0x42, 0x97};
+ u8 FactorToSet;
+ u8 *pRegToSet;
+ u8 index = 0;
+
+#ifdef CONFIG_BT_COEXIST
+ if( (pHalData->bt_coexist.BT_Coexist) &&
+ (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC4) )
+ pRegToSet = RegToSet_BT; // 0x97427431;
+ else
+#endif
+ pRegToSet = RegToSet_Normal; // 0xb972a841;
+
+ FactorToSet = *((u8 *)val);
+ if(FactorToSet <= 3)
+ {
+ FactorToSet = (1<<(FactorToSet + 2));
+ if(FactorToSet>0xf)
+ FactorToSet = 0xf;
+
+ for(index=0; index<4; index++)
+ {
+ if((pRegToSet[index] & 0xf0) > (FactorToSet<<4))
+ pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet<<4);
+
+ if((pRegToSet[index] & 0x0f) > FactorToSet)
+ pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
+
+ rtw_write8(Adapter, (REG_AGGLEN_LMT+index), pRegToSet[index]);
+ }
+
+ //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet));
+ }
+ }
+ break;
+ case HW_VAR_RXDMA_AGG_PG_TH:
+ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, *((u8 *)val));
+ break;
+ case HW_VAR_SET_RPWM:
+#ifdef CONFIG_LPS_LCLK
+ {
+ u8 ps_state = *((u8 *)val);
+ //rpwm value only use BIT0(clock bit) ,BIT6(Ack bit), and BIT7(Toggle bit) for 88e.
+ //BIT0 value - 1: 32k, 0:40MHz.
+ //BIT6 value - 1: report cpwm value after success set, 0:do not report.
+ //BIT7 value - Toggle bit change.
+ //modify by Thomas. 2012/4/2.
+ ps_state = ps_state & 0xC1;
+
+#ifdef CONFIG_EXT_CLK //for sprd
+ if(ps_state&BIT(6)) // want to leave 32k
+ {
+ //enable ext clock req before leave LPS-32K
+ //DBG_871X("enable ext clock req before leaving LPS-32K\n");
+ EnableGpio5ClockReq(Adapter, _FALSE, 1);
+ }
+#endif //CONFIG_EXT_CLK
+
+ //DBG_871X("##### Change RPWM value to = %x for switch clk #####\n",ps_state);
+ rtw_write8(Adapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, ps_state);
+ }
+#endif
+ break;
+ case HW_VAR_H2C_FW_PWRMODE:
+ {
+ u8 psmode = (*(u8 *)val);
+
+ // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
+ // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
+ if( (psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(pHalData->VersionID)))
+ {
+ ODM_RF_Saving(podmpriv, _TRUE);
+ }
+ rtl8188e_set_FwPwrMode_cmd(Adapter, psmode);
+ }
+ break;
+ case HW_VAR_H2C_FW_JOINBSSRPT:
+ {
+ u8 mstatus = (*(u8 *)val);
+ rtl8188e_set_FwJoinBssReport_cmd(Adapter, mstatus);
+ }
+ break;
+#ifdef CONFIG_P2P_PS
+ case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
+ {
+ u8 p2p_ps_state = (*(u8 *)val);
+ rtl8188e_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state);
+ }
+ break;
+#endif // CONFIG_P2P_PS
+ case HW_VAR_INITIAL_GAIN:
+ {
+ DIG_T *pDigTable = &podmpriv->DM_DigTable;
+ u32 rx_gain = ((u32 *)(val))[0];
+
+ if(rx_gain == 0xff){//restore rx gain
+ ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue);
+ }
+ else{
+ pDigTable->BackupIGValue = pDigTable->CurIGValue;
+ ODM_Write_DIG(podmpriv,rx_gain);
+ }
+ }
+ break;
+ case HW_VAR_TRIGGER_GPIO_0:
+// rtl8192cu_trigger_gpio_0(Adapter);
+ break;
+#ifdef CONFIG_BT_COEXIST
+ case HW_VAR_BT_SET_COEXIST:
+ {
+ u8 bStart = (*(u8 *)val);
+ rtl8192c_set_dm_bt_coexist(Adapter, bStart);
+ }
+ break;
+ case HW_VAR_BT_ISSUE_DELBA:
+ {
+ u8 dir = (*(u8 *)val);
+ rtl8192c_issue_delete_ba(Adapter, dir);
+ }
+ break;
+#endif
+#if (RATE_ADAPTIVE_SUPPORT==1)
+ case HW_VAR_RPT_TIMER_SETTING:
+ {
+ u16 min_rpt_time = (*(u16 *)val);
+
+ //DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");
+
+ //PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, Optimum_antenna);
+ ODM_RA_Set_TxRPT_Time(podmpriv,min_rpt_time);
+ }
+ break;
+#endif
+
+#ifdef CONFIG_SW_ANTENNA_DIVERSITY
+ case HW_VAR_ANTENNA_DIVERSITY_LINK:
+ //SwAntDivRestAfterLink8192C(Adapter);
+ ODM_SwAntDivRestAfterLink(podmpriv);
+ break;
+#endif
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ case HW_VAR_ANTENNA_DIVERSITY_SELECT:
+ {
+ u8 Optimum_antenna = (*(u8 *)val);
+ u8 Ant ;
+ //switch antenna to Optimum_antenna
+ //DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");
+ if(pHalData->CurAntenna != Optimum_antenna)
+ {
+ Ant = (Optimum_antenna==2)?MAIN_ANT:AUX_ANT;
+ ODM_UpdateRxIdleAnt_88E(&pHalData->odmpriv, Ant);
+
+ pHalData->CurAntenna = Optimum_antenna ;
+ //DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");
+ }
+ }
+ break;
+#endif
+ case HW_VAR_EFUSE_BYTES: // To set EFUE total used bytes, added by Roger, 2008.12.22.
+ pHalData->EfuseUsedBytes = *((u16 *)val);
+ break;
+ case HW_VAR_FIFO_CLEARN_UP:
+ {
+ struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
+ u8 trycnt = 100;
+
+ //pause tx
+ rtw_write8(Adapter,REG_TXPAUSE,0xff);
+
+ //keep sn
+ Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter,REG_NQOS_SEQ);
+
+ //RX DMA stop
+ rtw_write32(Adapter,REG_RXPKT_NUM,(rtw_read32(Adapter,REG_RXPKT_NUM)|RW_RELEASE_EN));
+ do{
+ if(!(rtw_read32(Adapter,REG_RXPKT_NUM)&RXDMA_IDLE))
+ break;
+ }while(trycnt--);
+ if(trycnt ==0)
+ DBG_8192C("Stop RX DMA failed...... \n");
+
+ //RQPN Load 0
+ rtw_write16(Adapter,REG_RQPN_NPQ,0x0);
+ rtw_write32(Adapter,REG_RQPN,0x80000000);
+ rtw_mdelay_os(10);
+
+ }
+ break;
+ case HW_VAR_CHECK_TXBUF:
+#ifdef CONFIG_CONCURRENT_MODE
+ {
+ int i;
+ u8 RetryLimit = 0x01;
+
+ rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+ for(i=0;i<1000;i++)
+ {
+ if(rtw_read32(Adapter, 0x200) != rtw_read32(Adapter, 0x204))
+ {
+ //DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(Adapter, 0x204), rtw_read32(Adapter, 0x200), i);
+ rtw_msleep_os(10);
+ }
+ else
+ {
+ DBG_871X("no packet in tx packet buffer (%d)\n", i);
+ break;
+ }
+ }
+
+ RetryLimit = 0x30;
+ rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+
+ }
+#endif
+ break;
+#ifdef CONFIG_WOWLAN
+ case HW_VAR_WOWLAN:
+ {
+ struct wowlan_ioctl_param *poidparam;
+ struct recv_buf *precvbuf;
+ int res, i;
+ u32 tmp;
+ u16 len = 0;
+ u8 mstatus = (*(u8 *)val);
+ u8 trycnt = 100;
+ u8 data[4];
+
+ poidparam = (struct wowlan_ioctl_param *)val;
+ switch (poidparam->subcode){
+ case WOWLAN_ENABLE:
+ DBG_871X_LEVEL(_drv_always_, "WOWLAN_ENABLE\n");
+
+ SetFwRelatedForWoWLAN8188ES(Adapter, _TRUE);
+
+ //Set Pattern
+ //if(Adapter->pwrctrlpriv.wowlan_pattern==_TRUE)
+ // rtw_wowlan_reload_pattern(Adapter);
+
+ //RX DMA stop
+ DBG_871X_LEVEL(_drv_always_, "Pause DMA\n");
+ rtw_write32(Adapter,REG_RXPKT_NUM,(rtw_read32(Adapter,REG_RXPKT_NUM)|RW_RELEASE_EN));
+ do{
+ if((rtw_read32(Adapter, REG_RXPKT_NUM)&RXDMA_IDLE)) {
+ DBG_871X_LEVEL(_drv_always_, "RX_DMA_IDLE is true\n");
+ break;
+ } else {
+ // If RX_DMA is not idle, receive one pkt from DMA
+ res = sdio_local_read(Adapter, SDIO_REG_RX0_REQ_LEN, 4, (u8*)&tmp);
+ //len = le16_to_cpu(*(u16*)data);
+ if (tmp == 0){
+ res = sdio_local_read(Adapter, SDIO_REG_HISR, 4, (u8*)&tmp);
+ DBG_871X_LEVEL(_drv_info_, "read SDIO_REG_HISR: 0x%08x\n", tmp);
+ }
+ res = RecvOnePkt(Adapter, tmp);
+ DBG_871X_LEVEL(_drv_always_, "RecvOnePkt Result: %d\n", res);
+ }
+ }while(trycnt--);
+ if(trycnt ==0)
+ DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed...... \n");
+
+ //Enable CPWM2 only.
+ DBG_871X_LEVEL(_drv_always_, "Enable only CPWM2\n");
+ res = sdio_local_read(Adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+ if (!res)
+ DBG_871X_LEVEL(_drv_info_, "read SDIO_REG_HIMR: 0x%08x\n", tmp);
+ else
+ DBG_871X_LEVEL(_drv_info_, "sdio_local_read fail\n");
+
+ tmp = SDIO_HIMR_CPWM2_MSK;
+
+ res = sdio_local_write(Adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+
+ if (!res){
+ res = sdio_local_read(Adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+ DBG_871X_LEVEL(_drv_info_, "read again SDIO_REG_HIMR: 0x%08x\n", tmp);
+ }else
+ DBG_871X_LEVEL(_drv_info_, "sdio_local_write fail\n");
+
+ //Set WOWLAN H2C command.
+ DBG_871X_LEVEL(_drv_always_, "Set WOWLan cmd\n");
+ rtl8188es_set_wowlan_cmd(Adapter, 1);
+
+ mstatus = rtw_read8(Adapter, REG_WOW_CTRL);
+ trycnt = 10;
+
+ while(!(mstatus&BIT1) && trycnt>1) {
+ mstatus = rtw_read8(Adapter, REG_WOW_CTRL);
+ DBG_871X_LEVEL(_drv_always_, "Loop index: %d :0x%02x\n", trycnt, mstatus);
+ trycnt --;
+ rtw_msleep_os(2);
+ }
+
+ Adapter->pwrctrlpriv.wowlan_wake_reason = rtw_read8(Adapter, REG_WOWLAN_WAKE_REASON);
+ DBG_871X_LEVEL(_drv_always_, "wowlan_wake_reason: 0x%02x\n",
+ Adapter->pwrctrlpriv.wowlan_wake_reason);
+
+ //rtw_msleep_os(10);
+ break;
+ case WOWLAN_DISABLE:
+ DBG_871X_LEVEL(_drv_always_, "WOWLAN_DISABLE\n");
+ trycnt = 10;
+ Adapter->pwrctrlpriv.wowlan_wake_reason =
+ rtw_read8(Adapter, REG_WOWLAN_WAKE_REASON);
+ DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n",
+ Adapter->pwrctrlpriv.wowlan_wake_reason);
+ rtl8188es_set_wowlan_cmd(Adapter, 0);
+ mstatus = rtw_read8(Adapter, REG_WOW_CTRL);
+ DBG_871X_LEVEL(_drv_info_, "%s mstatus:0x%02x\n", __func__, mstatus);
+
+ while(mstatus&BIT1 && trycnt>1) {
+ mstatus = rtw_read8(Adapter, REG_WOW_CTRL);
+ DBG_871X_LEVEL(_drv_always_, "Loop index: %d :0x%02x\n", trycnt, mstatus);
+ trycnt --;
+ rtw_msleep_os(2);
+ }
+
+ if (mstatus & BIT1)
+ printk("System did not release RX_DMA\n");
+ else
+ SetFwRelatedForWoWLAN8188ES(Adapter, _FALSE);
+
+ EnableInterrupt8188ESdio(Adapter);
+ rtw_msleep_os(2);
+ if(!(Adapter->pwrctrlpriv.wowlan_wake_reason & FWDecisionDisconnect) ||
+ !(Adapter->pwrctrlpriv.wowlan_wake_reason & Rx_GTK))
+ rtl8188e_set_FwJoinBssReport_cmd(Adapter, 1);
+ //rtw_msleep_os(10);
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+#endif //CONFIG_WOWLAN
+ case HW_VAR_APFM_ON_MAC:
+ pHalData->bMacPwrCtrlOn = *val;
+ DBG_871X("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
+ break;
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ case HW_VAR_TX_RPT_MAX_MACID:
+ {
+ u8 maxMacid = *val;
+ DBG_8192C("### MacID(%d),Set Max Tx RPT MID(%d)\n",maxMacid,maxMacid+1);
+ rtw_write8(Adapter, REG_TX_RPT_CTRL+1, maxMacid+1);
+ }
+ break;
+#endif // (RATE_ADAPTIVE_SUPPORT == 1)
+ case HW_VAR_H2C_MEDIA_STATUS_RPT:
+ {
+ rtl8188e_set_FwMediaStatus_cmd(Adapter , (*(u16 *)val));
+ }
+ break;
+ case HW_VAR_BCN_VALID:
+ //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
+ rtw_write8(Adapter, REG_TDECTRL+2, rtw_read8(Adapter, REG_TDECTRL+2) | BIT0);
+ break;
+ default:
+
+ break;
+ }
+
+_func_exit_;
+}
+
+static void GetHwReg8188ES(PADAPTER padapter, u8 variable, u8 *val)
+{
+ PHAL_DATA_TYPE pHalData= GET_HAL_DATA(padapter);
+ DM_ODM_T *podmpriv = &pHalData->odmpriv;
+_func_enter_;
+
+ switch (variable)
+ {
+ case HW_VAR_BASIC_RATE:
+ *((u16*)val) = pHalData->BasicRateSet;
+ break;
+
+ case HW_VAR_TXPAUSE:
+ val[0] = rtw_read8(padapter, REG_TXPAUSE);
+ break;
+
+ case HW_VAR_BCN_VALID:
+ //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
+ val[0] = (BIT0 & rtw_read8(padapter, REG_TDECTRL+2))?_TRUE:_FALSE;
+ break;
+
+ case HW_VAR_DM_FLAG:
+ val[0] = podmpriv->SupportAbility;
+ break;
+
+ case HW_VAR_RF_TYPE:
+ val[0] = pHalData->rf_type;
+ break;
+
+ case HW_VAR_FWLPS_RF_ON:
+ {
+ //When we halt NIC, we should check if FW LPS is leave.
+ if ((padapter->bSurpriseRemoved == _TRUE) ||
+ (padapter->pwrctrlpriv.rf_pwrstate == rf_off))
+ {
+ // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
+ // because Fw is unload.
+ val[0] = _TRUE;
+ }
+ else
+ {
+ u32 valRCR;
+ valRCR = rtw_read32(padapter, REG_RCR);
+ valRCR &= 0x00070000;
+ if(valRCR)
+ val[0] = _FALSE;
+ else
+ val[0] = _TRUE;
+ }
+ }
+ break;
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ case HW_VAR_CURRENT_ANTENNA:
+ val[0] = pHalData->CurAntenna;
+ break;
+#endif
+ case HW_VAR_EFUSE_BYTES: // To get EFUE total used bytes, added by Roger, 2008.12.22.
+ *((u16*)val) = pHalData->EfuseUsedBytes;
+ break;
+
+ case HW_VAR_APFM_ON_MAC:
+ *val = pHalData->bMacPwrCtrlOn;
+ break;
+ case HW_VAR_CHK_HI_QUEUE_EMPTY:
+ *val = ((rtw_read32(padapter, REG_HGQ_INFORMATION)&0x0000ff00)==0) ? _TRUE:_FALSE;
+ break;
+ default:
+ break;
+ }
+
+_func_exit_;
+}
+
+//
+// Description:
+// Query setting of specified variable.
+//
+u8
+GetHalDefVar8188ESDIO(
+ IN PADAPTER Adapter,
+ IN HAL_DEF_VARIABLE eVariable,
+ IN PVOID pValue
+ )
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 bResult = _SUCCESS;
+
+ switch(eVariable)
+ {
+ case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
+ {
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ struct sta_priv * pstapriv = &Adapter->stapriv;
+ struct sta_info * psta;
+ psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
+ if(psta)
+ {
+ *((int *)pValue) = psta->rssi_stat.UndecoratedSmoothedPWDB;
+ }
+ }
+
+ break;
+ case HAL_DEF_IS_SUPPORT_ANT_DIV:
+ #ifdef CONFIG_ANTENNA_DIVERSITY
+ *((u8 *)pValue) = (pHalData->AntDivCfg==0)?_FALSE:_TRUE;
+ #endif
+ break;
+ case HAL_DEF_CURRENT_ANTENNA:
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ *(( u8*)pValue) = pHalData->CurAntenna;
+#endif
+ break;
+ case HAL_DEF_DBG_DM_FUNC:
+ *(( u32*)pValue) =pHalData->odmpriv.SupportAbility;
+ break;
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ case HAL_DEF_RA_DECISION_RATE:
+ {
+ u8 MacID = *((u8*)pValue);
+ *((u8*)pValue) = ODM_RA_GetDecisionRate_8188E(&(pHalData->odmpriv), MacID);
+ }
+ break;
+
+ case HAL_DEF_RA_SGI:
+ {
+ u8 MacID = *((u8*)pValue);
+ *((u8*)pValue) = ODM_RA_GetShortGI_8188E(&(pHalData->odmpriv), MacID);
+ }
+ break;
+#endif
+
+
+ case HAL_DEF_PT_PWR_STATUS:
+#if(POWER_TRAINING_ACTIVE==1)
+ {
+ u8 MacID = *((u8*)pValue);
+ *((u8*)pValue) = ODM_RA_GetHwPwrStatus_8188E(&(pHalData->odmpriv), MacID);
+ }
+#endif //(POWER_TRAINING_ACTIVE==1)
+ break;
+
+ case HW_VAR_MAX_RX_AMPDU_FACTOR:
+ *(( u32*)pValue) = MAX_AMPDU_FACTOR_16K;
+ break;
+
+ case HW_DEF_RA_INFO_DUMP:
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ {
+ u8 entry_id = *((u8*)pValue);
+ if(check_fwstate(&Adapter->mlmepriv, _FW_LINKED)== _TRUE)
+ {
+ DBG_871X("============ RA status check ===================\n");
+ DBG_8192C("Mac_id:%d ,RateID = %d,RAUseRate = 0x%08x,RateSGI = %d, DecisionRate = 0x%02x ,PTStage = %d\n",
+ entry_id,
+ pHalData->odmpriv.RAInfo[entry_id].RateID,
+ pHalData->odmpriv.RAInfo[entry_id].RAUseRate,
+ pHalData->odmpriv.RAInfo[entry_id].RateSGI,
+ pHalData->odmpriv.RAInfo[entry_id].DecisionRate,
+ pHalData->odmpriv.RAInfo[entry_id].PTStage);
+ }
+ }
+#endif // (RATE_ADAPTIVE_SUPPORT == 1)
+ break;
+
+ case HAL_DEF_DBG_DUMP_RXPKT:
+ *(( u8*)pValue) = pHalData->bDumpRxPkt;
+ break;
+ case HAL_DEF_DBG_DUMP_TXPKT:
+ *(( u8*)pValue) = pHalData->bDumpTxPkt;
+ break;
+ case HW_DEF_ODM_DBG_FLAG:
+ {
+ u8Byte DebugComponents = *((u32*)pValue);
+ PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
+ printk("pDM_Odm->DebugComponents = 0x%llx \n",pDM_Odm->DebugComponents );
+ }
+ break;
+ default:
+ //RT_TRACE(COMP_INIT, DBG_WARNING, ("GetHalDefVar8188ESDIO(): Unkown variable: %d!\n", eVariable));
+ bResult = _FAIL;
+ break;
+ }
+
+ return bResult;
+}
+
+
+
+
+//
+// Description:
+// Change default setting of specified variable.
+//
+u8
+SetHalDefVar8188ESDIO(
+ IN PADAPTER Adapter,
+ IN HAL_DEF_VARIABLE eVariable,
+ IN PVOID pValue
+ )
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 bResult = _TRUE;
+
+ switch(eVariable)
+ {
+ case HAL_DEF_DBG_DM_FUNC:
+ {
+ u8 dm_func = *(( u8*)pValue);
+ struct dm_priv *pdmpriv = &pHalData->dmpriv;
+ DM_ODM_T *podmpriv = &pHalData->odmpriv;
+
+ if(dm_func == 0){ //disable all dynamic func
+ podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE;
+ DBG_8192C("==> Disable all dynamic function...\n");
+ }
+ else if(dm_func == 1){//disable DIG
+ podmpriv->SupportAbility &= (~DYNAMIC_BB_DIG);
+ DBG_8192C("==> Disable DIG...\n");
+ }
+ else if(dm_func == 2){//disable High power
+ podmpriv->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR);
+ }
+ else if(dm_func == 3){//disable tx power tracking
+ podmpriv->SupportAbility &= (~DYNAMIC_RF_CALIBRATION);
+ DBG_8192C("==> Disable tx power tracking...\n");
+ }
+ //else if(dm_func == 4){//disable BT coexistence
+ // pdmpriv->DMFlag &= (~DYNAMIC_FUNC_BT);
+ //}
+ else if(dm_func == 5){//disable antenna diversity
+ podmpriv->SupportAbility &= (~DYNAMIC_BB_ANT_DIV);
+ }
+ else if(dm_func == 6){//turn on all dynamic func
+ if(!(podmpriv->SupportAbility & DYNAMIC_BB_DIG))
+ {
+ DIG_T *pDigTable = &podmpriv->DM_DigTable;
+ pDigTable->CurIGValue= rtw_read8(Adapter,0xc50);
+ }
+ //pdmpriv->DMFlag |= DYNAMIC_FUNC_BT;
+ podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
+ DBG_8192C("==> Turn on all dynamic function...\n");
+ }
+ }
+ break;
+ case HAL_DEF_DBG_DUMP_RXPKT:
+ pHalData->bDumpRxPkt = *(( u8*)pValue);
+ break;
+ case HAL_DEF_DBG_DUMP_TXPKT:
+ pHalData->bDumpTxPkt = *(( u8*)pValue);
+ break;
+ case HW_DEF_FA_CNT_DUMP:
+ {
+ u8 bRSSIDump = *((u8*)pValue);
+ PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
+ if(bRSSIDump)
+ pDM_Odm->DebugComponents = ODM_COMP_DIG|ODM_COMP_FA_CNT ;
+ else
+ pDM_Odm->DebugComponents = 0;
+
+ }
+ break;
+ case HW_DEF_ODM_DBG_FLAG:
+ {
+ u8Byte DebugComponents = *((u8Byte*)pValue);
+ PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
+ pDM_Odm->DebugComponents = DebugComponents;
+ }
+ break;
+ default:
+ //RT_TRACE(COMP_INIT, DBG_TRACE, ("SetHalDefVar819xUsb(): Unkown variable: %d!\n", eVariable));
+ bResult = _FALSE;
+ break;
+ }
+
+ return bResult;
+}
+
+void UpdateHalRAMask8188ESdio(PADAPTER padapter, u32 mac_id, u8 rssi_level)
+{
+ //volatile unsigned int result;
+ u8 init_rate=0;
+ u8 networkType, raid;
+ u32 mask,rate_bitmap;
+ u8 shortGIrate = _FALSE;
+ int supportRateNum = 0;
+ struct sta_info *psta;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ //struct dm_priv *pdmpriv = &pHalData->dmpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
+#ifdef CONFIG_CONCURRENT_MODE
+ if(rtw_buddy_adapter_up(padapter) && padapter->adapter_type > PRIMARY_ADAPTER)
+ pHalData = GET_HAL_DATA(padapter->pbuddy_adapter);
+#endif //CONFIG_CONCURRENT_MODE
+
+ if (mac_id >= NUM_STA) //CAM_SIZE
+ {
+ return;
+ }
+
+ psta = pmlmeinfo->FW_sta_info[mac_id].psta;
+ if(psta == NULL)
+ {
+ return;
+ }
+
+ switch (mac_id)
+ {
+ case 0:// for infra mode
+#ifdef CONFIG_CONCURRENT_MODE
+ case 2:// first station uses macid=0, second station uses macid=2
+#endif
+ supportRateNum = rtw_get_rateset_len(cur_network->SupportedRates);
+ networkType = judge_network_type(padapter, cur_network->SupportedRates, supportRateNum) & 0xf;
+ //pmlmeext->cur_wireless_mode = networkType;
+ raid = networktype_to_raid(networkType);
+
+ mask = update_supported_rate(cur_network->SupportedRates, supportRateNum);
+ mask |= (pmlmeinfo->HT_enable)? update_MSC_rate(&(pmlmeinfo->HT_caps)): 0;
+
+
+ if (support_short_GI(padapter, &(pmlmeinfo->HT_caps)))
+ {
+ shortGIrate = _TRUE;
+ }
+
+ break;
+
+ case 1://for broadcast/multicast
+ supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
+ if(pmlmeext->cur_wireless_mode & WIRELESS_11B)
+ networkType = WIRELESS_11B;
+ else
+ networkType = WIRELESS_11G;
+ raid = networktype_to_raid(networkType);
+ mask = update_basic_rate(cur_network->SupportedRates, supportRateNum);
+
+
+ break;
+
+ default: //for each sta in IBSS
+ supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
+ networkType = judge_network_type(padapter, pmlmeinfo->FW_sta_info[mac_id].SupportedRates, supportRateNum) & 0xf;
+ //pmlmeext->cur_wireless_mode = networkType;
+ raid = networktype_to_raid(networkType);
+ mask = update_supported_rate(cur_network->SupportedRates, supportRateNum);
+
+ //todo: support HT in IBSS
+
+ break;
+ }
+
+ //mask &=0xffffffff;
+ rate_bitmap = 0x0fffffff;
+#ifdef CONFIG_ODM_REFRESH_RAMASK
+ {
+ rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv,mac_id,mask,rssi_level);
+ DBG_8192C("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
+ __FUNCTION__,mac_id,networkType,mask,rssi_level,rate_bitmap);
+ }
+#endif
+ mask &= rate_bitmap;
+
+
+ init_rate = get_highest_rate_idx(mask)&0x3f;
+
+ if(pHalData->fw_ractrl == _TRUE)
+ {
+ u8 arg = 0;
+
+ //arg = (cam_idx-4)&0x1f;//MACID
+ arg = mac_id&0x1f;//MACID
+
+ arg |= BIT(7);
+
+ if (shortGIrate==_TRUE)
+ arg |= BIT(5);
+ mask |= ((raid<<28)&0xf0000000);
+
+ DBG_871X("update raid entry, mask=0x%x, arg=0x%x\n", mask, arg);
+ psta->ra_mask=mask;
+#ifdef CONFIG_INTEL_PROXIM
+ if(padapter->proximity.proxim_on ==_TRUE){
+ arg &= ~BIT(6);
+ }
+ else {
+ arg |= BIT(6);
+ }
+#endif //CONFIG_INTEL_PROXIM
+ rtl8188e_set_raid_cmd(padapter, mask);
+
+ }
+ else
+ {
+
+#if(RATE_ADAPTIVE_SUPPORT == 1)
+
+ ODM_RA_UpdateRateInfo_8188E(
+ &(pHalData->odmpriv),
+ mac_id,
+ raid,
+ mask,
+ shortGIrate
+ );
+
+#endif
+ }
+
+
+ //set ra_id
+ psta->raid = raid;
+ psta->init_rate = init_rate;
+
+
+}
+
+
+static VOID
+_BeaconFunctionEnable(
+ IN PADAPTER padapter,
+ IN BOOLEAN Enable,
+ IN BOOLEAN Linked
+ )
+{
+ rtw_write8(padapter, REG_BCN_CTRL, (BIT4 | BIT3 | BIT1));
+// RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("_BeaconFunctionEnable 0x550 0x%x\n", rtw_read8(padapter, 0x550)));
+
+ rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
+}
+
+void SetBeaconRelatedRegisters8188ESdio(PADAPTER padapter)
+{
+ u32 value32;
+ //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ u32 bcn_ctrl_reg = REG_BCN_CTRL;
+ //reset TSF, enable update TSF, correcting TSF On Beacon
+
+ //REG_BCN_INTERVAL
+ //REG_BCNDMATIM
+ //REG_ATIMWND
+ //REG_TBTT_PROHIBIT
+ //REG_DRVERLYINT
+ //REG_BCN_MAX_ERR
+ //REG_BCNTCFG //(0x510)
+ //REG_DUAL_TSF_RST
+ //REG_BCN_CTRL //(0x550)
+
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (padapter->iface_type == IFACE_PORT1){
+ bcn_ctrl_reg = REG_BCN_CTRL_1;
+ }
+#endif
+ //
+ // ATIM window
+ //
+ rtw_write16(padapter, REG_ATIMWND, 2);
+
+ //
+ // Beacon interval (in unit of TU).
+ //
+ rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
+
+ _InitBeaconParameters(padapter);
+
+ rtw_write8(padapter, REG_SLOT, 0x09);
+
+ //
+ // Force beacon frame transmission even after receiving beacon frame from other ad hoc STA
+ //
+ //PlatformEFIOWrite1Byte(Adapter, BCN_ERR_THRESH, 0x0a); // We force beacon sent to prevent unexpect disconnect status in Ad hoc mode
+
+ //
+ // Reset TSF Timer to zero, added by Roger. 2008.06.24
+ //
+ value32 = rtw_read32(padapter, REG_TCR);
+ value32 &= ~TSFRST;
+ rtw_write32(padapter, REG_TCR, value32);
+
+ value32 |= TSFRST;
+ rtw_write32(padapter, REG_TCR, value32);
+
+ // TODO: Modify later (Find the right parameters)
+ // NOTE: Fix test chip's bug (about contention windows's randomness)
+// if (OpMode == RT_OP_MODE_IBSS || OpMode == RT_OP_MODE_AP)
+ if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_AP_STATE) == _TRUE)
+ {
+ rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
+ rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
+ }
+
+ _BeaconFunctionEnable(padapter, _TRUE, _TRUE);
+
+ ResumeTxBeacon(padapter);
+ rtw_write8(padapter, bcn_ctrl_reg, rtw_read8(padapter, bcn_ctrl_reg)|BIT(1));
+}
+
+void rtl8188es_set_hal_ops(PADAPTER padapter)
+{
+ struct hal_ops *pHalFunc = &padapter->HalFunc;
+
+_func_enter_;
+
+
+ //set hardware operation functions
+ padapter->HalData = rtw_zmalloc(sizeof(HAL_DATA_TYPE));
+
+ if (padapter->HalData == NULL) {
+ RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
+ ("can't alloc memory for HAL DATA\n"));
+ }
+
+
+ padapter->hal_data_sz = sizeof(HAL_DATA_TYPE);
+
+ pHalFunc->hal_power_on = rtl8188es_InitPowerOn;
+ pHalFunc->hal_init = &rtl8188es_hal_init;
+ pHalFunc->hal_deinit = &rtl8188es_hal_deinit;
+
+ pHalFunc->inirp_init = &rtl8188es_inirp_init;
+ pHalFunc->inirp_deinit = &rtl8188es_inirp_deinit;
+
+ pHalFunc->init_xmit_priv = &rtl8188es_init_xmit_priv;
+ pHalFunc->free_xmit_priv = &rtl8188es_free_xmit_priv;
+
+ pHalFunc->init_recv_priv = &rtl8188es_init_recv_priv;
+ pHalFunc->free_recv_priv = &rtl8188es_free_recv_priv;
+
+ pHalFunc->InitSwLeds = &rtl8188es_InitSwLeds;
+ pHalFunc->DeInitSwLeds = &rtl8188es_DeInitSwLeds;
+
+ pHalFunc->init_default_value = &rtl8188es_init_default_value;
+ pHalFunc->intf_chip_configure = &rtl8188es_interface_configure;
+ pHalFunc->read_adapter_info = &ReadAdapterInfo8188ES;
+
+ pHalFunc->enable_interrupt = &EnableInterrupt8188ESdio;
+ pHalFunc->disable_interrupt = &DisableInterrupt8188ESdio;
+
+#ifdef COWFIG_WOWLAN
+ pHalFunc->disable_interrupt = &ClearInterrupt8189ESdio;
+#endif
+
+ pHalFunc->SetHwRegHandler = &SetHwReg8188ES;
+ pHalFunc->GetHwRegHandler = &GetHwReg8188ES;
+
+ pHalFunc->GetHalDefVarHandler = &GetHalDefVar8188ESDIO;
+ pHalFunc->SetHalDefVarHandler = &SetHalDefVar8188ESDIO;
+
+ pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8188ESdio;
+ pHalFunc->SetBeaconRelatedRegistersHandler = &SetBeaconRelatedRegisters8188ESdio;
+
+ pHalFunc->hal_xmit = &rtl8188es_hal_xmit;
+ pHalFunc->mgnt_xmit = &rtl8188es_mgnt_xmit;
+ pHalFunc->hal_xmitframe_enqueue = &rtl8188es_hal_xmitframe_enqueue;
+
+#ifdef CONFIG_HOSTAPD_MLME
+ pHalFunc->hostap_mgnt_xmit_entry = NULL;
+// pHalFunc->hostap_mgnt_xmit_entry = &rtl8192cu_hostap_mgnt_xmit_entry;
+#endif
+ rtl8188e_set_hal_ops(pHalFunc);
+_func_exit_;
+
+}
+
diff --git a/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_ops.c b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_ops.c
new file mode 100755
index 00000000..35c94a00
--- /dev/null
+++ b/drivers/net/wireless/rtl8188E_8192E/hal/rtl8188e/sdio/sdio_ops.c
@@ -0,0 +1,1940 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *******************************************************************************/
+#define _SDIO_OPS_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+#include <rtl8188e_spec.h>
+
+//#define SDIO_DEBUG_IO 1
+
+#define SDIO_ERR_VAL8 0xEA
+#define SDIO_ERR_VAL16 0xEAEA
+#define SDIO_ERR_VAL32 0xEAEAEAEA
+
+extern u8 sd_f0_read8(PSDIO_DATA psdio, u32 addr, s32 *err);
+extern void sd_f0_write8(PSDIO_DATA psdio, u32 addr, s32 *err);
+
+extern s32 _sd_cmd52_read(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+extern s32 _sd_cmd52_write(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+extern s32 sd_cmd52_read(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+extern s32 sd_cmd52_write(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+
+extern u8 _sd_read8(PSDIO_DATA psdio, u32 addr, s32 *err);
+extern u8 sd_read8(PSDIO_DATA psdio, u32 addr, s32 *err);
+extern u16 sd_read16(PSDIO_DATA psdio, u32 addr, s32 *err);
+extern u32 _sd_read32(PSDIO_DATA psdio, u32 addr, s32 *err);
+extern u32 sd_read32(PSDIO_DATA psdio, u32 addr, s32 *err);
+extern s32 _sd_read(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+extern s32 sd_read(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+extern void sd_write8(PSDIO_DATA psdio, u32 addr, u8 v, s32 *err);
+extern void sd_write16(PSDIO_DATA psdio, u32 addr, u16 v, s32 *err);
+extern void _sd_write32(PSDIO_DATA psdio, u32 addr, u32 v, s32 *err);
+extern void sd_write32(PSDIO_DATA psdio, u32 addr, u32 v, s32 *err);
+extern s32 _sd_write(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+extern s32 sd_write(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata);
+
+#ifdef CONFIG_EXT_CLK
+void EnableGpio5ClockReq(PADAPTER Adapter, u8 in_interrupt, u32 Enable);
+#endif //CONFIG_EXT_CLK
+
+//
+// Description:
+// The following mapping is for SDIO host local register space.
+//
+// Creadted by Roger, 2011.01.31.
+//
+static void HalSdioGetCmdAddr8723ASdio(
+ IN PADAPTER padapter,
+ IN u8 DeviceID,
+ IN u32 Addr,
+ OUT u32* pCmdAddr
+ )
+{
+ switch (DeviceID)
+ {
+ case SDIO_LOCAL_DEVICE_ID:
+ *pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK));
+ break;
+
+ case WLAN_IOREG_DEVICE_ID:
+ *pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK));
+ break;
+
+ case WLAN_TX_HIQ_DEVICE_ID:
+ *pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
+ break;
+
+ case WLAN_TX_MIQ_DEVICE_ID:
+ *pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
+ break;
+
+ case WLAN_TX_LOQ_DEVICE_ID:
+ *pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
+ break;
+
+ case WLAN_RX0FF_DEVICE_ID:
+ *pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK));
+ break;
+
+ default:
+ break;
+ }
+}
+
+static u8 get_deviceid(u32 addr)
+{
+ u8 devideId;
+ u16 pseudoId;
+
+
+ pseudoId = (u16)(addr >> 16);
+ switch (pseudoId)
+ {
+ case 0x1025:
+ devideId = SDIO_LOCAL_DEVICE_ID;
+ break;
+
+ case 0x1026:
+ devideId = WLAN_IOREG_DEVICE_ID;
+ break;
+
+// case 0x1027:
+// devideId = SDIO_FIRMWARE_FIFO;
+// break;
+
+ case 0x1031:
+ devideId = WLAN_TX_HIQ_DEVICE_ID;
+ break;
+
+ case 0x1032:
+ devideId = WLAN_TX_MIQ_DEVICE_ID;
+ break;
+
+ case 0x1033:
+ devideId = WLAN_TX_LOQ_DEVICE_ID;
+ break;
+
+ case 0x1034:
+ devideId = WLAN_RX0FF_DEVICE_ID;
+ break;
+
+ default:
+// devideId = (u8)((addr >> 13) & 0xF);
+ devideId = WLAN_IOREG_DEVICE_ID;
+ break;
+ }
+
+ return devideId;
+}
+
+/*
+ * Ref:
+ * HalSdioGetCmdAddr8723ASdio()
+ */
+static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset)
+{
+ u8 deviceId;
+ u16 offset;
+ u32 ftaddr;
+
+
+ deviceId = get_deviceid(addr);
+ offset = 0;
+
+ switch (deviceId)
+ {
+ case SDIO_LOCAL_DEVICE_ID:
+ offset = addr & SDIO_LOCAL_MSK;
+ break;
+
+ case WLAN_TX_HIQ_DEVICE_ID:
+ case WLAN_TX_MIQ_DEVICE_ID:
+ case WLAN_TX_LOQ_DEVICE_ID:
+ offset = addr & WLAN_FIFO_MSK;
+ break;
+
+ case WLAN_RX0FF_DEVICE_ID:
+ offset = addr & WLAN_RX0FF_MSK;
+ break;
+
+ case WLAN_IOREG_DEVICE_ID:
+ default:
+ deviceId = WLAN_IOREG_DEVICE_ID;
+ offset = addr & WLAN_IOREG_MSK;
+ break;
+ }
+ ftaddr = (deviceId << 13) | offset;
+
+ if (pdeviceId) *pdeviceId = deviceId;
+ if (poffset) *poffset = offset;
+
+ return ftaddr;
+}
+
+u8 _sdio_read8(PADAPTER padapter, u32 addr)
+{
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u32 ftaddr;
+ u8 val;
+
+_func_enter_;
+
+ //psdiodev = pintfhdl->pintf_dev;
+ //psdio = &psdiodev->intf_data;
+ psdiodev = adapter_to_dvobj(padapter);
+ psdio = &psdiodev->intf_data;
+
+ ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+ val = _sd_read8(psdio, ftaddr, NULL);
+
+_func_exit_;
+
+ return val;
+}
+
+u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr)
+{
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u32 ftaddr;
+ u8 val;
+
+_func_enter_;
+
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+
+ ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+ val = sd_read8(psdio, ftaddr, NULL);
+
+_func_exit_;
+
+ return val;
+}
+
+u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr)
+{
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u32 ftaddr;
+ u16 val;
+
+_func_enter_;
+
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+
+ ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+ sd_cmd52_read(psdio, ftaddr, 2, (u8*)&val);
+ val = le16_to_cpu(val);
+
+_func_exit_;
+
+ return val;
+}
+
+u32 _sdio_read32(PADAPTER padapter, u32 addr)
+{
+ //PADAPTER padapter;
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ u8 deviceId;
+ u16 offset;
+ u32 ftaddr;
+ u8 shift;
+ u32 val;
+ s32 err;
+
+_func_enter_;
+
+ //padapter = pintfhdl->padapter;
+ //psdiodev = pintfhdl->pintf_dev;
+ psdiodev = adapter_to_dvobj(padapter);
+ psdio = &psdiodev->intf_data;
+
+ ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+ || (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = _sd_cmd52_read(psdio, ftaddr, 4, (u8*)&val);
+#ifdef SDIO_DEBUG_IO
+ if (!err) {
+#endif
+ val = le32_to_cpu(val);
+ return val;
+#ifdef SDIO_DEBUG_IO
+ }
+
+ DBG_871X(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr);
+ return SDIO_ERR_VAL32;
+#endif
+ }
+
+ // 4 bytes alignment
+ shift = ftaddr & 0x3;
+ if (shift == 0) {
+ val = _sd_read32(psdio, ftaddr, NULL);
+ } else {
+ u8 *ptmpbuf;
+
+ ptmpbuf = (u8*)rtw_malloc(8);
+ if (NULL == ptmpbuf) {
+ DBG_871X(KERN_ERR "%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr);
+ return SDIO_ERR_VAL32;
+ }
+
+ ftaddr &= ~(u16)0x3;
+ _sd_read(psdio, ftaddr, 8, ptmpbuf);
+ _rtw_memcpy(&val, ptmpbuf+shift, 4);
+ val = le32_to_cpu(val);
+
+ rtw_mfree(ptmpbuf, 8);
+ }
+
+_func_exit_;
+
+ return val;
+}
+
+u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr)
+{
+ PADAPTER padapter;
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ u8 deviceId;
+ u16 offset;
+ u32 ftaddr;
+ u8 shift;
+ u32 val;
+ s32 err;
+
+_func_enter_;
+
+ padapter = pintfhdl->padapter;
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+
+ ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+ || (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = sd_cmd52_read(psdio, ftaddr, 4, (u8*)&val);
+#ifdef SDIO_DEBUG_IO
+ if (!err) {
+#endif
+ val = le32_to_cpu(val);
+ return val;
+#ifdef SDIO_DEBUG_IO
+ }
+
+ DBG_871X(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr);
+ return SDIO_ERR_VAL32;
+#endif
+ }
+
+ // 4 bytes alignment
+ shift = ftaddr & 0x3;
+ if (shift == 0) {
+ val = sd_read32(psdio, ftaddr, NULL);
+ } else {
+ u8 *ptmpbuf;
+
+ ptmpbuf = (u8*)rtw_malloc(8);
+ if (NULL == ptmpbuf) {
+ DBG_871X(KERN_ERR "%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr);
+ return SDIO_ERR_VAL32;
+ }
+
+ ftaddr &= ~(u16)0x3;
+ sd_read(psdio, ftaddr, 8, ptmpbuf);
+ _rtw_memcpy(&val, ptmpbuf+shift, 4);
+ val = le32_to_cpu(val);
+
+ rtw_mfree(ptmpbuf, 8);
+ }
+
+_func_exit_;
+
+ return val;
+}
+
+s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8* pbuf)
+{
+ PADAPTER padapter;
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ u8 deviceId;
+ u16 offset;
+ u32 ftaddr;
+ u8 shift;
+ s32 err;
+
+_func_enter_;
+
+ padapter = pintfhdl->padapter;
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+ err = 0;
+
+ ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+ || (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = sd_cmd52_read(psdio, ftaddr, cnt, pbuf);
+ return err;
+ }
+
+ // 4 bytes alignment
+ shift = ftaddr & 0x3;
+ if (shift == 0) {
+ err = sd_read(psdio, ftaddr, cnt, pbuf);
+ } else {
+ u8 *ptmpbuf;
+ u32 n;
+
+ ftaddr &= ~(u16)0x3;
+ n = cnt + shift;
+ ptmpbuf = rtw_malloc(n);
+ if (NULL == ptmpbuf) return -1;
+ err = sd_read(psdio, ftaddr, n, ptmpbuf);
+ if (!err)
+ _rtw_memcpy(pbuf, ptmpbuf+shift, cnt);
+ rtw_mfree(ptmpbuf, n);
+ }
+
+_func_exit_;
+
+ return err;
+}
+
+s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
+{
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u32 ftaddr;
+ s32 err;
+
+_func_enter_;
+
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+
+ ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+ sd_write8(psdio, ftaddr, val, &err);
+
+_func_exit_;
+
+ return err;
+}
+
+s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
+{
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u32 ftaddr;
+ u8 shift;
+ s32 err;
+
+_func_enter_;
+
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+
+ ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+ val = cpu_to_le16(val);
+ err = sd_cmd52_write(psdio, ftaddr, 2, (u8*)&val);
+
+_func_exit_;
+
+ return err;
+}
+
+s32 _sdio_write32(PADAPTER padapter, u32 addr, u32 val)
+{
+ //PADAPTER padapter;
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ u8 deviceId;
+ u16 offset;
+ u32 ftaddr;
+ u8 shift;
+ s32 err;
+
+_func_enter_;
+
+ //padapter = pintfhdl->padapter;
+ //psdiodev = pintfhdl->pintf_dev;
+ psdiodev = adapter_to_dvobj(padapter);
+ psdio = &psdiodev->intf_data;
+ err = 0;
+
+ ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+ || (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ val = cpu_to_le32(val);
+ err = _sd_cmd52_write(psdio, ftaddr, 4, (u8*)&val);
+ return err;
+ }
+
+ // 4 bytes alignment
+ shift = ftaddr & 0x3;
+#if 1
+ if (shift == 0)
+ {
+ _sd_write32(psdio, ftaddr, val, &err);
+ }
+ else
+ {
+ val = cpu_to_le32(val);
+ err = _sd_cmd52_write(psdio, ftaddr, 4, (u8*)&val);
+ }
+#else
+ if (shift == 0) {
+ sd_write32(psdio, ftaddr, val, &err);
+ } else {
+ u8 *ptmpbuf;
+
+ ptmpbuf = (u8*)rtw_malloc(8);
+ if (NULL == ptmpbuf) return (-1);
+
+ ftaddr &= ~(u16)0x3;
+ err = sd_read(psdio, ftaddr, 8, ptmpbuf);
+ if (err) {
+ _rtw_mfree(ptmpbuf, 8);
+ return err;
+ }
+ val = cpu_to_le32(val);
+ _rtw_memcpy(ptmpbuf+shift, &val, 4);
+ err = sd_write(psdio, ftaddr, 8, ptmpbuf);
+
+ rtw_mfree(ptmpbuf, 8);
+ }
+#endif
+
+_func_exit_;
+
+ return err;
+}
+
+
+s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
+{
+ PADAPTER padapter;
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ u8 deviceId;
+ u16 offset;
+ u32 ftaddr;
+ u8 shift;
+ s32 err;
+
+_func_enter_;
+
+ padapter = pintfhdl->padapter;
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+ err = 0;
+
+ ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+ || (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ val = cpu_to_le32(val);
+ err = sd_cmd52_write(psdio, ftaddr, 4, (u8*)&val);
+ return err;
+ }
+
+ // 4 bytes alignment
+ shift = ftaddr & 0x3;
+#if 1
+ if (shift == 0)
+ {
+ sd_write32(psdio, ftaddr, val, &err);
+ }
+ else
+ {
+ val = cpu_to_le32(val);
+ err = sd_cmd52_write(psdio, ftaddr, 4, (u8*)&val);
+ }
+#else
+ if (shift == 0) {
+ sd_write32(psdio, ftaddr, val, &err);
+ } else {
+ u8 *ptmpbuf;
+
+ ptmpbuf = (u8*)rtw_malloc(8);
+ if (NULL == ptmpbuf) return (-1);
+
+ ftaddr &= ~(u16)0x3;
+ err = sd_read(psdio, ftaddr, 8, ptmpbuf);
+ if (err) {
+ _rtw_mfree(ptmpbuf, 8);
+ return err;
+ }
+ val = cpu_to_le32(val);
+ _rtw_memcpy(ptmpbuf+shift, &val, 4);
+ err = sd_write(psdio, ftaddr, 8, ptmpbuf);
+
+ rtw_mfree(ptmpbuf, 8);
+ }
+#endif
+
+_func_exit_;
+
+ return err;
+}
+
+s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8* pbuf)
+{
+ PADAPTER padapter;
+ struct dvobj_priv *psdiodev;
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ u8 deviceId;
+ u16 offset;
+ u32 ftaddr;
+ u8 shift;
+ s32 err;
+
+_func_enter_;
+
+ padapter = pintfhdl->padapter;
+ psdiodev = pintfhdl->pintf_dev;
+ psdio = &psdiodev->intf_data;
+ err = 0;
+
+ ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+ || (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = sd_cmd52_write(psdio, ftaddr, cnt, pbuf);
+ return err;
+ }
+
+ shift = ftaddr & 0x3;
+ if (shift == 0) {
+ err = sd_write(psdio, ftaddr, cnt, pbuf);
+ } else {
+ u8 *ptmpbuf;
+ u32 n;
+
+ ftaddr &= ~(u16)0x3;
+ n = cnt + shift;
+ ptmpbuf = rtw_malloc(n);
+ if (NULL == ptmpbuf) return -1;
+ err = sd_read(psdio, ftaddr, 4, ptmpbuf);
+ if (err) {
+ rtw_mfree(ptmpbuf, n);
+ return err;
+ }
+ _rtw_memcpy(ptmpbuf+shift, pbuf, cnt);
+ err = sd_write(psdio, ftaddr, n, ptmpbuf);
+ rtw_mfree(ptmpbuf, n);
+ }
+
+_func_exit_;
+
+ return err;
+}
+
+void sdio_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
+{
+ s32 err;
+
+_func_enter_;
+
+ err = sdio_readN(pintfhdl, addr, cnt, rmem);
+
+_func_exit_;
+}
+
+void sdio_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
+{
+_func_enter_;
+
+ sdio_writeN(pintfhdl, addr, cnt, wmem);
+
+_func_exit_;
+}
+
+/*
+ * Description:
+ * Read from RX FIFO
+ * Round read size to block size,
+ * and make sure data transfer will be done in one command.
+ *
+ * Parameters:
+ * pintfhdl a pointer of intf_hdl
+ * addr port ID
+ * cnt size to read
+ * rmem address to put data
+ *
+ * Return:
+ * _SUCCESS(1) Success
+ * _FAIL(0) Fail
+ */
+static u32 sdio_read_port(
+ struct intf_hdl *pintfhdl,
+ u32 addr,
+ u32 cnt,
+ u8 *mem)
+{
+ PADAPTER padapter = pintfhdl->padapter;
+ PSDIO_DATA psdio= &adapter_to_dvobj(padapter)->intf_data;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ s32 err;
+
+ HalSdioGetCmdAddr8723ASdio(padapter, addr, pHalData->SdioRxFIFOCnt++, &addr);
+
+
+ cnt = _RND4(cnt);
+ if (cnt > psdio->block_transfer_len)
+ cnt = _RND(cnt, psdio->block_transfer_len);
+
+// cnt = sdio_align_size(cnt);
+
+ err = _sd_read(psdio, addr, cnt, mem);
+ //err = sd_read(psdio, addr, cnt, mem);
+
+
+
+ if (err) return _FAIL;
+ return _SUCCESS;
+}
+
+/*
+ * Description:
+ * Write to TX FIFO
+ * Align write size block size,
+ * and make sure data could be written in one command.
+ *
+ * Parameters:
+ * pintfhdl a pointer of intf_hdl
+ * addr port ID
+ * cnt size to write
+ * wmem data pointer to write
+ *
+ * Return:
+ * _SUCCESS(1) Success
+ * _FAIL(0) Fail
+ */
+static u32 sdio_write_port(
+ struct intf_hdl *pintfhdl,
+ u32 addr,
+ u32 cnt,
+ u8 *mem)
+{
+ PADAPTER padapter;
+ PSDIO_DATA psdio;
+ s32 err;
+ struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
+
+ padapter = pintfhdl->padapter;
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+
+ cnt = _RND4(cnt);
+ HalSdioGetCmdAddr8723ASdio(padapter, addr, cnt >> 2, &addr);
+
+ if (cnt > psdio->block_transfer_len)
+ cnt = _RND(cnt, psdio->block_transfer_len);
+// cnt = sdio_align_size(cnt);
+
+ err = sd_write(psdio, addr, cnt, xmitbuf->pdata);
+
+ rtw_sctx_done_err(&xmitbuf->sctx,
+ err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
+
+ if (err)
+ {
+ DBG_871X("%s, error=%d\n", __func__, err);
+
+ return _FAIL;
+ }
+ return _SUCCESS;
+}
+
+void sdio_set_intf_ops(struct _io_ops *pops)
+{
+_func_enter_;
+
+ pops->_read8 = &sdio_read8;
+ pops->_read16 = &sdio_read16;
+ pops->_read32 = &sdio_read32;
+ pops->_read_mem = &sdio_read_mem;
+ pops->_read_port = &sdio_read_port;
+
+ pops->_write8 = &sdio_write8;
+ pops->_write16 = &sdio_write16;
+ pops->_write32 = &sdio_write32;
+ pops->_writeN = &sdio_writeN;
+ pops->_write_mem = &sdio_write_mem;
+ pops->_write_port = &sdio_write_port;
+
+_func_exit_;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 _sdio_local_read(
+ PADAPTER padapter,
+ u32 addr,
+ u32 cnt,
+ u8 *pbuf)
+{
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ s32 err;
+ u8 *ptmpbuf;
+ u32 n;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+// || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = _sd_cmd52_read(psdio, addr, cnt, pbuf);
+ return err;
+ }
+
+ n = RND4(cnt);
+ ptmpbuf = (u8*)rtw_malloc(n);
+ if(!ptmpbuf)
+ return (-1);
+
+ err = _sd_read(psdio, addr, n, ptmpbuf);
+ if (!err)
+ _rtw_memcpy(pbuf, ptmpbuf, cnt);
+
+ if(ptmpbuf)
+ rtw_mfree(ptmpbuf, n);
+
+ return err;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 sdio_local_read(
+ PADAPTER padapter,
+ u32 addr,
+ u32 cnt,
+ u8 *pbuf)
+{
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ s32 err;
+ u8 *ptmpbuf;
+ u32 n;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = sd_cmd52_read(psdio, addr, cnt, pbuf);
+ return err;
+ }
+
+ n = RND4(cnt);
+ ptmpbuf = (u8*)rtw_malloc(n);
+ if(!ptmpbuf)
+ return (-1);
+
+ err = sd_read(psdio, addr, n, ptmpbuf);
+ if (!err)
+ _rtw_memcpy(pbuf, ptmpbuf, cnt);
+
+ if(ptmpbuf)
+ rtw_mfree(ptmpbuf, n);
+
+ return err;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 _sdio_local_write(
+ PADAPTER padapter,
+ u32 addr,
+ u32 cnt,
+ u8 *pbuf)
+{
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ s32 err;
+ u8 *ptmpbuf;
+
+ if(addr & 0x3)
+ DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__);
+
+ if(cnt & 0x3)
+ DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__);
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+// || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = _sd_cmd52_write(psdio, addr, cnt, pbuf);
+ return err;
+ }
+
+ ptmpbuf = (u8*)rtw_malloc(cnt);
+ if(!ptmpbuf)
+ return (-1);
+
+ _rtw_memcpy(ptmpbuf, pbuf, cnt);
+
+ err = _sd_write(psdio, addr, cnt, ptmpbuf);
+
+ if (ptmpbuf)
+ rtw_mfree(ptmpbuf, cnt);
+
+ return err;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 sdio_local_write(
+ PADAPTER padapter,
+ u32 addr,
+ u32 cnt,
+ u8 *pbuf)
+{
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ s32 err;
+ u8 *ptmpbuf;
+
+ if(addr & 0x3)
+ DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__);
+
+ if(cnt & 0x3)
+ DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__);
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ err = sd_cmd52_write(psdio, addr, cnt, pbuf);
+ return err;
+ }
+
+ ptmpbuf = (u8*)rtw_malloc(cnt);
+ if(!ptmpbuf)
+ return (-1);
+
+ _rtw_memcpy(ptmpbuf, pbuf, cnt);
+
+ err = sd_write(psdio, addr, cnt, ptmpbuf);
+
+ if (ptmpbuf)
+ rtw_mfree(ptmpbuf, cnt);
+
+ return err;
+}
+
+u8 SdioLocalCmd52Read1Byte(PADAPTER padapter, u32 addr)
+{
+ PSDIO_DATA psdio;
+ u8 val = 0;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+ sd_cmd52_read(psdio, addr, 1, &val);
+
+ return val;
+}
+
+u16 SdioLocalCmd52Read2Byte(PADAPTER padapter, u32 addr)
+{
+ PSDIO_DATA psdio;
+ u16 val = 0;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+ sd_cmd52_read(psdio, addr, 2, (u8*)&val);
+
+ val = le16_to_cpu(val);
+
+ return val;
+}
+
+u32 SdioLocalCmd52Read4Byte(PADAPTER padapter, u32 addr)
+{
+ PSDIO_DATA psdio;
+ u32 val = 0;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+ sd_cmd52_read(psdio, addr, 4, (u8*)&val);
+
+ val = le32_to_cpu(val);
+
+ return val;
+}
+
+u32 SdioLocalCmd53Read4Byte(PADAPTER padapter, u32 addr)
+{
+ PSDIO_DATA psdio;
+ u8 bMacPwrCtrlOn;
+ u32 val;
+
+
+ val = 0;
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+ || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
+#endif
+ )
+ {
+ sd_cmd52_read(psdio, addr, 4, (u8*)&val);
+ val = le32_to_cpu(val);
+ }
+ else
+ val = sd_read32(psdio, addr, NULL);
+
+ return val;
+}
+
+void SdioLocalCmd52Write1Byte(PADAPTER padapter, u32 addr, u8 v)
+{
+ PSDIO_DATA psdio;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+ sd_cmd52_write(psdio, addr, 1, &v);
+}
+
+void SdioLocalCmd52Write2Byte(PADAPTER padapter, u32 addr, u16 v)
+{
+ PSDIO_DATA psdio;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+ v = cpu_to_le16(v);
+ sd_cmd52_write(psdio, addr, 2, (u8*)&v);
+}
+
+void SdioLocalCmd52Write4Byte(PADAPTER padapter, u32 addr, u32 v)
+{
+ PSDIO_DATA psdio;
+
+
+ psdio = &adapter_to_dvobj(padapter)->intf_data;
+ HalSdioGetCmdAddr8723ASdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+ v = cpu_to_le32(v);
+ sd_cmd52_write(psdio, addr, 4, (u8*)&v);
+}
+
+#if 0
+void
+DumpLoggedInterruptHistory8723Sdio(
+ PADAPTER padapter
+)
+{
+ HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter);
+ u4Byte DebugLevel = DBG_LOUD;
+
+ if (DBG_Var.DbgPrintIsr == 0)
+ return;
+
+ DBG_ChkDrvResource(padapter);
+
+
+ if(pHalData->InterruptLog.nISR_RX_REQUEST)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RX_REQUEST[%ld]\t\n", pHalData->InterruptLog.nISR_RX_REQUEST));
+
+ if(pHalData->InterruptLog.nISR_AVAL)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# AVAL[%ld]\t\n", pHalData->InterruptLog.nISR_AVAL));
+
+ if(pHalData->InterruptLog.nISR_TXERR)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXERR));
+
+ if(pHalData->InterruptLog.nISR_RXERR)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXERR[%ld]\t\n", pHalData->InterruptLog.nISR_RXERR));
+
+ if(pHalData->InterruptLog.nISR_TXFOVW)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_TXFOVW));
+
+ if(pHalData->InterruptLog.nISR_RXFOVW)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_RXFOVW));
+
+ if(pHalData->InterruptLog.nISR_TXBCNOK)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNOK[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNOK));
+
+ if(pHalData->InterruptLog.nISR_TXBCNERR)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNERR));
+
+ if(pHalData->InterruptLog.nISR_BCNERLY_INT)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# BCNERLY_INT[%ld]\t\n", pHalData->InterruptLog.nISR_BCNERLY_INT));
+
+ if(pHalData->InterruptLog.nISR_C2HCMD)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# C2HCMD[%ld]\t\n", pHalData->InterruptLog.nISR_C2HCMD));
+
+ if(pHalData->InterruptLog.nISR_CPWM1)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM1L[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM1));
+
+ if(pHalData->InterruptLog.nISR_CPWM2)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM2[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM2));
+
+ if(pHalData->InterruptLog.nISR_HSISR_IND)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# HSISR_IND[%ld]\t\n", pHalData->InterruptLog.nISR_HSISR_IND));
+
+ if(pHalData->InterruptLog.nISR_GTINT3_IND)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# GTINT3_IND[%ld]\t\n", pHalData->InterruptLog.nISR_GTINT3_IND));
+
+ if(pHalData->InterruptLog.nISR_GTINT4_IND)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# GTINT4_IND[%ld]\t\n", pHalData->InterruptLog.nISR_GTINT4_IND));
+
+ if(pHalData->InterruptLog.nISR_PSTIMEOUT)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# PSTIMEOUT[%ld]\t\n", pHalData->InterruptLog.nISR_PSTIMEOUT));
+
+ if(pHalData->InterruptLog.nISR_OCPINT)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# OCPINT[%ld]\t\n", pHalData->InterruptLog.nISR_OCPINT));
+
+ if(pHalData->InterruptLog.nISR_ATIMEND)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# ATIMEND[%ld]\t\n", pHalData->InterruptLog.nISR_ATIMEND));
+
+ if(pHalData->InterruptLog.nISR_ATIMEND_E)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# ATIMEND_E[%ld]\t\n", pHalData->InterruptLog.nISR_ATIMEND_E));
+
+ if(pHalData->InterruptLog.nISR_CTWEND)
+ RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CTWEND[%ld]\t\n", pHalData->InterruptLog.nISR_CTWEND));
+}
+
+void
+LogInterruptHistory8723Sdio(
+ PADAPTER padapter,
+ PRT_ISR_CONTENT pIsrContent
+)
+{
+ HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter);
+
+ if((pHalData->IntrMask[0] & SDIO_HIMR_RX_REQUEST_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_RX_REQUEST))
+ pHalData->InterruptLog.nISR_RX_REQUEST ++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_AVAL_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_AVAL))
+ pHalData->InterruptLog.nISR_AVAL++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_TXERR_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_TXERR))
+ pHalData->InterruptLog.nISR_TXERR++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_RXERR_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_RXERR))
+ pHalData->InterruptLog.nISR_RXERR++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_TXFOVW_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_TXFOVW))
+ pHalData->InterruptLog.nISR_TXFOVW++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_RXFOVW_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_RXFOVW))
+ pHalData->InterruptLog.nISR_RXFOVW++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNOK_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_TXBCNOK))
+ pHalData->InterruptLog.nISR_TXBCNOK++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNERR_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_TXBCNERR))
+ pHalData->InterruptLog.nISR_TXBCNERR++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_BCNERLY_INT_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_BCNERLY_INT))
+ pHalData->InterruptLog.nISR_BCNERLY_INT ++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_C2HCMD_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_C2HCMD))
+ pHalData->InterruptLog.nISR_C2HCMD++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_CPWM1_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_CPWM1))
+ pHalData->InterruptLog.nISR_CPWM1++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_CPWM2_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_CPWM2))
+ pHalData->InterruptLog.nISR_CPWM2++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_HSISR_IND_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_HSISR_IND))
+ pHalData->InterruptLog.nISR_HSISR_IND++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_GTINT3_IND_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_GTINT3_IND))
+ pHalData->InterruptLog.nISR_GTINT3_IND++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_GTINT4_IND_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_GTINT4_IND))
+ pHalData->InterruptLog.nISR_GTINT4_IND++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_PSTIMEOUT_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_PSTIMEOUT))
+ pHalData->InterruptLog.nISR_PSTIMEOUT++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_OCPINT_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_OCPINT))
+ pHalData->InterruptLog.nISR_OCPINT++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND))
+ pHalData->InterruptLog.nISR_ATIMEND++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_E_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND_E))
+ pHalData->InterruptLog.nISR_ATIMEND_E++;
+ if((pHalData->IntrMask[0] & SDIO_HIMR_CTWEND_MSK) &&
+ (pIsrContent->IntArray[0] & SDIO_HISR_CTWEND))
+ pHalData->InterruptLog.nISR_CTWEND++;
+
+}
+
+void
+DumpHardwareProfile8723Sdio(
+ IN PADAPTER padapter
+)
+{
+ DumpLoggedInterruptHistory8723Sdio(padapter);
+}
+#endif
+
+//
+// Description:
+// Initialize SDIO Host Interrupt Mask configuration variables for future use.
+//
+// Assumption:
+// Using SDIO Local register ONLY for configuration.
+//
+// Created by Roger, 2011.02.11.
+//
+void InitInterrupt8188ESdio(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+ pHalData->sdio_himr = (u32)( \
+ SDIO_HIMR_RX_REQUEST_MSK |
+// SDIO_HIMR_AVAL_MSK |
+// SDIO_HIMR_TXERR_MSK |
+// SDIO_HIMR_RXERR_MSK |
+// SDIO_HIMR_TXFOVW_MSK |
+// SDIO_HIMR_RXFOVW_MSK |
+// SDIO_HIMR_TXBCNOK_MSK |
+// SDIO_HIMR_TXBCNERR_MSK |
+#ifdef CONFIG_EXT_CLK //for sprd
+ SDIO_HIMR_BCNERLY_INT_MSK |
+#endif //CONFIG_EXT_CLK
+// SDIO_HIMR_C2HCMD_MSK |
+#ifdef CONFIG_LPS_LCLK
+ SDIO_HIMR_CPWM1_MSK |
+ SDIO_HIMR_CPWM2_MSK |
+#endif
+// SDIO_HIMR_HSISR_IND_MSK |
+// SDIO_HIMR_GTINT3_IND_MSK |
+// SDIO_HIMR_GTINT4_IND_MSK |
+// SDIO_HIMR_PSTIMEOUT_MSK |
+// SDIO_HIMR_OCPINT_MSK |
+// SDIO_HIMR_ATIMEND_MSK |
+// SDIO_HIMR_ATIMEND_E_MSK |
+// SDIO_HIMR_CTWEND_MSK |
+ 0);
+}
+
+//
+// Description:
+// Clear corresponding SDIO Host ISR interrupt service.
+//
+// Assumption:
+// Using SDIO Local register ONLY for configuration.
+//
+// Created by Roger, 2011.02.11.
+//
+void ClearInterrupt8723ASdio(PADAPTER padapter)
+{
+ u32 tmp = 0;
+ tmp = SdioLocalCmd52Read4Byte(padapter, SDIO_REG_HISR);
+ SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, tmp);
+// padapter->IsrContent.IntArray[0] = 0;
+ padapter->IsrContent = 0;
+}
+
+//
+// Description:
+// Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain.
+//
+// Assumption:
+// 1. Using SDIO Local register ONLY for configuration.
+// 2. PASSIVE LEVEL
+//
+// Created by Roger, 2011.02.11.
+//
+void EnableInterrupt8188ESdio(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+ u32 himr;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
+ padapter = padapter->pbuddy_adapter;
+ }
+#endif
+ pHalData = GET_HAL_DATA(padapter);
+ himr = cpu_to_le32(pHalData->sdio_himr);
+ sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
+
+
+ //
+ // <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM.
+ // So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore.
+ // 2011.10.19.
+ //
+ rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
+
+}
+
+//
+// Description:
+// Disable SDIO Host IMR configuration to mask unnecessary interrupt service.
+//
+// Assumption:
+// Using SDIO Local register ONLY for configuration.
+//
+// Created by Roger, 2011.02.11.
+//
+void DisableInterrupt8188ESdio(PADAPTER padapter)
+{
+ u32 himr;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
+ padapter = padapter->pbuddy_adapter;
+ }
+#endif
+ himr = cpu_to_le32(SDIO_HIMR_DISABLED);
+ sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
+
+}
+
+//
+// Description:
+// Update SDIO Host Interrupt Mask configuration on SDIO local domain.
+//
+// Assumption:
+// 1. Using SDIO Local register ONLY for configuration.
+// 2. PASSIVE LEVEL
+//
+// Created by Roger, 2011.02.11.
+//
+void UpdateInterruptMask8188ESdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR)
+{
+ HAL_DATA_TYPE *pHalData;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
+ padapter = padapter->pbuddy_adapter;
+ }
+#endif
+ pHalData = GET_HAL_DATA(padapter);
+
+ if (AddMSR)
+ pHalData->sdio_himr |= AddMSR;
+
+ if (RemoveMSR)
+ pHalData->sdio_himr &= (~RemoveMSR);
+
+ DisableInterrupt8188ESdio(padapter);
+ EnableInterrupt8188ESdio(padapter);
+}
+
+#ifdef CONFIG_WOWLAN
+void ClearInterrupt8189ESdio(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u32 v32;
+
+ pHalData->sdio_hisr &= pHalData->sdio_himr;
+
+ // clear HISR
+ v32 = pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR;
+ if (v32) {
+ v32 = cpu_to_le32(v32);
+ _sdio_local_write(padapter, SDIO_REG_HISR, 4, (u8*)&v32);
+ }
+}
+#endif
+
+#ifdef CONFIG_MAC_LOOPBACK_DRIVER
+static void sd_recv_loopback(PADAPTER padapter, u32 size)
+{
+ PLOOPBACKDATA ploopback;
+ u32 readsize, allocsize;
+ u8 *preadbuf;
+
+
+ readsize = size;
+ DBG_8192C("%s: read size=%d\n", __func__, readsize);
+ allocsize = _RND(readsize, adapter_to_dvobj(padapter)->intf_data.block_transfer_len);
+
+ ploopback = padapter->ploopback;
+ if (ploopback) {
+ ploopback->rxsize = readsize;
+ preadbuf = ploopback->rxbuf;
+ }
+ else {
+ preadbuf = rtw_malloc(allocsize);
+ if (preadbuf == NULL) {
+ DBG_8192C("%s: malloc fail size=%d\n", __func__, allocsize);
+ return;
+ }
+ }
+
+// rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+ sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+
+ if (ploopback)
+ _rtw_up_sema(&ploopback->sema);
+ else {
+ u32 i;
+
+ DBG_8192C("%s: drop pkt\n", __func__);
+ for (i = 0; i < readsize; i+=4) {
+ DBG_8192C("%08X", *(u32*)(preadbuf + i));
+ if ((i+4) & 0x1F) printk(" ");
+ else printk("\n");
+ }
+ printk("\n");
+ rtw_mfree(preadbuf, allocsize);
+ }
+}
+#endif // CONFIG_MAC_LOOPBACK_DRIVER
+
+#ifdef CONFIG_SDIO_RX_COPY
+static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size)
+{
+ u32 readsize, ret;
+ u8 *preadbuf;
+ struct recv_priv *precvpriv;
+ struct recv_buf *precvbuf;
+
+
+ readsize = size;
+
+ //3 1. alloc recvbuf
+ precvpriv = &padapter->recvpriv;
+ precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
+ if (precvbuf == NULL) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: alloc recvbuf FAIL!\n", __FUNCTION__));
+ return NULL;
+ }
+
+ //3 2. alloc skb
+ if (precvbuf->pskb == NULL) {
+ SIZE_PTR tmpaddr=0;
+ SIZE_PTR alignment=0;
+
+ DBG_871X("%s: alloc_skb for rx buffer\n", __FUNCTION__);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
+ precvbuf->pskb = __dev_alloc_skb(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL);
+#else
+ precvbuf->pskb = __netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL);
+#endif
+
+ if(precvbuf->pskb)
+ {
+ precvbuf->pskb->dev = padapter->pnetdev;
+
+ tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
+ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+ skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
+
+ precvbuf->phead = precvbuf->pskb->head;
+ precvbuf->pdata = precvbuf->pskb->data;
+ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+ precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+ precvbuf->len = 0;
+ }
+
+ if (precvbuf->pskb == NULL) {
+ DBG_871X("%s: alloc_skb fail! read=%d\n", __FUNCTION__, readsize);
+ return NULL;
+ }
+ }
+
+ //3 3. read data from rxfifo
+ preadbuf = precvbuf->pdata;
+// rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+ ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+ if (ret == _FAIL) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__));
+ return NULL;
+ }
+
+
+ //3 4. init recvbuf
+ precvbuf->len = readsize;
+
+ return precvbuf;
+}
+#else
+static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size)
+{
+ u32 readsize, allocsize, ret;
+ u8 *preadbuf;
+ _pkt *ppkt;
+ struct recv_priv *precvpriv;
+ struct recv_buf *precvbuf;
+
+
+ readsize = size;
+
+ //3 1. alloc skb
+ // align to block size
+ allocsize = _RND(readsize, adapter_to_dvobj(padapter)->intf_data.block_transfer_len);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
+ ppkt = __dev_alloc_skb(allocsize, GFP_KERNEL);
+#else
+ ppkt = __netdev_alloc_skb(padapter->pnetdev, allocsize, GFP_KERNEL);
+#endif
+ if (ppkt == NULL) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: alloc_skb fail! alloc=%d read=%d\n", __FUNCTION__, allocsize, readsize));
+ return NULL;
+ }
+
+ //3 2. read data from rxfifo
+ preadbuf = skb_put(ppkt, readsize);
+// rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+ ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+ if (ret == _FAIL) {
+ dev_kfree_skb_any(ppkt);
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__));
+ return NULL;
+ }
+
+ //3 3. alloc recvbuf
+ precvpriv = &padapter->recvpriv;
+ precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
+ if (precvbuf == NULL) {
+ dev_kfree_skb_any(ppkt);
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: alloc recvbuf FAIL!\n", __FUNCTION__));
+ return NULL;
+ }
+
+ //3 4. init recvbuf
+ precvbuf->pskb = ppkt;
+
+ precvbuf->len = ppkt->len;
+
+ precvbuf->phead = ppkt->head;
+ precvbuf->pdata = ppkt->data;
+ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+ precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+
+ return precvbuf;
+}
+#endif
+
+static void sd_rxhandler(PADAPTER padapter, struct recv_buf *precvbuf)
+{
+ struct recv_priv *precvpriv;
+ _queue *ppending_queue;
+
+
+ precvpriv = &padapter->recvpriv;
+ ppending_queue = &precvpriv->recv_buf_pending_queue;
+
+ //3 1. enqueue recvbuf
+ rtw_enqueue_recvbuf(precvbuf, ppending_queue);
+
+ //3 2. schedule tasklet
+#ifdef PLATFORM_LINUX
+ tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+}
+
+void sd_int_dpc(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (pHalData->sdio_hisr & SDIO_HISR_CPWM1)
+ {
+ struct reportpwrstate_parm report;
+
+ _sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state);
+#ifdef CONFIG_LPS_LCLK
+ //88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow.
+ //modify by Thomas. 2012/4/2.
+
+#ifdef CONFIG_EXT_CLK //for sprd
+ if(report.state & BIT(4)) //indicate FW entering 32k
+ {
+ u8 chk_cnt = 0;
+
+ do{
+ if(_sdio_read8(padapter, 0x90)&BIT(0))//FW in 32k already
+ {
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+
+ if(pwrpriv->rpwm < PS_STATE_S2)
+ {
+ //DBG_871X("disable ext clk when FW in LPS-32K already!\n");
+ EnableGpio5ClockReq(padapter, _TRUE, 0);
+ }
+
+ break;
+ }
+
+ chk_cnt++;
+
+ }while(chk_cnt<10);
+
+ if(chk_cnt==10)
+ {
+ DBG_871X("polling fw in 32k already, fail!\n");
+ }
+
+ }
+ else //indicate fw leaving 32K
+#endif //CONFIG_EXT_CLK
+ {
+ report.state |= PS_STATE_S2;
+ //cpwm_int_hdl(padapter, &report);
+ _set_workitem(&padapter->pwrctrlpriv.cpwm_event);
+ }
+#endif
+ }
+
+#ifdef CONFIG_WOWLAN
+ if (pHalData->sdio_hisr & SDIO_HISR_CPWM2) {
+ u32 value;
+ value = rtw_read32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR);
+ DBG_871X_LEVEL(_drv_always_, "Reset SDIO HISR(0x%08x) original:0x%08x\n",
+ SDIO_LOCAL_BASE+SDIO_REG_HISR, value);
+ value |= BIT19;
+ rtw_write32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR, value);
+
+ value = rtw_read8(padapter, SDIO_LOCAL_BASE+SDIO_REG_HIMR+2);
+ DBG_871X_LEVEL(_drv_always_, "Reset SDIO HIMR CPWM2(0x%08x) original:0x%02x\n",
+ SDIO_LOCAL_BASE+SDIO_REG_HIMR + 2, value);
+ }
+#endif
+ if (pHalData->sdio_hisr & SDIO_HISR_TXERR)
+ {
+ u8 *status;
+ u32 addr;
+
+ status = _rtw_malloc(4);
+ if (status)
+ {
+ addr = REG_TXDMA_STATUS;
+ HalSdioGetCmdAddr8723ASdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
+ _sd_read(&adapter_to_dvobj(padapter)->intf_data, addr, 4, status);
+ _sd_write(&adapter_to_dvobj(padapter)->intf_data, addr, 4, status);
+ DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status));
+ _rtw_mfree(status, 4);
+ } else {
+ DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
+ }
+ }
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
+ #endif
+ #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ if (pHalData->sdio_hisr & (SDIO_HISR_TXBCNOK|SDIO_HISR_TXBCNERR))
+ #endif
+ {
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ #if 0 //for debug
+ if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
+ DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__);
+
+ if (pHalData->sdio_hisr & SDIO_HISR_TXBCNOK)
+ DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
+
+ if (pHalData->sdio_hisr & SDIO_HISR_TXBCNERR)
+ DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
+ #endif
+
+
+ if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
+ {
+ //send_beacon(padapter);
+ if(pmlmepriv->update_bcn == _TRUE)
+ {
+ //tx_beacon_hdl(padapter, NULL);
+ set_tx_beacon_cmd(padapter);
+ }
+ }
+#ifdef CONFIG_CONCURRENT_MODE
+ if(check_buddy_fwstate(padapter, WIFI_AP_STATE))
+ {
+ //send_beacon(padapter);
+ if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE)
+ {
+ //tx_beacon_hdl(padapter, NULL);
+ set_tx_beacon_cmd(padapter->pbuddy_adapter);
+ }
+ }
+#endif
+ }
+#endif //CONFIG_INTERRUPT_BASED_TXBCN
+
+#ifdef CONFIG_EXT_CLK
+ if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
+ {
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ if(check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE))
+ {
+ //DBG_8192C("BCNERLY_INT for enabling ext clk\n");
+ EnableGpio5ClockReq(padapter, _TRUE, 1);
+ }
+ }
+#endif //CONFIG_EXT_CLK
+
+ if (pHalData->sdio_hisr & SDIO_HISR_C2HCMD)
+ {
+ DBG_8192C("%s: C2H Command\n", __func__);
+ }
+
+ if (pHalData->sdio_hisr & SDIO_HISR_RX_REQUEST)
+ {
+ struct recv_buf *precvbuf;
+
+ //DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
+ pHalData->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
+#ifdef CONFIG_MAC_LOOPBACK_DRIVER
+ sd_recv_loopback(padapter, pHalData->SdioRxFIFOSize);
+#else
+ do {
+ //Sometimes rx length will be zero. driver need to use cmd53 read again.
+ if(pHalData->SdioRxFIFOSize == 0)
+ {
+ u8 data[4];
+
+ _sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, data);
+
+ pHalData->SdioRxFIFOSize = le16_to_cpu(*(u16*)data);
+ }
+
+ if(pHalData->SdioRxFIFOSize)
+ {
+ precvbuf = sd_recv_rxfifo(padapter, pHalData->SdioRxFIFOSize);
+
+ pHalData->SdioRxFIFOSize = 0;
+
+ if (precvbuf)
+ sd_rxhandler(padapter, precvbuf);
+ else
+ break;
+ }
+ else
+ break;
+#ifdef CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP
+ } while (0);
+#else
+ } while (1);
+#endif
+#endif
+
+ }
+
+}
+
+void sd_int_hdl(PADAPTER padapter)
+{
+ u8 data[6];
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ if ((padapter->bDriverStopped == _TRUE) ||
+ (padapter->bSurpriseRemoved == _TRUE))
+ return;
+
+ _sdio_local_read(padapter, SDIO_REG_HISR, 6, data);
+ pHalData->sdio_hisr = le32_to_cpu(*(u32*)data);
+ pHalData->SdioRxFIFOSize = le16_to_cpu(*(u16*)&data[4]);
+
+ if (pHalData->sdio_hisr & pHalData->sdio_himr)
+ {
+ u32 v32;
+
+ pHalData->sdio_hisr &= pHalData->sdio_himr;
+
+ // clear HISR
+ v32 = pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR;
+ if (v32) {
+ v32 = cpu_to_le32(v32);
+ _sdio_local_write(padapter, SDIO_REG_HISR, 4, (u8*)&v32);
+ }
+
+ sd_int_dpc(padapter);
+
+ }
+ else
+ {
+ RT_TRACE(_module_hci_ops_c_, _drv_err_,
+ ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
+ __FUNCTION__, pHalData->sdio_hisr, pHalData->sdio_himr));
+ }
+
+}
+
+//
+// Description:
+// Query SDIO Local register to query current the number of Free TxPacketBuffer page.
+//
+// Assumption:
+// 1. Running at PASSIVE_LEVEL
+// 2. RT_TX_SPINLOCK is NOT acquired.
+//
+// Created by Roger, 2011.01.28.
+//
+u8 HalQueryTxBufferStatus8189ESdio(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u32 NumOfFreePage;
+// _irqL irql;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+
+ NumOfFreePage = SdioLocalCmd53Read4Byte(padapter, SDIO_REG_FREE_TXPG);
+
+// _enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
+ _rtw_memcpy(pHalData->SdioTxFIFOFreePage, &NumOfFreePage, 4);
+ RT_TRACE(_module_hci_ops_c_, _drv_notice_,
+ ("%s: Free page for HIQ(%#x),MIDQ(%#x),LOWQ(%#x),PUBQ(%#x)\n",
+ __FUNCTION__,
+ pHalData->SdioTxFIFOFreePage[HI_QUEUE_IDX],
+ pHalData->SdioTxFIFOFreePage[MID_QUEUE_IDX],
+ pHalData->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
+ pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
+// _exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
+
+ return _TRUE;
+}
+
+#ifdef CONFIG_WOWLAN
+u8 RecvOnePkt(PADAPTER padapter, u32 size)
+{
+ struct recv_buf *precvbuf;
+ struct dvobj_priv *psddev;
+ PSDIO_DATA psdio_data;
+ struct sdio_func *func;
+
+ u8 res = _FALSE;
+
+ DBG_8192C("+%s: size: %d+\n", __func__, size);
+
+ if (padapter == NULL) {
+ DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
+ return _FALSE;
+ }
+
+ psddev = padapter->dvobj;
+ psdio_data = &psddev->intf_data;
+ func = psdio_data->func;
+
+ if(size) {
+ sdio_claim_host(func);
+ precvbuf = sd_recv_rxfifo(padapter, size);
+
+ if (precvbuf) {
+ //printk("Completed Recv One Pkt.\n");
+ sd_rxhandler(padapter, precvbuf);
+ res = _TRUE;
+ }else{
+ res = _FALSE;
+ }
+ sdio_release_host(func);
+ }
+ DBG_8192C("-%s-\n", __func__);
+ return res;
+}
+#endif //CONFIG_WOWLAN