mirror of
https://github.com/drasko/open-ameba.git
synced 2026-07-07 03:45:42 +00:00
Change SDK dir name. Use OpenOCD only.
Signed-off-by: Drasko DRASKOVIC <drasko.draskovic@gmail.com>
This commit is contained in:
parent
05b731b5f3
commit
eeb7f808ae
1446 changed files with 1 additions and 65 deletions
|
|
@ -0,0 +1,493 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 _GSPI_INTF_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
|
||||
struct dvobj_priv *gspi_dvobj_init(void)
|
||||
{
|
||||
// int status = _FAIL;
|
||||
struct dvobj_priv *dvobj = NULL;
|
||||
PGSPI_DATA pgspi_data;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
dvobj = (struct dvobj_priv*)rtw_zmalloc(sizeof(*dvobj));
|
||||
if (NULL == dvobj) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pgspi_data = &dvobj->intf_data;
|
||||
|
||||
rtw_mutex_init(&pgspi_data->spi_mutex);
|
||||
//pgspi_data->block_transfer_len = 512; //512 blocks r/w is not required for GSPI interface
|
||||
//pgspi_data->tx_block_mode = 0;
|
||||
//pgspi_data->rx_block_mode = 0;
|
||||
|
||||
// status = _SUCCESS;
|
||||
|
||||
#if 0
|
||||
free_dvobj:
|
||||
if (status != _SUCCESS && dvobj) {
|
||||
rtw_mfree((u8*)dvobj, sizeof(*dvobj));
|
||||
dvobj = NULL;
|
||||
}
|
||||
#endif
|
||||
exit:
|
||||
_func_exit_;
|
||||
|
||||
return dvobj;
|
||||
}
|
||||
|
||||
void gspi_dvobj_deinit(struct dvobj_priv *dvobj)
|
||||
{
|
||||
//TODO
|
||||
// struct dvobj_priv *dvobj = spi_get_drvdata(spi);
|
||||
|
||||
_func_enter_;
|
||||
//TODO
|
||||
// spi_set_drvdata(spi, NULL);
|
||||
if (dvobj) {
|
||||
//TODO
|
||||
// gspi_deinit(dvobj);
|
||||
rtw_mutex_free(&dvobj->intf_data.spi_mutex);
|
||||
rtw_mfree((u8*)dvobj, sizeof(*dvobj));
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
}
|
||||
|
||||
s32 gspi_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe)
|
||||
{
|
||||
s32 ret = _SUCCESS;
|
||||
struct pkt_attrib *pattrib;
|
||||
struct xmit_buf *pxmitbuf;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
u8 *pframe = NULL;
|
||||
|
||||
RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("+rtw_xmit_mgnt()\n"));
|
||||
|
||||
pattrib = &pmgntframe->attrib;
|
||||
pxmitbuf = pmgntframe->pxmitbuf;
|
||||
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
|
||||
|
||||
rtw_hal_update_txdesc(padapter, pmgntframe, pmgntframe->buf_addr);
|
||||
|
||||
pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
|
||||
//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);
|
||||
|
||||
//RT_TRACE(_module_rtl871x_xmit_c_, _drv_always_, ("+rtw_xmit_mgnt(): type=%d\n", GetFrameSubType(pframe)));
|
||||
if(GetFrameSubType(pframe)==WIFI_BEACON) //dump beacon directly
|
||||
{
|
||||
//When using dedicated xmit frame for issue bcn on ap mode
|
||||
//free xmit frame for bcn reserved page on station mode - Alex Fang
|
||||
#if USE_DEDICATED_BCN_TX
|
||||
if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) {
|
||||
rtw_free_xmitframe(pxmitpriv, pmgntframe);
|
||||
pxmitbuf->priv_data = NULL;
|
||||
}
|
||||
rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, pxmitbuf->pbuf);
|
||||
|
||||
if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
|
||||
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
|
||||
#else
|
||||
rtw_free_xmitframe(pxmitpriv, pmgntframe);
|
||||
pxmitbuf->priv_data = NULL;
|
||||
rtw_xmit_xmitbuf(padapter, pxmitbuf);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
rtw_free_xmitframe(pxmitpriv, pmgntframe);
|
||||
pxmitbuf->priv_data = NULL;
|
||||
rtw_xmit_xmitbuf(padapter, pxmitbuf);
|
||||
}
|
||||
|
||||
if (ret != _SUCCESS)
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
|
||||
|
||||
RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("-rtw_xmit_mgnt\n"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
//#include <skbuff.h>
|
||||
s32 gspi_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe)
|
||||
{
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
_irqL irql;
|
||||
s32 err;
|
||||
|
||||
#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
|
||||
|
||||
#if USE_SKB_AS_XMITBUF
|
||||
rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
|
||||
#endif
|
||||
|
||||
rtw_enter_critical_bh(&pxmitpriv->lock, &irql);
|
||||
#if 1 //FIX_XMITFRAME_FAULT, move from rtw_xmit().
|
||||
#ifdef CONFIG_AP_MODE
|
||||
if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE)
|
||||
{
|
||||
rtw_exit_critical_bh(&pxmitpriv->lock, &irql);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
err = rtw_xmitframe_enqueue(padapter, pxmitframe);
|
||||
rtw_exit_critical_bh(&pxmitpriv->lock, &irql);
|
||||
|
||||
if (err != _SUCCESS) {
|
||||
RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmit_data(): enqueue xmitframe fail\n"));
|
||||
rtw_free_xmitframe(pxmitpriv, pxmitframe);
|
||||
|
||||
// Trick, make the statistics correct
|
||||
pxmitpriv->tx_pkts--;
|
||||
pxmitpriv->tx_drop++;
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz);
|
||||
#ifdef CONFIG_CONCURRENT_MODE
|
||||
if (padapter->adapter_type > PRIMARY_ADAPTER){
|
||||
padapter = padapter->pbuddy_adapter;
|
||||
}
|
||||
#endif
|
||||
|
||||
rtw_wakeup_task(&padapter->xmitThread);
|
||||
|
||||
return _FALSE;
|
||||
}
|
||||
|
||||
const struct host_ctrl_intf_ops hci_ops = {
|
||||
gspi_dvobj_init,
|
||||
gspi_dvobj_deinit,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
//TODO
|
||||
#if 0
|
||||
|
||||
unsigned int oob_irq;
|
||||
static irqreturn_t spi_interrupt_thread(int irq, void *data)
|
||||
{
|
||||
struct dvobj_priv *dvobj;
|
||||
PGSPI_DATA pgspi_data;
|
||||
|
||||
|
||||
dvobj = (struct dvobj_priv*)data;
|
||||
pgspi_data = &dvobj->intf_data;
|
||||
|
||||
//spi_int_hdl(padapter);
|
||||
if (pgspi_data->priv_wq)
|
||||
queue_delayed_work(pgspi_data->priv_wq, &pgspi_data->irq_work, 0);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static u8 gspi_alloc_irq(struct dvobj_priv *dvobj)
|
||||
{
|
||||
PGSPI_DATA pgspi_data;
|
||||
struct spi_device *spi;
|
||||
int err;
|
||||
|
||||
|
||||
pgspi_data = &dvobj->intf_data;
|
||||
spi = pgspi_data->func;
|
||||
|
||||
err = request_irq(oob_irq, spi_interrupt_thread,
|
||||
IRQF_TRIGGER_FALLING,//IRQF_TRIGGER_HIGH;//|IRQF_ONESHOT,
|
||||
DRV_NAME, dvobj);
|
||||
//err = request_threaded_irq(oob_irq, NULL, spi_interrupt_thread,
|
||||
// IRQF_TRIGGER_FALLING,
|
||||
// DRV_NAME, dvobj);
|
||||
if (err < 0) {
|
||||
DBG_871X("Oops: can't allocate irq %d err:%d\n", oob_irq, err);
|
||||
goto exit;
|
||||
}
|
||||
enable_irq_wake(oob_irq);
|
||||
disable_irq(oob_irq);
|
||||
|
||||
exit:
|
||||
return err?_FAIL:_SUCCESS;
|
||||
}
|
||||
|
||||
#endif //#if 0
|
||||
//TODO
|
||||
#if 0
|
||||
|
||||
static void spi_irq_work(void *data)
|
||||
{
|
||||
struct delayed_work *dwork;
|
||||
PGSPI_DATA pgspi;
|
||||
struct dvobj_priv *dvobj;
|
||||
|
||||
|
||||
dwork = container_of(data, struct delayed_work, work);
|
||||
pgspi = container_of(dwork, GSPI_DATA, irq_work);
|
||||
|
||||
dvobj = spi_get_drvdata(pgspi->func);
|
||||
if (!dvobj->if1) {
|
||||
DBG_871X("%s if1 == NULL !!\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
spi_int_hdl(dvobj->if1);
|
||||
}
|
||||
|
||||
#endif //#if 0
|
||||
|
||||
|
||||
//TODO
|
||||
#if 0
|
||||
|
||||
static int rtw_gspi_suspend(struct spi_device *spi, pm_message_t mesg)
|
||||
{
|
||||
struct dvobj_priv *dvobj = spi_get_drvdata(spi);
|
||||
PADAPTER padapter = (_adapter *)dvobj->if1;
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct net_device *pnetdev = padapter->pnetdev;
|
||||
int ret = 0;
|
||||
|
||||
u32 start_time = rtw_get_current_time();
|
||||
|
||||
_func_enter_;
|
||||
|
||||
DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
|
||||
|
||||
pwrpriv->bInSuspend = _TRUE;
|
||||
|
||||
while (pwrpriv->bips_processing == _TRUE)
|
||||
rtw_msleep_os(1);
|
||||
|
||||
if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved))
|
||||
{
|
||||
DBG_871X("%s bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", __FUNCTION__
|
||||
,padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rtw_cancel_all_timer(padapter);
|
||||
LeaveAllPowerSaveMode(padapter);
|
||||
|
||||
//padapter->net_closed = _TRUE;
|
||||
//s1.
|
||||
if(pnetdev)
|
||||
{
|
||||
netif_carrier_off(pnetdev);
|
||||
rtw_netif_stop_queue(pnetdev);
|
||||
}
|
||||
#ifdef CONFIG_WOWLAN
|
||||
padapter->pwrctrlpriv.bSupportWakeOnWlan=_TRUE;
|
||||
#else
|
||||
//s2.
|
||||
//s2-1. issue rtw_disassoc_cmd to fw
|
||||
disconnect_hdl(padapter, NULL);
|
||||
//rtw_disassoc_cmd(padapter);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LAYER2_ROAMING_RESUME
|
||||
if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) )
|
||||
{
|
||||
DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__,
|
||||
pmlmepriv->cur_network.network.Ssid.Ssid,
|
||||
MAC_ARG(pmlmepriv->cur_network.network.MacAddress),
|
||||
pmlmepriv->cur_network.network.Ssid.SsidLength,
|
||||
pmlmepriv->assoc_ssid.SsidLength);
|
||||
|
||||
pmlmepriv->to_roaming = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
//s2-2. indicate disconnect to os
|
||||
rtw_indicate_disconnect(padapter);
|
||||
//s2-3.
|
||||
rtw_free_assoc_resources(padapter, 1);
|
||||
|
||||
//s2-4.
|
||||
rtw_free_network_queue(padapter, _TRUE);
|
||||
|
||||
rtw_led_control(padapter, LED_CTL_POWER_OFF);
|
||||
|
||||
rtw_dev_unload(padapter);
|
||||
|
||||
if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
|
||||
rtw_indicate_scan_done(padapter, 1);
|
||||
|
||||
if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
|
||||
rtw_indicate_disconnect(padapter);
|
||||
|
||||
// interface deinit
|
||||
gspi_deinit(dvobj);
|
||||
RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("%s: deinit GSPI complete!\n", __FUNCTION__));
|
||||
|
||||
rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_OFF);
|
||||
rtw_mdelay_os(1);
|
||||
exit:
|
||||
DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__
|
||||
, ret, rtw_get_passing_time_ms(start_time));
|
||||
|
||||
_func_exit_;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern int pm_netdev_open(struct net_device *pnetdev,u8 bnormal);
|
||||
int rtw_resume_process(_adapter *padapter)
|
||||
{
|
||||
struct net_device *pnetdev;
|
||||
struct pwrctrl_priv *pwrpriv;
|
||||
u8 is_pwrlock_hold_by_caller;
|
||||
u8 is_directly_called_by_auto_resume;
|
||||
int ret = 0;
|
||||
u32 start_time = rtw_get_current_time();
|
||||
|
||||
_func_enter_;
|
||||
|
||||
DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
|
||||
|
||||
rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_ON);
|
||||
rtw_mdelay_os(1);
|
||||
|
||||
rtw_set_chip_endian(adapter);
|
||||
|
||||
if (padapter) {
|
||||
pnetdev = padapter->pnetdev;
|
||||
pwrpriv = &padapter->pwrctrlpriv;
|
||||
} else {
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// interface init
|
||||
if (gspi_init(adapter_to_dvobj(padapter)) != _SUCCESS)
|
||||
{
|
||||
ret = -1;
|
||||
RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!!\n", __FUNCTION__));
|
||||
goto exit;
|
||||
}
|
||||
rtw_hal_disable_interrupt(padapter);
|
||||
if (gspi_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)
|
||||
{
|
||||
ret = -1;
|
||||
RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: gspi_alloc_irq Failed!!\n", __FUNCTION__));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rtw_reset_drv_sw(padapter);
|
||||
pwrpriv->bkeepfwalive = _FALSE;
|
||||
|
||||
DBG_871X("bkeepfwalive(%x)\n",pwrpriv->bkeepfwalive);
|
||||
if(pm_netdev_open(pnetdev,_TRUE) != 0) {
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
netif_device_attach(pnetdev);
|
||||
netif_carrier_on(pnetdev);
|
||||
|
||||
if( padapter->pid[1]!=0) {
|
||||
DBG_871X("pid[1]:%d\n",padapter->pid[1]);
|
||||
rtw_signal_process(padapter->pid[1], SIGUSR2);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LAYER2_ROAMING_RESUME
|
||||
rtw_roaming(padapter, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RESUME_IN_WORKQUEUE
|
||||
rtw_unlock_suspend();
|
||||
#endif //CONFIG_RESUME_IN_WORKQUEUE
|
||||
|
||||
pwrpriv->bInSuspend = _FALSE;
|
||||
exit:
|
||||
DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__
|
||||
, ret, rtw_get_passing_time_ms(start_time));
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw_gspi_resume(struct spi_device *spi)
|
||||
{
|
||||
struct dvobj_priv *dvobj = spi_get_drvdata(spi);
|
||||
PADAPTER padapter = (_adapter *)dvobj->if1;
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
|
||||
|
||||
if(pwrpriv->bInternalAutoSuspend ){
|
||||
ret = rtw_resume_process(padapter);
|
||||
} else {
|
||||
#ifdef CONFIG_RESUME_IN_WORKQUEUE
|
||||
rtw_resume_in_workqueue(pwrpriv);
|
||||
#elif defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
|
||||
if(rtw_is_earlysuspend_registered(pwrpriv)) {
|
||||
//jeff: bypass resume here, do in late_resume
|
||||
pwrpriv->do_late_resume = _TRUE;
|
||||
} else {
|
||||
ret = rtw_resume_process(padapter);
|
||||
}
|
||||
#else // Normal resume process
|
||||
ret = rtw_resume_process(padapter);
|
||||
#endif //CONFIG_RESUME_IN_WORKQUEUE
|
||||
}
|
||||
|
||||
DBG_871X("<======== %s return %d\n", __FUNCTION__, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static struct spi_driver rtw_spi_drv = {
|
||||
.probe = rtw_drv_probe,
|
||||
.remove = rtw_dev_remove,
|
||||
.suspend = rtw_gspi_suspend,
|
||||
.resume = rtw_gspi_resume,
|
||||
.driver = {
|
||||
.name = "wlan_spi",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //#if 0
|
||||
#endif
|
||||
566
sdk/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_io.c
Normal file
566
sdk/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_io.c
Normal file
|
|
@ -0,0 +1,566 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 _GSPI_IO_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
|
||||
u8 spi_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err);
|
||||
u16 spi_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err);
|
||||
u32 spi_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err);
|
||||
s32 spi_write8(struct dvobj_priv *pdvobj, u32 addr, u8 buf, s32 *err);
|
||||
s32 spi_write16(struct dvobj_priv *pdvobj, u32 addr, u16 buf, s32 *err);
|
||||
s32 spi_write32(struct dvobj_priv *pdvobj, u32 addr, u32 buf, s32 *err);
|
||||
|
||||
static u32 rtw_spi_transfer(
|
||||
struct dvobj_priv *pdvobj,
|
||||
bool pool,
|
||||
u8* buf,
|
||||
u32 buf_len)
|
||||
{
|
||||
_mutex *spi_mutex;
|
||||
u32 ret_value = _SUCCESS;
|
||||
|
||||
spi_mutex = &(pdvobj->intf_data.spi_mutex);
|
||||
|
||||
rtw_enter_critical_mutex(spi_mutex, NULL);
|
||||
if(!WLAN_BSP_Transfer(buf, buf_len))
|
||||
ret_value = _FAIL;
|
||||
rtw_exit_critical_mutex(spi_mutex, NULL);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
static int addr_convert(u32 addr)
|
||||
{
|
||||
u32 domain_id = 0 ;
|
||||
u32 temp_addr = addr&0xffff0000;
|
||||
|
||||
if (temp_addr == 0 ) {
|
||||
domain_id = WLAN_IOREG_DOMAIN;
|
||||
return domain_id;
|
||||
}
|
||||
|
||||
switch (temp_addr) {
|
||||
case WLAN_LOCAL_OFFSET:
|
||||
domain_id = SPI_LOCAL_DOMAIN;
|
||||
break;
|
||||
case WLAN_IOREG_OFFSET:
|
||||
domain_id = WLAN_IOREG_DOMAIN;
|
||||
break;
|
||||
case FW_FIFO_OFFSET:
|
||||
domain_id = FW_FIFO_DOMAIN;
|
||||
break;
|
||||
case TX_HIQ_OFFSET:
|
||||
domain_id = TX_HIQ_DOMAIN;
|
||||
break;
|
||||
case TX_MIQ_OFFSET:
|
||||
domain_id = TX_MIQ_DOMAIN;
|
||||
break;
|
||||
case TX_LOQ_OFFSET:
|
||||
domain_id = TX_LOQ_DOMAIN;
|
||||
break;
|
||||
case RX_RXOFF_OFFSET:
|
||||
domain_id = RX_RXFIFO_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return domain_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* Translate sdio fifo address to Domain ID in each WLAN FIFO
|
||||
*/
|
||||
static u32 hwaddr2txfifo(u32 addr)
|
||||
{
|
||||
u32 fifo_domain_id;
|
||||
switch (addr)
|
||||
{
|
||||
case WLAN_TX_HIQ_DEVICE_ID:
|
||||
fifo_domain_id = TX_HIQ_DOMAIN;
|
||||
break;
|
||||
|
||||
case WLAN_TX_MIQ_DEVICE_ID:
|
||||
fifo_domain_id = TX_MIQ_DOMAIN;
|
||||
break;
|
||||
|
||||
case WLAN_TX_LOQ_DEVICE_ID:
|
||||
fifo_domain_id = TX_LOQ_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
fifo_domain_id = TX_LOQ_DOMAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
return fifo_domain_id;
|
||||
}
|
||||
|
||||
static u32 buf_endian_reverse(u32 src)
|
||||
{
|
||||
return (((src&0x000000ff)<<24)|((src&0x0000ff00)<<8)|
|
||||
((src&0x00ff0000)>>8)|((src&0xff000000)>>24));
|
||||
}
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
#ifdef CONFIG_RTL8188F
|
||||
u8 spi_query_status_info(struct dvobj_priv *pdvobj)
|
||||
{
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX] = spi_read8(pdvobj, LOCAL_REG_FREE_TXPG, NULL);
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX] =spi_read8(pdvobj, LOCAL_REG_FREE_TXPG+2, NULL);
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = spi_read8(pdvobj, LOCAL_REG_FREE_TXPG+4, NULL);
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = spi_read8(pdvobj, LOCAL_REG_FREE_TXPG+6, NULL);
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_notice_,
|
||||
("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n",
|
||||
__FUNCTION__,
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
|
||||
//_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
#else
|
||||
u8 spi_query_status_info(struct dvobj_priv *pdvobj)
|
||||
{
|
||||
u32 NumOfFreePage;
|
||||
|
||||
NumOfFreePage = spi_read32(pdvobj, LOCAL_REG_FREE_TXPG, NULL);
|
||||
|
||||
// _enter_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql);
|
||||
rtw_memcpy(pdvobj->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__,
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
|
||||
// _exit_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql);
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
static void spi_get_status_info(struct dvobj_priv *pdvobj, unsigned char *status)
|
||||
{
|
||||
#ifdef CONFIG_MEMORY_ACCESS_ALIGNED
|
||||
u32 local_status[2];
|
||||
u8 *pstatus = (u8*)(&local_status[0]);
|
||||
|
||||
memcpy(pstatus, status, GSPI_STATUS_LEN);
|
||||
#else
|
||||
u8 *pstatus = status;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTL8188F
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = GET_STATUS_PUB_PAGE_NUM(pstatus)*2;
|
||||
#else
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = GET_STATUS_PUB_PAGE_NUM(pstatus);
|
||||
#endif
|
||||
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX] = GET_STATUS_HI_PAGE_NUM(pstatus);
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX] = GET_STATUS_MID_PAGE_NUM(pstatus);
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = GET_STATUS_LOW_PAGE_NUM(pstatus);
|
||||
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_dump_,
|
||||
("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n",
|
||||
__FUNCTION__,
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
|
||||
}
|
||||
|
||||
static int spi_read_write_reg(struct dvobj_priv *pdvobj, int write_flag, u32 addr, char * buf, int len, u32 eddien)
|
||||
{
|
||||
int fun = 1, domain_id = 0x0; //LOCAL
|
||||
unsigned int cmd = 0 ;
|
||||
int byte_en = 0 ;//,i = 0 ;
|
||||
int ret = 1;
|
||||
unsigned char status[8] = {0};
|
||||
unsigned int data_tmp = 0;
|
||||
u32 force_bigendian = eddien;
|
||||
|
||||
u32 spi_buf[4] = {0};
|
||||
bool polled = TRUE;
|
||||
|
||||
if (len!=1 && len!=2 && len != 4) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
domain_id = addr_convert(addr);
|
||||
|
||||
addr &= 0x7fff;
|
||||
len &= 0xff;
|
||||
if (write_flag) //write register
|
||||
{
|
||||
int remainder = addr % 4;
|
||||
u32 val32 = *(u32 *)buf;
|
||||
switch(len) {
|
||||
case 1:
|
||||
byte_en = (0x1 << remainder);
|
||||
data_tmp = (val32& 0xff)<< (remainder*8);
|
||||
break;
|
||||
case 2:
|
||||
byte_en = (0x3 << remainder);
|
||||
data_tmp = (val32 & 0xffff)<< (remainder*8);
|
||||
break;
|
||||
case 4:
|
||||
byte_en = 0xf;
|
||||
data_tmp = val32 & 0xffffffff;
|
||||
break;
|
||||
default:
|
||||
byte_en = 0xf;
|
||||
data_tmp = val32 & 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //read register
|
||||
{
|
||||
switch(len) {
|
||||
case 1:
|
||||
byte_en = 0x1;
|
||||
break;
|
||||
case 2:
|
||||
byte_en = 0x3;
|
||||
break;
|
||||
case 4:
|
||||
byte_en = 0xf;
|
||||
break;
|
||||
default:
|
||||
byte_en = 0xf;
|
||||
break;
|
||||
}
|
||||
|
||||
if(domain_id == SPI_LOCAL_DOMAIN)
|
||||
byte_en = 0;
|
||||
}
|
||||
|
||||
//addr = 0xF0 4byte: 0x2800f00f
|
||||
REG_LEN_FORMAT(&cmd, byte_en);
|
||||
REG_ADDR_FORMAT(&cmd, (addr&0xfffffffc));
|
||||
REG_DOMAIN_ID_FORMAT(&cmd, domain_id);
|
||||
REG_FUN_FORMAT(&cmd, fun);
|
||||
REG_RW_FORMAT(&cmd, write_flag);
|
||||
|
||||
if (force_bigendian) {
|
||||
cmd = buf_endian_reverse(cmd);
|
||||
}
|
||||
|
||||
if (!write_flag && (domain_id!= RX_RXFIFO_DOMAIN)) {
|
||||
u32 read_data = 0;
|
||||
|
||||
rtw_memset(spi_buf, 0x00, sizeof(spi_buf));
|
||||
|
||||
spi_buf[0] = cmd;
|
||||
spi_buf[1] = 0;
|
||||
spi_buf[2] = 0;
|
||||
spi_buf[3] = 0;
|
||||
|
||||
rtw_spi_transfer(pdvobj, polled, (u8*)spi_buf, sizeof(spi_buf));
|
||||
|
||||
rtw_memcpy(status, (u8 *) &spi_buf[1], sizeof(status));
|
||||
read_data = EF4Byte(spi_buf[3]);
|
||||
|
||||
//add for 8810
|
||||
#ifdef CONFIG_BIG_ENDIAN
|
||||
if (!force_bigendian)
|
||||
read_data = buf_endian_reverse(read_data);
|
||||
#else
|
||||
if (force_bigendian)
|
||||
read_data = buf_endian_reverse(read_data);
|
||||
#endif
|
||||
*(u32*)buf = read_data;
|
||||
} else if (write_flag ) {
|
||||
|
||||
#ifdef CONFIG_BIG_ENDIAN
|
||||
if (!force_bigendian)
|
||||
data_tmp = buf_endian_reverse(data_tmp);
|
||||
#else
|
||||
if (force_bigendian)
|
||||
data_tmp = buf_endian_reverse(data_tmp);
|
||||
#endif
|
||||
|
||||
spi_buf[0] = cmd;
|
||||
spi_buf[1] = data_tmp;
|
||||
spi_buf[2] = 0;
|
||||
spi_buf[3] = 0;
|
||||
|
||||
rtw_spi_transfer(pdvobj, polled, (u8*)spi_buf, sizeof(spi_buf));
|
||||
|
||||
rtw_memcpy(status, (u8 *) &spi_buf[2], sizeof(status));
|
||||
}
|
||||
|
||||
spi_get_status_info(pdvobj, (unsigned char*)status);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_io_priv(struct dvobj_priv *pdvobj)
|
||||
{
|
||||
//struct dvobj_priv *pdvobj = &Adapter->dvobjpriv;
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
static int spi_write8_endian(struct dvobj_priv *pdvobj, u32 addr, u32 buf, u32 big)
|
||||
{
|
||||
return spi_read_write_reg(pdvobj,1,addr,(char *)&buf,1, big);
|
||||
}
|
||||
|
||||
u8 spi_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err)
|
||||
{
|
||||
u32 ret = 0;
|
||||
int val32 = 0 , remainder = 0 ;
|
||||
s32 _err = 0;
|
||||
|
||||
_err = spi_read_write_reg(pdvobj,0,addr&0xFFFFFFFC,(char *)&ret,4,0);
|
||||
remainder = addr % 4;
|
||||
val32 = ret;
|
||||
val32 = (val32& (0xff<< (remainder<<3)))>>(remainder<<3);
|
||||
|
||||
if (err)
|
||||
*err = _err;
|
||||
|
||||
return (u8)val32;
|
||||
|
||||
}
|
||||
|
||||
u16 spi_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err)
|
||||
{
|
||||
u32 ret = 0;
|
||||
int val32 = 0 , remainder = 0 ;
|
||||
s32 _err = 0;
|
||||
|
||||
_err = spi_read_write_reg(pdvobj,0,addr&0xFFFFFFFC,(char *)&ret,4,0);
|
||||
remainder = addr % 4;
|
||||
val32 = ret;
|
||||
val32 = (val32& (0xffff<< (remainder<<3)))>>(remainder<<3);
|
||||
|
||||
if (err)
|
||||
*err = _err;
|
||||
|
||||
return (u16)val32;
|
||||
}
|
||||
|
||||
u32 spi_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err)
|
||||
{
|
||||
u32 ret = 0;
|
||||
s32 _err = 0;
|
||||
|
||||
_err = spi_read_write_reg(pdvobj,0,addr&0xFFFFFFFC,(char *)&ret,4,0);
|
||||
if (err)
|
||||
*err = _err;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 spi_write8(struct dvobj_priv *pdvobj, u32 addr, u8 buf, s32 *err)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = spi_read_write_reg(pdvobj,1,addr,(char *)&buf,1,0);
|
||||
if (err)
|
||||
*err = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 spi_write16(struct dvobj_priv *pdvobj, u32 addr, u16 buf, s32 *err)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = spi_read_write_reg(pdvobj,1,addr,(char *)&buf,2,0);
|
||||
if (err)
|
||||
*err = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 spi_write32(struct dvobj_priv *pdvobj, u32 addr, u32 buf, s32 *err)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = spi_read_write_reg(pdvobj, 1,addr,(char *)&buf,4,0);
|
||||
if (err)
|
||||
*err = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_read_rx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *buf, u32 len, struct fifo_more_data *pmore_data)
|
||||
{
|
||||
int fun = 1, domain_id = RX_RXFIFO_DOMAIN;
|
||||
unsigned int cmd = 0;
|
||||
unsigned char *status = buf + len;
|
||||
u8 *spi_buf = (u8 *) (buf - GSPI_CMD_LEN);
|
||||
int spi_buf_len = 0;
|
||||
bool polled = TRUE;
|
||||
bool use_alloc = FALSE;
|
||||
u32 max_skb_len = 0;
|
||||
|
||||
#ifndef CONFIG_DONT_CARE_TP
|
||||
max_skb_len = MAX_SKB_BUF_SIZE;
|
||||
#else
|
||||
max_skb_len = MAX_RX_SKB_BUF_SIZE;
|
||||
#endif
|
||||
|
||||
if(((GSPI_CMD_LEN + len + GSPI_STATUS_LEN) > max_skb_len) || (!buf)) {
|
||||
#if !defined(CONFIG_MP_INCLUDED) || !defined(CONFIG_MP_IWPRIV_SUPPORT) // Cloud 2013/09/06
|
||||
DBG_871X("data len=%d, MAX_SKB_BUF_SIZE(%d) is not enough, change to dynamic alloc\n", len, max_skb_len);
|
||||
#endif
|
||||
use_alloc = TRUE;
|
||||
spi_buf_len = GSPI_CMD_LEN + len + GSPI_STATUS_LEN;
|
||||
spi_buf = rtw_malloc(spi_buf_len);
|
||||
|
||||
if(spi_buf == NULL) {
|
||||
DBG_871X("Failed to alloc %d bytes\n", len);
|
||||
return _FAIL;
|
||||
}
|
||||
else {
|
||||
buf = spi_buf + GSPI_CMD_LEN;
|
||||
status = spi_buf + GSPI_CMD_LEN + len;
|
||||
}
|
||||
}
|
||||
|
||||
FIFO_LEN_FORMAT(&cmd, len); //TX Agg len
|
||||
FIFO_DOMAIN_ID_FORMAT(&cmd, domain_id);
|
||||
FIFO_FUN_FORMAT(&cmd, fun);
|
||||
FIFO_RW_FORMAT(&cmd, 0); //read
|
||||
|
||||
rtw_memset(status, 0x00, GSPI_STATUS_LEN);
|
||||
rtw_memset(buf, 0x0, len);
|
||||
|
||||
#ifdef CONFIG_MEMORY_ACCESS_ALIGNED
|
||||
memcpy(spi_buf, (u8 *)&cmd, sizeof(int));
|
||||
#else
|
||||
*((u32 *) spi_buf) = cmd;
|
||||
#endif
|
||||
|
||||
rtw_spi_transfer(pdvobj, polled, (u8 *) spi_buf, GSPI_CMD_LEN + len + GSPI_STATUS_LEN);
|
||||
|
||||
spi_get_status_info(pdvobj, status);
|
||||
pmore_data->more_data = GET_STATUS_HISR_LOW8BIT(status) & BIT(0);
|
||||
pmore_data->len = GET_STATUS_RX_LENGTH(status);
|
||||
|
||||
if(use_alloc) {
|
||||
//Drop the data
|
||||
rtw_mfree(spi_buf, spi_buf_len);
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
static int spi_write_tx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *buf, u32 len)
|
||||
{
|
||||
int fun = 1; //TX_HIQ_FIFO
|
||||
unsigned int cmd = 0;
|
||||
unsigned char *status = buf + len;
|
||||
u8 *spi_buf = (u8 *) (buf - GSPI_CMD_LEN);
|
||||
u32 page_num = 0;
|
||||
u32 wait_num = 100;
|
||||
bool polled = TRUE;
|
||||
u32 fifo = 0;
|
||||
|
||||
_func_enter_;
|
||||
fifo = hwaddr2txfifo(addr);
|
||||
|
||||
spi_query_status_info(pdvobj);
|
||||
if (fifo == TX_HIQ_DOMAIN)
|
||||
page_num = pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX];
|
||||
else if (fifo == TX_LOQ_DOMAIN)
|
||||
page_num = pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX];
|
||||
else
|
||||
page_num = pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX];
|
||||
|
||||
while (page_num + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] < 15) {
|
||||
DBG_871X("Oops: spi_write_tx_fifo(): page_num is %d, padapter->pub_page is %d, wait_num is %d",
|
||||
page_num, pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX], wait_num);
|
||||
|
||||
rtw_msleep_os(1);
|
||||
//rtw_udelay_os(20);
|
||||
spi_read32(pdvobj, 0x608, NULL);
|
||||
|
||||
if (fifo == TX_HIQ_DOMAIN)
|
||||
page_num = pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX];
|
||||
else if (fifo == TX_LOQ_DOMAIN)
|
||||
page_num = pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX];
|
||||
else
|
||||
page_num = pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX];
|
||||
|
||||
if (wait_num <= 2) {
|
||||
DBG_871X("%s(): wait_num is <= 2 drop", __FUNCTION__);
|
||||
return _FAIL;
|
||||
}
|
||||
wait_num --;
|
||||
}
|
||||
|
||||
FIFO_LEN_FORMAT(&cmd, len); //TX Agg len
|
||||
FIFO_DOMAIN_ID_FORMAT(&cmd, fifo);
|
||||
FIFO_FUN_FORMAT(&cmd, fun);
|
||||
FIFO_RW_FORMAT(&cmd, (unsigned int) 1); //write
|
||||
|
||||
//DBG_871X("%s(): len = %d\n", __FUNCTION__, len);
|
||||
//RT_PRINT_DATA(_module_hal_xmit_c_, _drv_always_, "Tx:\n", buf, GSPI_CMD_LEN + len);
|
||||
rtw_memset(status, 0x00, GSPI_STATUS_LEN);
|
||||
|
||||
#ifdef CONFIG_MEMORY_ACCESS_ALIGNED
|
||||
memcpy(spi_buf, (u8 *)&cmd, sizeof(int));
|
||||
#else
|
||||
*((u32 *) spi_buf) = cmd;
|
||||
#endif
|
||||
|
||||
rtw_spi_transfer(pdvobj, polled, (u8 *) spi_buf, GSPI_CMD_LEN + len + GSPI_STATUS_LEN);
|
||||
|
||||
spi_get_status_info(pdvobj, status);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
void spi_set_intf_ops(struct _io_ops *pops)
|
||||
{
|
||||
pops->init_io_priv = &spi_io_priv;
|
||||
pops->write8_endian = &spi_write8_endian;
|
||||
|
||||
pops->_read8 = &spi_read8;
|
||||
pops->_read16 = &spi_read16;
|
||||
pops->_read32 = &spi_read32;
|
||||
|
||||
pops->_write8 = &spi_write8;
|
||||
pops->_write16 = &spi_write16;
|
||||
pops->_write32 = &spi_write32;
|
||||
|
||||
pops->read_rx_fifo = &spi_read_rx_fifo;
|
||||
pops->write_tx_fifo = &spi_write_tx_fifo;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 _GSPI_ISR_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
|
||||
extern struct recv_buf* rtw_recv_rxfifo(_adapter * padapter, u32 size, struct fifo_more_data* more_data);
|
||||
u8 spi_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err);
|
||||
u16 spi_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err);
|
||||
u32 spi_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err);
|
||||
s32 spi_write8(struct dvobj_priv *pdvobj, u32 addr, u8 buf, s32 *err);
|
||||
s32 spi_write16(struct dvobj_priv *pdvobj, u32 addr, u16 buf, s32 *err);
|
||||
s32 spi_write32(struct dvobj_priv *pdvobj, u32 addr, u32 buf, s32 *err);
|
||||
|
||||
void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr)
|
||||
{
|
||||
struct dvobj_priv *pdvobj = padapter->dvobj;
|
||||
|
||||
#ifdef CONFIG_LPS_LCLK
|
||||
if (sdio_hisr & HCI_HISR_CPWM1)
|
||||
{
|
||||
struct reportpwrstate_parm report;
|
||||
|
||||
report.state = spi_read8(pdvobj, LOCAL_REG_HCPWM1, NULL);
|
||||
if(report.state == 0xEA)
|
||||
report.state = PS_STATE_S0;
|
||||
else
|
||||
report.state = PS_STATE_S2;
|
||||
cpwm_int_hdl(padapter, &report);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sdio_hisr & HCI_HISR_TXERR)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
status = rtw_read32(padapter, REG_TXDMA_STATUS);
|
||||
rtw_write32(padapter, REG_TXDMA_STATUS, status);
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, status));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN
|
||||
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
|
||||
if (sdio_hisr & HCI_HISR_BCNERLY_INT)
|
||||
#endif
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
|
||||
if (sdio_hisr & (HCI_HISR_TXBCNOK|HCI_HISR_TXBCNERR))
|
||||
#endif
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
#if 0 //for debug
|
||||
if (sdio_hisr & SDIO_HISR_BCNERLY_INT)
|
||||
DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__);
|
||||
|
||||
if (sdio_hisr & SDIO_HISR_TXBCNOK)
|
||||
DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
|
||||
|
||||
if (sdio_hisr & SDIO_HISR_TXBCNERR) {
|
||||
u1Byte v422, v550, v419;
|
||||
v422 = rtw_read8(padapter, 0x422);
|
||||
v419 = rtw_read8(padapter, 0x419);
|
||||
v550 = rtw_read8(padapter, 0x550);
|
||||
|
||||
DBG_8192C("%s: SDIO_HISR_TXBCNERR 422=%02x, 419=%02x, 550=%02x\n", __func__, v422, v419, v550);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0//def 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
|
||||
|
||||
if (sdio_hisr & HCI_HISR_C2HCMD)
|
||||
{
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: C2H Command\n", __func__));
|
||||
//TODO
|
||||
// rtw_c2h_wk_cmd(padapter);
|
||||
}
|
||||
|
||||
if (sdio_hisr & HCI_HISR_RX_REQUEST)// || sdio_hisr & SPI_HISR_RXFOVW)
|
||||
{
|
||||
struct recv_buf *precvbuf;
|
||||
struct fifo_more_data more_data = {0};
|
||||
|
||||
//RT_TRACE(_module_hci_ops_c_,_drv_info_, ("%s: RX Request, size=%d\n", __func__, pdvobj->SdioRxFIFOSize));
|
||||
|
||||
sdio_hisr ^= HCI_HISR_RX_REQUEST;
|
||||
|
||||
do {
|
||||
more_data.more_data = 0;
|
||||
more_data.len = 0;
|
||||
|
||||
if (pdvobj->SdioRxFIFOSize == 0)
|
||||
{
|
||||
u16 val = 0;
|
||||
s32 ret;
|
||||
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize));
|
||||
|
||||
val = spi_read16(pdvobj, LOCAL_REG_RX0_REQ_LEN_1_BYTE, &ret);
|
||||
if (!ret) {
|
||||
pdvobj->SdioRxFIFOSize = val;
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize again size=%d\n", __func__, pdvobj->SdioRxFIFOSize));
|
||||
} else {
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize ERROR!!\n", __func__));
|
||||
}
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize));
|
||||
}
|
||||
|
||||
if (pdvobj->SdioRxFIFOSize != 0)
|
||||
{
|
||||
#ifdef RTL8723A_SDIO_LOOPBACK
|
||||
sd_recv_loopback(padapter, pdvobj->SdioRxFIFOSize);
|
||||
#else
|
||||
if (sdio_hisr & HCI_HISR_RXFOVW)
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s RXFOVW RX\n", __func__));
|
||||
|
||||
precvbuf = rtw_recv_rxfifo(padapter, pdvobj->SdioRxFIFOSize, &more_data);
|
||||
if (precvbuf)
|
||||
rtw_rxhandler(padapter, precvbuf);
|
||||
|
||||
if (more_data.more_data) {
|
||||
pdvobj->SdioRxFIFOSize = more_data.len;
|
||||
} else {
|
||||
pdvobj->SdioRxFIFOSize = 0;
|
||||
}
|
||||
#endif
|
||||
//If Rx_request ISR is set, execute receive tasklet (sdio_hisr & SPI_HISR_RX_REQUEST)
|
||||
#if defined(CONFIG_ISR_THREAD_MODE_INTERRUPT) && defined(CONFIG_RECV_TASKLET_THREAD)
|
||||
rtw_wakeup_task(&padapter->recvtasklet_thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN
|
||||
{
|
||||
//Prevent BCN update not realtime in ap mode - Alex Fang
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
if((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) && (pmlmepriv->update_bcn == _TRUE))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
} while (more_data.more_data);
|
||||
#ifdef PLATFORM_LINUX
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
tasklet_schedule(&padapter->recvpriv.recv_tasklet);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void spi_int_hdl(PADAPTER padapter)
|
||||
{
|
||||
struct dvobj_priv *pdvobj = padapter->dvobj;
|
||||
u32 sdio_hisr = 0;
|
||||
s32 ret;
|
||||
|
||||
if ((padapter->bDriverStopped == _TRUE) ||
|
||||
(padapter->bSurpriseRemoved == _TRUE))
|
||||
return;
|
||||
|
||||
sdio_hisr = spi_read32(pdvobj, LOCAL_REG_HISR, &ret);
|
||||
if (!ret) {
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SDIO_REG_HISR FAIL!!\n", __func__));
|
||||
return;
|
||||
}
|
||||
pdvobj->SdioRxFIFOSize = spi_read16(pdvobj, LOCAL_REG_RX0_REQ_LEN_1_BYTE, &ret);
|
||||
|
||||
if (!ret) {
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SPI_REG_RX0_REQ_LEN FAIL!!\n", __func__));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sdio_hisr & pdvobj->sdio_himr)
|
||||
{
|
||||
u32 v32;
|
||||
|
||||
sdio_hisr &= pdvobj->sdio_himr;
|
||||
|
||||
// clear HISR
|
||||
v32 = sdio_hisr & MASK_SPI_HISR_CLEAR;
|
||||
if (v32) {
|
||||
spi_write32(pdvobj, LOCAL_REG_HISR, v32, &ret);
|
||||
}
|
||||
|
||||
spi_int_dpc(padapter, sdio_hisr);
|
||||
} else {
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_err_,
|
||||
("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
|
||||
__FUNCTION__, sdio_hisr, pdvobj->sdio_himr));
|
||||
if(sdio_hisr)
|
||||
spi_write32(pdvobj, LOCAL_REG_HISR, sdio_hisr, &ret);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __GSPI_SPEC_H__
|
||||
#define __GSPI_SPEC_H__
|
||||
|
||||
|
||||
#define SPI_LOCAL_DOMAIN 0x0
|
||||
#define WLAN_IOREG_DOMAIN 0x8
|
||||
#define FW_FIFO_DOMAIN 0x4
|
||||
#define TX_HIQ_DOMAIN 0xc
|
||||
#define TX_MIQ_DOMAIN 0xd
|
||||
#define TX_LOQ_DOMAIN 0xe
|
||||
#define RX_RXFIFO_DOMAIN 0x1f
|
||||
|
||||
//IO Bus domain address mapping
|
||||
#define DEFUALT_OFFSET 0x0
|
||||
#define LOCAL_OFFSET 0x10250000
|
||||
#define SPI_LOCAL_OFFSET 0x10250000
|
||||
#define WLAN_IOREG_OFFSET 0x10260000
|
||||
#define FW_FIFO_OFFSET 0x10270000
|
||||
#define TX_HIQ_OFFSET 0x10310000
|
||||
#define TX_MIQ_OFFSET 0x1032000
|
||||
#define TX_LOQ_OFFSET 0x10330000
|
||||
#define RX_RXOFF_OFFSET 0x10340000
|
||||
|
||||
#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13]
|
||||
#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13]
|
||||
#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13]
|
||||
#define WLAN_TX_EXQ_DEVICE_ID 3 // 0b[16], 011b[15:13]
|
||||
#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13]
|
||||
#define WLAN_IOREG_DEVICE_ID 8 // 1b[16]
|
||||
|
||||
//SPI Tx Free Page Index
|
||||
#define HI_QUEUE_IDX 0
|
||||
#define MID_QUEUE_IDX 1
|
||||
#define LOW_QUEUE_IDX 2
|
||||
#define PUBLIC_QUEUE_IDX 3
|
||||
|
||||
#define MAX_TX_QUEUE 3 // HIQ, MIQ and LOQ
|
||||
#define MAX_RX_QUEUE 1
|
||||
|
||||
//SPI Local registers
|
||||
#ifdef CONFIG_RTL8188F
|
||||
#define SPI_REG_TX_CTRL 0x0000 // SPI Tx Control
|
||||
#define SPI_REG_STATUS_RECOVERY 0x0004
|
||||
#define SPI_REG_INT_TIMEOUT 0x0006
|
||||
#define SPI_REG_HIMR 0x0014 // SPI Host Interrupt Mask
|
||||
#define SPI_REG_HISR 0x0018 // SPI Host Interrupt Service Routine
|
||||
#define SPI_REG_RX0_REQ_LEN 0x001C // RXDMA Request Length
|
||||
#define SPI_REG_FREE_TXPG 0x0020 // Free Tx Buffer Page
|
||||
#define SPI_REG_HTSFR_INFO 0x0030 // HTSF Informaion
|
||||
#define SPI_REG_HCPWM1 0x0038 // HCI Current Power Mode 1
|
||||
#define SPI_REG_HCPWM2 0x003A // HCI Current Power Mode 2
|
||||
#define SPI_REG_HRPWM1 0x0080 // HCI Request Power Mode 1 need check for 8188f???
|
||||
#define SPI_REG_HPS_CLKR 0x0084 // HCI Power Save Clock
|
||||
#define SPI_REG_HSUS_CTRL 0x0086 // SPI HCI Suspend Control
|
||||
#else
|
||||
#define SPI_REG_TX_CTRL 0x0000 // SPI Tx Control
|
||||
#define SPI_REG_STATUS_RECOVERY 0x0004
|
||||
#define SPI_REG_INT_TIMEOUT 0x0006
|
||||
#define SPI_REG_HIMR 0x0014 // SPI Host Interrupt Mask
|
||||
#define SPI_REG_HISR 0x0018 // SPI Host Interrupt Service Routine
|
||||
#define SPI_REG_RX0_REQ_LEN 0x001C // RXDMA Request Length
|
||||
#define SPI_REG_FREE_TXPG 0x0020 // Free Tx Buffer Page
|
||||
#define SPI_REG_HCPWM1 0x0024 // HCI Current Power Mode 1
|
||||
#define SPI_REG_HCPWM2 0x0026 // HCI Current Power Mode 2
|
||||
#define SPI_REG_HTSFR_INFO 0x0030 // HTSF Informaion
|
||||
#define SPI_REG_HRPWM1 0x0080 // HCI Request Power Mode 1
|
||||
#define SPI_REG_HRPWM2 0x0082 // HCI Request Power Mode 2
|
||||
#define SPI_REG_HPS_CLKR 0x0084 // HCI Power Save Clock
|
||||
#define SPI_REG_HSUS_CTRL 0x0086 // SPI HCI Suspend Control
|
||||
#define SPI_REG_HIMR_ON 0x0090 //SPI Host Extension Interrupt Mask Always
|
||||
#define SPI_REG_HISR_ON 0x0091 //SPI Host Extension Interrupt Status Always
|
||||
#define SPI_REG_CFG 0x00F0 //SPI Configuration Register
|
||||
#endif
|
||||
|
||||
#define LOCAL_REG_TX_CTRL (SPI_REG_TX_CTRL |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_STATUS_RECOVERY (SPI_REG_STATUS_RECOVERY |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_INT_TIMEOUT (SPI_REG_INT_TIMEOUT |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HIMR (SPI_REG_HIMR |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HISR (SPI_REG_HISR |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_RX0_REQ_LEN_1_BYTE (SPI_REG_RX0_REQ_LEN |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_FREE_TXPG (SPI_REG_FREE_TXPG |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HRPWM1 (SPI_REG_HRPWM1 |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HCPWM1 (SPI_REG_HCPWM1 |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_SUSPEND_NORMAL (SPI_REG_HSUS_CTRL|SPI_LOCAL_OFFSET)
|
||||
#define HCI_HIMR_DISABLED 0
|
||||
|
||||
//SPI HIMR MASK diff with SDIO
|
||||
#ifdef CONFIG_RTL8188F
|
||||
#define HCI_HISR_RX_REQUEST BIT(0)
|
||||
#define HCI_HISR_AVAL BIT(1)
|
||||
#define HCI_HISR_TXERR BIT(2)
|
||||
#define HCI_HISR_RXERR BIT(3)
|
||||
#define HCI_HISR_TXFOVW BIT(4)
|
||||
#define HCI_HISR_RXFOVW BIT(5)
|
||||
#define HCI_HISR_TXBCNOK BIT(6)
|
||||
#define HCI_HISR_TXBCNERR BIT(7)
|
||||
#define HCI_HISR_BCNERLY_INT BIT(16)
|
||||
#define HCI_HISR_C2HCMD BIT(17)
|
||||
#define HCI_HISR_CPWM1 BIT(18)
|
||||
#define HCI_HISR_CPWM2 BIT(19)
|
||||
#define HCI_HISR_HSISR_IND BIT(20)
|
||||
#define HCI_HISR_GTINT3_IND BIT(21)
|
||||
#define HCI_HISR_GTINT4_IND BIT(22)
|
||||
#define HCI_HISR_PSTIMEOUT BIT(23)
|
||||
#define HCI_HISR_OCPINT BIT(24)
|
||||
#define HCI_HISR_ATIMEND BIT(25)
|
||||
#define HCI_HISR_ATIMEND_E BIT(26)
|
||||
#define HCI_HISR_CTWEND BIT(27)
|
||||
#define HCI_HISR_TSF_BIT32_TOGGLE BIT(29)
|
||||
#define HCI_HISR_PSTIMEOUT_E BIT(30)
|
||||
//SPI HIMR MASK diff with SDIO
|
||||
#define HCI_HIMR_RX_REQUEST BIT(0)
|
||||
#define HCI_HIMR_AVAL BIT(1)
|
||||
#define HCI_HIMR_TXERR BIT(2)
|
||||
#define HCI_HIMR_RXERR BIT(3)
|
||||
#define HCI_HIMR_TXFOVW BIT(4)
|
||||
#define HCI_HIMR_RXFOVW BIT(5)
|
||||
#define HCI_HIMR_TXBCNOK BIT(6)
|
||||
#define HCI_HIMR_TXBCNERR BIT(7)
|
||||
#define HCI_HIMR_BCNERLY_INT BIT(16)
|
||||
#define HCI_HIMR_C2HCMD BIT(17)
|
||||
#define HCI_HIMR_CPWM1 BIT(18)
|
||||
#define HCI_HIMR_CPWM2 BIT(19)
|
||||
#define HCI_HIMR_HSISR_IND BIT(20)
|
||||
#define HCI_HIMR_GTINT3_IND BIT(21)
|
||||
#define HCI_HIMR_GTINT4_IND BIT(22)
|
||||
#define HCI_HIMR_PSTIMEOUT BIT(23)
|
||||
#define HCI_HIMR_OCPINT BIT(24)
|
||||
#define HCI_HIMR_ATIMEND BIT(25)
|
||||
#define HCI_HIMR_ATIMEND_E BIT(26)
|
||||
#define HCI_HIMR_CTWEND BIT(27)
|
||||
#define HCI_HIMR_TSF_BIT32_TOGGLE BIT(29)
|
||||
#define HCI_HIMR_PSTIMEOUT_E BIT(30)
|
||||
#else
|
||||
#define HCI_HISR_RX_REQUEST BIT(0)
|
||||
#define HCI_HISR_AVAL BIT(1)
|
||||
#define HCI_HISR_TXERR BIT(2)
|
||||
#define HCI_HISR_RXERR BIT(3)
|
||||
#define HCI_HISR_TXFOVW BIT(4)
|
||||
#define HCI_HISR_RXFOVW BIT(5)
|
||||
#define HCI_HISR_TXBCNOK BIT(6)
|
||||
#define HCI_HISR_TXBCNERR BIT(7)
|
||||
#define HCI_HISR_BCNERLY_INT BIT(16)
|
||||
#define HCI_HISR_ATIMEND BIT(17)
|
||||
#define HCI_HISR_ATIMEND_E BIT(18)
|
||||
#define HCI_HISR_CTWEND BIT(19)
|
||||
#define HCI_HISR_C2HCMD BIT(20)
|
||||
#define HCI_HISR_CPWM1 BIT(21)
|
||||
#define HCI_HISR_CPWM2 BIT(22)
|
||||
#define HCI_HISR_HSISR_IND BIT(23)
|
||||
#define HCI_HISR_GTINT3_IND BIT(24)
|
||||
#define HCI_HISR_GTINT4_IND BIT(25)
|
||||
#define HCI_HISR_PSTIMEOUT BIT(26)
|
||||
#define HCI_HISR_OCPINT BIT(27)
|
||||
#define HCI_HISR_TSF_BIT32_TOGGLE BIT(29)
|
||||
//SPI HIMR MASK diff with SDIO
|
||||
#define HCI_HIMR_RX_REQUEST BIT(0)
|
||||
#define HCI_HIMR_AVAL BIT(1)
|
||||
#define HCI_HIMR_TXERR BIT(2)
|
||||
#define HCI_HIMR_RXERR BIT(3)
|
||||
#define HCI_HIMR_TXFOVW BIT(4)
|
||||
#define HCI_HIMR_RXFOVW BIT(5)
|
||||
#define HCI_HIMR_TXBCNOK BIT(6)
|
||||
#define HCI_HIMR_TXBCNERR BIT(7)
|
||||
#define HCI_HIMR_BCNERLY_INT BIT(16)
|
||||
#define HCI_HIMR_ATIMEND BIT(17)
|
||||
#define HCI_HIMR_ATIMEND_E BIT(18)
|
||||
#define HCI_HIMR_CTWEND BIT(19)
|
||||
#define HCI_HIMR_C2HCMD BIT(20)
|
||||
#define HCI_HIMR_CPWM1 BIT(21)
|
||||
#define HCI_HIMR_CPWM2 BIT(22)
|
||||
#define HCI_HIMR_HSISR_IND BIT(23)
|
||||
#define HCI_HIMR_GTINT3_IND BIT(24)
|
||||
#define HCI_HIMR_GTINT4_IND BIT(25)
|
||||
#define HCI_HIMR_PSTIMEOUT BIT(26)
|
||||
#define HCI_HIMR_OCPINT BIT(27)
|
||||
#define HCI_HIMR_TSF_BIT32_TOGGLE BIT(29)
|
||||
#endif
|
||||
#define MASK_SPI_HISR_CLEAR (HCI_HIMR_TXERR |\
|
||||
HCI_HIMR_RXERR |\
|
||||
HCI_HIMR_TXFOVW |\
|
||||
HCI_HIMR_RXFOVW |\
|
||||
HCI_HIMR_TXBCNOK |\
|
||||
HCI_HIMR_TXBCNERR |\
|
||||
HCI_HIMR_C2HCMD |\
|
||||
HCI_HIMR_CPWM1 |\
|
||||
HCI_HIMR_CPWM2 |\
|
||||
HCI_HIMR_HSISR_IND |\
|
||||
HCI_HIMR_GTINT3_IND |\
|
||||
HCI_HIMR_GTINT4_IND |\
|
||||
HCI_HIMR_PSTIMEOUT |\
|
||||
HCI_HIMR_OCPINT)
|
||||
|
||||
#define REG_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 8, x)//(x<<(unsigned int)24)
|
||||
#define REG_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16)
|
||||
#define REG_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0)
|
||||
#define REG_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5)
|
||||
#define REG_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7)
|
||||
|
||||
#define FIFO_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 16, x)//(x<<(unsigned int)24)
|
||||
//#define FIFO_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16)
|
||||
#define FIFO_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0)
|
||||
#define FIFO_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5)
|
||||
#define FIFO_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7)
|
||||
|
||||
|
||||
//get status dword0
|
||||
#define GET_STATUS_PUB_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 24, 8)
|
||||
#define GET_STATUS_HI_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 18, 6)
|
||||
#define GET_STATUS_MID_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 12, 6)
|
||||
#define GET_STATUS_LOW_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 6, 6)
|
||||
#define GET_STATUS_HISR_HI6BIT(status) LE_BITS_TO_4BYTE(status, 0, 6)
|
||||
|
||||
//get status dword1
|
||||
#define GET_STATUS_HISR_MID8BIT(status) LE_BITS_TO_4BYTE(status + 4, 24, 8)
|
||||
#define GET_STATUS_HISR_LOW8BIT(status) LE_BITS_TO_4BYTE(status + 4, 16, 8)
|
||||
#define GET_STATUS_ERROR(status) LE_BITS_TO_4BYTE(status + 4, 17, 1)
|
||||
#define GET_STATUS_INT(status) LE_BITS_TO_4BYTE(status + 4, 16, 1)
|
||||
#define GET_STATUS_RX_LENGTH(status) LE_BITS_TO_4BYTE(status + 4, 0, 16)
|
||||
|
||||
|
||||
#define RXDESC_SIZE 24
|
||||
|
||||
#define TX_FREE_PG_QUEUE 4 // The number of Tx FIFO free page
|
||||
#define TX_FIFO_PAGE_SZ 128
|
||||
|
||||
struct spi_more_data {
|
||||
unsigned long more_data;
|
||||
unsigned long len;
|
||||
};
|
||||
|
||||
extern BUS_DRV_OPS_T bus_driver_ops;
|
||||
|
||||
extern u8 spi_query_status_info(struct dvobj_priv *pdvobj);
|
||||
|
||||
extern void spi_set_intf_ops(struct _io_ops *pops);
|
||||
|
||||
#endif //__GSPI_SPEC_H__
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef _HCI_INTFS_H_
|
||||
#define _HCI_INTFS_H_
|
||||
|
||||
#include <autoconf.h>
|
||||
|
||||
struct host_ctrl_intf_ops
|
||||
{
|
||||
struct dvobj_priv * (*dvobj_init)(void);
|
||||
void (*dvobj_deinit)(struct dvobj_priv *dvobj);
|
||||
void (*dvobj_request_irq)(struct dvobj_priv *dvobj);
|
||||
void (*dvobj_free_irq)(struct dvobj_priv *dvobj);
|
||||
};
|
||||
|
||||
extern struct dvobj_priv *hci_dvobj_init(void);
|
||||
extern void hci_dvobj_deinit(struct dvobj_priv *dvobj);
|
||||
extern void hci_dvobj_request_irq(struct dvobj_priv *dvobj);
|
||||
extern void hci_dvobj_free_irq(struct dvobj_priv *dvobj);
|
||||
|
||||
#if defined(CONFIG_GSPI_HCI)
|
||||
#define hci_bus_intf_type RTW_GSPI
|
||||
#define hci_set_intf_ops spi_set_intf_ops
|
||||
#define hci_intf_start rtw_hal_enable_interrupt
|
||||
#define hci_intf_stop rtw_hal_disable_interrupt
|
||||
extern s32 gspi_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe);
|
||||
extern s32 gspi_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SDIO_HCI)
|
||||
#define hci_bus_intf_type RTW_SDIO
|
||||
#define hci_set_intf_ops sdio_set_intf_ops
|
||||
#define hci_intf_start rtw_hal_enable_interrupt
|
||||
#define hci_intf_stop rtw_hal_disable_interrupt
|
||||
extern s32 sdio_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe);
|
||||
extern s32 sdio_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_LX_HCI)
|
||||
#define hci_bus_intf_type RTW_LXBUS
|
||||
#define hci_set_intf_ops lxbus_set_intf_ops
|
||||
#define hci_intf_start rtw_hal_enable_interrupt
|
||||
#define hci_intf_stop hci_lxbus_intf_stop
|
||||
void hci_lxbus_intf_stop(_adapter *padapter);
|
||||
u32 lextra_bus_dma_Interrupt (void* data);
|
||||
#endif
|
||||
|
||||
|
||||
#endif //_HCI_INTFS_H_
|
||||
|
||||
433
sdk/component/common/drivers/wlan/realtek/src/hci/hci_spec.h
Normal file
433
sdk/component/common/drivers/wlan/realtek/src/hci/hci_spec.h
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __HCI_SPEC_H__
|
||||
#define __HCI_SPEC_H__
|
||||
|
||||
|
||||
#if defined(CONFIG_GSPI_HCI)
|
||||
#include "gspi/gspi_spec.h"
|
||||
|
||||
// SPI Header Files
|
||||
#ifdef PLATFORM_LINUX
|
||||
#include <linux/spi/spi.h>
|
||||
#endif
|
||||
|
||||
#define GSPI_CMD_LEN 4
|
||||
#define HAL_INTERFACE_CMD_LEN GSPI_CMD_LEN
|
||||
#define GSPI_STATUS_LEN 8
|
||||
#define HAL_INTERFACE_CMD_STATUS_LEN GSPI_STATUS_LEN
|
||||
#define HAL_INTERFACE_OVERHEAD (HAL_INTERFACE_CMD_LEN+HAL_INTERFACE_OVERHEAD)
|
||||
//reserve tx headroom in case of softap forwarding unicase packet
|
||||
#define RX_RESERV_HEADROOM (SKB_WLAN_TX_EXTRA_LEN>RX_DRIVER_INFO+RXDESC_SIZE)?(SKB_WLAN_TX_EXTRA_LEN-RX_DRIVER_INFO-RXDESC_SIZE):0
|
||||
typedef struct gspi_data
|
||||
{
|
||||
//u8 func_number;
|
||||
|
||||
//u8 tx_block_mode;
|
||||
//u8 rx_block_mode;
|
||||
u16 block_transfer_len; //u32 block_transfer_len;
|
||||
|
||||
#ifdef PLATFORM_LINUX
|
||||
struct spi_device *func;
|
||||
|
||||
struct workqueue_struct *priv_wq;
|
||||
struct delayed_work irq_work;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS)
|
||||
_mutex spi_mutex;
|
||||
#endif
|
||||
} GSPI_DATA, *PGSPI_DATA;
|
||||
|
||||
#define INTF_DATA GSPI_DATA
|
||||
|
||||
//extern void spi_set_intf_ops(struct _io_ops *pops);
|
||||
extern void spi_int_hdl(PADAPTER padapter);
|
||||
#define rtw_hci_interrupt_handler(__adapter) spi_int_hdl(__adapter)
|
||||
|
||||
#elif defined(CONFIG_SDIO_HCI)
|
||||
#include "sdio/sdio_spec.h"
|
||||
|
||||
#define GSPI_CMD_LEN 0
|
||||
#define HAL_INTERFACE_CMD_LEN GSPI_CMD_LEN
|
||||
#define GSPI_STATUS_LEN 8
|
||||
#define HAL_INTERFACE_CMD_STATUS_LEN GSPI_STATUS_LEN
|
||||
#define HAL_INTERFACE_OVERHEAD (HAL_INTERFACE_CMD_LEN+HAL_INTERFACE_OVERHEAD)
|
||||
#define RX_RESERV_HEADROOM (SKB_WLAN_TX_EXTRA_LEN>RX_DRIVER_INFO+RXDESC_SIZE)?(SKB_WLAN_TX_EXTRA_LEN-RX_DRIVER_INFO-RXDESC_SIZE):0
|
||||
|
||||
typedef struct gspi_data
|
||||
{
|
||||
//u8 func_number;
|
||||
|
||||
//u8 tx_block_mode;
|
||||
//u8 rx_block_mode;
|
||||
u16 block_transfer_len; //u32 block_transfer_len;
|
||||
|
||||
#ifdef PLATFORM_LINUX
|
||||
struct spi_device *func;
|
||||
|
||||
struct workqueue_struct *priv_wq;
|
||||
struct delayed_work irq_work;
|
||||
#endif
|
||||
|
||||
struct sdio_func *func;
|
||||
|
||||
#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS)
|
||||
_mutex spi_mutex;
|
||||
#endif
|
||||
} GSPI_DATA, *PGSPI_DATA;
|
||||
|
||||
#define INTF_DATA GSPI_DATA
|
||||
|
||||
//extern void spi_set_intf_ops(struct _io_ops *pops);
|
||||
extern void spi_int_hdl(PADAPTER padapter);
|
||||
#define rtw_hci_interrupt_handler(__adapter) spi_int_hdl(__adapter)
|
||||
|
||||
#elif defined(CONFIG_USB_HCI)
|
||||
#include <usb_ops.h>
|
||||
#include <usb_osintf.h>
|
||||
|
||||
#elif defined(CONFIG_PCI_HCI)
|
||||
#include <pci_osintf.h>
|
||||
#ifdef PLATFORM_LINUX
|
||||
#include <linux/pci.h>
|
||||
#endif
|
||||
|
||||
#define INTF_CMD_LEN 0
|
||||
|
||||
#define INTEL_VENDOR_ID 0x8086
|
||||
#define SIS_VENDOR_ID 0x1039
|
||||
#define ATI_VENDOR_ID 0x1002
|
||||
#define ATI_DEVICE_ID 0x7914
|
||||
#define AMD_VENDOR_ID 0x1022
|
||||
|
||||
#define PCI_MAX_BRIDGE_NUMBER 255
|
||||
#define PCI_MAX_DEVICES 32
|
||||
#define PCI_MAX_FUNCTION 8
|
||||
|
||||
#define PCI_CONF_ADDRESS 0x0CF8 // PCI Configuration Space Address
|
||||
#define PCI_CONF_DATA 0x0CFC // PCI Configuration Space Data
|
||||
|
||||
#define PCI_CLASS_BRIDGE_DEV 0x06
|
||||
#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
|
||||
|
||||
#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
|
||||
|
||||
#define U1DONTCARE 0xFF
|
||||
#define U2DONTCARE 0xFFFF
|
||||
#define U4DONTCARE 0xFFFFFFFF
|
||||
|
||||
#define PCI_VENDER_ID_REALTEK 0x10ec
|
||||
|
||||
#define HAL_HW_PCI_8180_DEVICE_ID 0x8180
|
||||
#define HAL_HW_PCI_8185_DEVICE_ID 0x8185 //8185 or 8185b
|
||||
#define HAL_HW_PCI_8188_DEVICE_ID 0x8188 //8185b
|
||||
#define HAL_HW_PCI_8198_DEVICE_ID 0x8198 //8185b
|
||||
#define HAL_HW_PCI_8190_DEVICE_ID 0x8190 //8190
|
||||
#define HAL_HW_PCI_8723E_DEVICE_ID 0x8723 //8723E
|
||||
#define HAL_HW_PCI_8192_DEVICE_ID 0x8192 //8192 PCI-E
|
||||
#define HAL_HW_PCI_8192SE_DEVICE_ID 0x8192 //8192 SE
|
||||
#define HAL_HW_PCI_8174_DEVICE_ID 0x8174 //8192 SE
|
||||
#define HAL_HW_PCI_8173_DEVICE_ID 0x8173 //8191 SE Crab
|
||||
#define HAL_HW_PCI_8172_DEVICE_ID 0x8172 //8191 SE RE
|
||||
#define HAL_HW_PCI_8171_DEVICE_ID 0x8171 //8191 SE Unicron
|
||||
#define HAL_HW_PCI_0045_DEVICE_ID 0x0045 //8190 PCI for Ceraga
|
||||
#define HAL_HW_PCI_0046_DEVICE_ID 0x0046 //8190 Cardbus for Ceraga
|
||||
#define HAL_HW_PCI_0044_DEVICE_ID 0x0044 //8192e PCIE for Ceraga
|
||||
#define HAL_HW_PCI_0047_DEVICE_ID 0x0047 //8192e Express Card for Ceraga
|
||||
#define HAL_HW_PCI_700F_DEVICE_ID 0x700F
|
||||
#define HAL_HW_PCI_701F_DEVICE_ID 0x701F
|
||||
#define HAL_HW_PCI_DLINK_DEVICE_ID 0x3304
|
||||
#define HAL_HW_PCI_8192CET_DEVICE_ID 0x8191 //8192ce
|
||||
#define HAL_HW_PCI_8192CE_DEVICE_ID 0x8178 //8192ce
|
||||
#define HAL_HW_PCI_8191CE_DEVICE_ID 0x8177 //8192ce
|
||||
#define HAL_HW_PCI_8188CE_DEVICE_ID 0x8176 //8192ce
|
||||
#define HAL_HW_PCI_8192CU_DEVICE_ID 0x8191 //8192ce
|
||||
#define HAL_HW_PCI_8192DE_DEVICE_ID 0x8193 //8192de
|
||||
#define HAL_HW_PCI_002B_DEVICE_ID 0x002B //8192de, provided by HW SD
|
||||
#define HAL_HW_PCI_8188EE_DEVICE_ID 0x8179
|
||||
|
||||
#define HAL_MEMORY_MAPPED_IO_RANGE_8190PCI 0x1000 //8190 support 16 pages of IO registers
|
||||
#define HAL_HW_PCI_REVISION_ID_8190PCI 0x00
|
||||
#define HAL_MEMORY_MAPPED_IO_RANGE_8192PCIE 0x4000 //8192 support 16 pages of IO registers
|
||||
#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01
|
||||
#define HAL_MEMORY_MAPPED_IO_RANGE_8192SE 0x4000 //8192 support 16 pages of IO registers
|
||||
#define HAL_HW_PCI_REVISION_ID_8192SE 0x10
|
||||
#define HAL_HW_PCI_REVISION_ID_8192CE 0x1
|
||||
#define HAL_MEMORY_MAPPED_IO_RANGE_8192CE 0x4000 //8192 support 16 pages of IO registers
|
||||
#define HAL_HW_PCI_REVISION_ID_8192DE 0x0
|
||||
#define HAL_MEMORY_MAPPED_IO_RANGE_8192DE 0x4000 //8192 support 16 pages of IO registers
|
||||
|
||||
enum pci_bridge_vendor {
|
||||
PCI_BRIDGE_VENDOR_INTEL = 0x0,//0b'0000,0001
|
||||
PCI_BRIDGE_VENDOR_ATI, //= 0x02,//0b'0000,0010
|
||||
PCI_BRIDGE_VENDOR_AMD, //= 0x04,//0b'0000,0100
|
||||
PCI_BRIDGE_VENDOR_SIS ,//= 0x08,//0b'0000,1000
|
||||
PCI_BRIDGE_VENDOR_UNKNOWN, //= 0x40,//0b'0100,0000
|
||||
PCI_BRIDGE_VENDOR_MAX ,//= 0x80
|
||||
} ;
|
||||
|
||||
// copy this data structor defination from MSDN SDK
|
||||
typedef struct _PCI_COMMON_CONFIG {
|
||||
u16 VendorID;
|
||||
u16 DeviceID;
|
||||
u16 Command;
|
||||
u16 Status;
|
||||
u8 RevisionID;
|
||||
u8 ProgIf;
|
||||
u8 SubClass;
|
||||
u8 BaseClass;
|
||||
u8 CacheLineSize;
|
||||
u8 LatencyTimer;
|
||||
u8 HeaderType;
|
||||
u8 BIST;
|
||||
|
||||
union {
|
||||
struct _PCI_HEADER_TYPE_0 {
|
||||
u32 BaseAddresses[6];
|
||||
u32 CIS;
|
||||
u16 SubVendorID;
|
||||
u16 SubSystemID;
|
||||
u32 ROMBaseAddress;
|
||||
u8 CapabilitiesPtr;
|
||||
u8 Reserved1[3];
|
||||
u32 Reserved2;
|
||||
|
||||
u8 InterruptLine;
|
||||
u8 InterruptPin;
|
||||
u8 MinimumGrant;
|
||||
u8 MaximumLatency;
|
||||
} type0;
|
||||
#if 0
|
||||
struct _PCI_HEADER_TYPE_1 {
|
||||
u32 BaseAddresses[PCI_TYPE1_ADDRESSES];
|
||||
u8 PrimaryBusNumber;
|
||||
u8 SecondaryBusNumber;
|
||||
u8 SubordinateBusNumber;
|
||||
u8 SecondaryLatencyTimer;
|
||||
u8 IOBase;
|
||||
u8 IOLimit;
|
||||
u16 SecondaryStatus;
|
||||
u16 MemoryBase;
|
||||
u16 MemoryLimit;
|
||||
u16 PrefetchableMemoryBase;
|
||||
u16 PrefetchableMemoryLimit;
|
||||
u32 PrefetchableMemoryBaseUpper32;
|
||||
u32 PrefetchableMemoryLimitUpper32;
|
||||
u16 IOBaseUpper;
|
||||
u16 IOLimitUpper;
|
||||
u32 Reserved2;
|
||||
u32 ExpansionROMBase;
|
||||
u8 InterruptLine;
|
||||
u8 InterruptPin;
|
||||
u16 BridgeControl;
|
||||
} type1;
|
||||
|
||||
struct _PCI_HEADER_TYPE_2 {
|
||||
u32 BaseAddress;
|
||||
u8 CapabilitiesPtr;
|
||||
u8 Reserved2;
|
||||
u16 SecondaryStatus;
|
||||
u8 PrimaryBusNumber;
|
||||
u8 CardbusBusNumber;
|
||||
u8 SubordinateBusNumber;
|
||||
u8 CardbusLatencyTimer;
|
||||
u32 MemoryBase0;
|
||||
u32 MemoryLimit0;
|
||||
u32 MemoryBase1;
|
||||
u32 MemoryLimit1;
|
||||
u16 IOBase0_LO;
|
||||
u16 IOBase0_HI;
|
||||
u16 IOLimit0_LO;
|
||||
u16 IOLimit0_HI;
|
||||
u16 IOBase1_LO;
|
||||
u16 IOBase1_HI;
|
||||
u16 IOLimit1_LO;
|
||||
u16 IOLimit1_HI;
|
||||
u8 InterruptLine;
|
||||
u8 InterruptPin;
|
||||
u16 BridgeControl;
|
||||
u16 SubVendorID;
|
||||
u16 SubSystemID;
|
||||
u32 LegacyBaseAddress;
|
||||
u8 Reserved3[56];
|
||||
u32 SystemControl;
|
||||
u8 MultiMediaControl;
|
||||
u8 GeneralStatus;
|
||||
u8 Reserved4[2];
|
||||
u8 GPIO0Control;
|
||||
u8 GPIO1Control;
|
||||
u8 GPIO2Control;
|
||||
u8 GPIO3Control;
|
||||
u32 IRQMuxRouting;
|
||||
u8 RetryStatus;
|
||||
u8 CardControl;
|
||||
u8 DeviceControl;
|
||||
u8 Diagnostic;
|
||||
} type2;
|
||||
#endif
|
||||
} u;
|
||||
|
||||
u8 DeviceSpecific[108];
|
||||
} PCI_COMMON_CONFIG , *PPCI_COMMON_CONFIG;
|
||||
|
||||
typedef struct _RT_PCI_CAPABILITIES_HEADER {
|
||||
u8 CapabilityID;
|
||||
u8 Next;
|
||||
} RT_PCI_CAPABILITIES_HEADER, *PRT_PCI_CAPABILITIES_HEADER;
|
||||
|
||||
struct pci_priv{
|
||||
BOOLEAN pci_clk_req;
|
||||
|
||||
u8 pciehdr_offset;
|
||||
// PCIeCap is only differece between B-cut and C-cut.
|
||||
// Configuration Space offset 72[7:4]
|
||||
// 0: A/B cut
|
||||
// 1: C cut and later.
|
||||
u8 pcie_cap;
|
||||
u8 linkctrl_reg;
|
||||
|
||||
u8 busnumber;
|
||||
u8 devnumber;
|
||||
u8 funcnumber;
|
||||
|
||||
u8 pcibridge_busnum;
|
||||
u8 pcibridge_devnum;
|
||||
u8 pcibridge_funcnum;
|
||||
u8 pcibridge_vendor;
|
||||
u16 pcibridge_vendorid;
|
||||
u16 pcibridge_deviceid;
|
||||
u8 pcibridge_pciehdr_offset;
|
||||
u8 pcibridge_linkctrlreg;
|
||||
|
||||
u8 amd_l1_patch;
|
||||
};
|
||||
|
||||
typedef struct _RT_ISR_CONTENT
|
||||
{
|
||||
union{
|
||||
u32 IntArray[2];
|
||||
u32 IntReg4Byte;
|
||||
u16 IntReg2Byte;
|
||||
};
|
||||
}RT_ISR_CONTENT, *PRT_ISR_CONTENT;
|
||||
|
||||
//#define RegAddr(addr) (addr + 0xB2000000UL)
|
||||
//some platform macros will def here
|
||||
static inline void NdisRawWritePortUlong(u32 port, u32 val)
|
||||
{
|
||||
outl(val, port);
|
||||
//writel(val, (u8 *)RegAddr(port));
|
||||
}
|
||||
|
||||
static inline void NdisRawWritePortUchar(u32 port, u8 val)
|
||||
{
|
||||
outb(val, port);
|
||||
//writeb(val, (u8 *)RegAddr(port));
|
||||
}
|
||||
|
||||
static inline void NdisRawReadPortUchar(u32 port, u8 *pval)
|
||||
{
|
||||
*pval = inb(port);
|
||||
//*pval = readb((u8 *)RegAddr(port));
|
||||
}
|
||||
|
||||
static inline void NdisRawReadPortUshort(u32 port, u16 *pval)
|
||||
{
|
||||
*pval = inw(port);
|
||||
//*pval = readw((u8 *)RegAddr(port));
|
||||
}
|
||||
|
||||
static inline void NdisRawReadPortUlong(u32 port, u32 *pval)
|
||||
{
|
||||
*pval = inl(port);
|
||||
//*pval = readl((u8 *)RegAddr(port));
|
||||
}
|
||||
#elif defined(CONFIG_LX_HCI)
|
||||
#define GSPI_CMD_LEN 0
|
||||
#define GSPI_STATUS_LEN 0
|
||||
#include "lxbus/lxbus_spec.h"
|
||||
#endif // interface define
|
||||
|
||||
#if 0 //TODO
|
||||
struct intf_priv {
|
||||
|
||||
u8 *intf_dev;
|
||||
u32 max_iosz; //USB2.0: 128, USB1.1: 64, SDIO:64
|
||||
u32 max_xmitsz; //USB2.0: unlimited, SDIO:512
|
||||
u32 max_recvsz; //USB2.0: unlimited, SDIO:512
|
||||
|
||||
volatile u8 *io_rwmem;
|
||||
volatile u8 *allocated_io_rwmem;
|
||||
u32 io_wsz; //unit: 4bytes
|
||||
u32 io_rsz;//unit: 4bytes
|
||||
u8 intf_status;
|
||||
|
||||
void (*_bus_io)(u8 *priv);
|
||||
|
||||
/*
|
||||
Under Sync. IRP (SDIO/USB)
|
||||
A protection mechanism is necessary for the io_rwmem(read/write protocol)
|
||||
|
||||
Under Async. IRP (SDIO/USB)
|
||||
The protection mechanism is through the pending queue.
|
||||
*/
|
||||
|
||||
_mutex ioctl_mutex;
|
||||
|
||||
|
||||
#ifdef PLATFORM_LINUX
|
||||
#ifdef CONFIG_USB_HCI
|
||||
// when in USB, IO is through interrupt in/out endpoints
|
||||
struct usb_device *udev;
|
||||
PURB piorw_urb;
|
||||
u8 io_irp_cnt;
|
||||
u8 bio_irp_pending;
|
||||
_sema io_retevt;
|
||||
_timer io_timer;
|
||||
u8 bio_irp_timeout;
|
||||
u8 bio_timer_cancel;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_OS_XP
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
// below is for io_rwmem...
|
||||
PMDL pmdl;
|
||||
PSDBUS_REQUEST_PACKET sdrp;
|
||||
PSDBUS_REQUEST_PACKET recv_sdrp;
|
||||
PSDBUS_REQUEST_PACKET xmit_sdrp;
|
||||
|
||||
PIRP piorw_irp;
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_USB_HCI
|
||||
PURB piorw_urb;
|
||||
PIRP piorw_irp;
|
||||
u8 io_irp_cnt;
|
||||
u8 bio_irp_pending;
|
||||
_sema io_retevt;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif
|
||||
#endif //__HCI_SPEC_H__
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __LXBUS_SPEC_H__
|
||||
#define __LXBUS_SPEC_H__
|
||||
|
||||
#include <lxbus_ops.h>
|
||||
//#include <lxbus_hal.h>
|
||||
|
||||
|
||||
#define HAL_INTERFACE_CMD_LEN 0
|
||||
#define HAL_INTERFACE_CMD_STATUS_LEN 0
|
||||
#define HAL_INTERFACE_OVERHEAD (HAL_INTERFACE_CMD_LEN+HAL_INTERFACE_CMD_STATUS_LEN)
|
||||
|
||||
/*
|
||||
* The following data structure is used for 8195a debug, and should not
|
||||
* declared this parameter in release version to save sram usage
|
||||
* It is used for debugging tx/rx and r/w pointer
|
||||
*/
|
||||
struct hal_debug
|
||||
{
|
||||
unsigned int int_count;
|
||||
unsigned int crc_err;
|
||||
u16 last_write_be;
|
||||
u16 last_write_mgt;
|
||||
u16 last_closed_be;
|
||||
u16 last_closed_mgt;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// The following section should be removed?
|
||||
#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13]
|
||||
#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13]
|
||||
#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13]
|
||||
#define SDIO_MAX_TX_QUEUE 3 // HIQ, MIQ and LOQ
|
||||
|
||||
#endif //__LXBUS_SPEC_H__
|
||||
|
|
@ -0,0 +1,818 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 _GSPI_IO_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
#include "wifi_io.h" //from sdio_host driver
|
||||
//#include <FreeRTOS.h>
|
||||
//#include <task.h>
|
||||
//#define SDIO_CMD52_IO
|
||||
|
||||
//SDIO host local register space mapping.
|
||||
#define SDIO_LOCAL_MSK 0x0FFF
|
||||
#define WLAN_IOREG_MSK 0x7FFF
|
||||
#define WLAN_FIFO_MSK 0x1FFF // Aggregation Length[12:0]
|
||||
#define WLAN_RX0FF_MSK 0x0003
|
||||
|
||||
#define SDIO_WITHOUT_REF_DEVICE_ID 0 // Without reference to the SDIO Device ID
|
||||
#define SDIO_LOCAL_DEVICE_ID 0 // 0b[16], 000b[15:13]
|
||||
#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13]
|
||||
#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13]
|
||||
#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13]
|
||||
#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13]
|
||||
#define WLAN_IOREG_DEVICE_ID 8 // 1b[16]
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
#ifdef CONFIG_RTL8188F
|
||||
u8 spi_query_status_info(struct dvobj_priv *pdvobj)
|
||||
{
|
||||
|
||||
ADAPTER *padapter = pdvobj->if1;
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG);
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG+2);
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG+4);
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG+6);
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_notice_,
|
||||
("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n",
|
||||
__FUNCTION__,
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
|
||||
//_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
#else
|
||||
u8 spi_query_status_info(struct dvobj_priv *pdvobj)
|
||||
{
|
||||
u32 NumOfFreePage;
|
||||
ADAPTER *padapter = pdvobj->if1;
|
||||
|
||||
NumOfFreePage = rtw_read32(padapter, LOCAL_REG_FREE_TXPG);
|
||||
|
||||
// _enter_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql);
|
||||
rtw_memcpy(pdvobj->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__,
|
||||
pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
|
||||
pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
|
||||
// _exit_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql);
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
#endif
|
||||
static unsigned char get_deviceid(unsigned int addr)
|
||||
{
|
||||
unsigned char devideId;
|
||||
unsigned short pseudoId;
|
||||
|
||||
|
||||
pseudoId = (unsigned short)(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;
|
||||
}
|
||||
|
||||
static unsigned int _cvrt2ftaddr(const unsigned int addr, unsigned char *pdeviceId, unsigned short *poffset)
|
||||
{
|
||||
unsigned char deviceId;
|
||||
unsigned short offset;
|
||||
unsigned int 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;
|
||||
}
|
||||
|
||||
unsigned char sdio_read8(ADAPTER *Adapter, unsigned int addr, int *err)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned char val;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||||
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
val = rtw_sdio_bus_ops.readb(psdiodev->intf_data.func, ftaddr, err);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
|
||||
if(err && *err)
|
||||
DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
unsigned short sdio_read16(ADAPTER *Adapter, unsigned int addr, int *err)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned short val;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
|
||||
if (addr & 1)
|
||||
DBG_871X( "sdio_read16 addr is wrong addr:0x%08x\n", addr);
|
||||
|
||||
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
val = rtw_sdio_bus_ops.readw(psdiodev->intf_data.func, ftaddr, err);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
|
||||
if(err && *err)
|
||||
DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int sdio_read32(ADAPTER *Adapter, unsigned int addr, int *err)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned int val;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
|
||||
if (addr & 3)
|
||||
DBG_871X( "sdio_read32 addr is wrong addr:0x%08x\n", addr);
|
||||
|
||||
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
val = rtw_sdio_bus_ops.readl(psdiodev->intf_data.func, ftaddr, err);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
if(err && *err)
|
||||
DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned int sdio_write8(ADAPTER *Adapter, unsigned int addr, unsigned int buf, int*err)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned int val = 0;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
|
||||
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||||
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
rtw_sdio_bus_ops.writeb(psdiodev->intf_data.func, buf&0xFF,ftaddr, err);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
|
||||
if(err && *err)
|
||||
DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int sdio_write16(ADAPTER *Adapter, unsigned int addr,unsigned int buf, int *err)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned int val = 0;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
|
||||
if (addr & 1)
|
||||
DBG_871X( "sdio_write16 addr is wrong addr:0x%08x\n", addr);
|
||||
|
||||
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
rtw_sdio_bus_ops.writew(psdiodev->intf_data.func, buf&0xFFFF,ftaddr, err);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
if(err && *err)
|
||||
DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int sdio_write32(ADAPTER *Adapter, unsigned int addr, unsigned int buf, int *err)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned int val = 0;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
|
||||
if (addr & 3)
|
||||
DBG_871X( "sdio_write32 addr is wrong addr:0x%08x\n", addr);
|
||||
|
||||
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
rtw_sdio_bus_ops.writel(psdiodev->intf_data.func, buf&0xFFFFFFFF,ftaddr, err);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
|
||||
if(err && *err)
|
||||
DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int _fifoqueue2ftaddr(unsigned int fifo, unsigned int addr)
|
||||
{
|
||||
unsigned int cmdaddr = TX_HIQ_DOMAIN;
|
||||
|
||||
switch(fifo) {
|
||||
case TX_LOQ_DOMAIN:
|
||||
cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
|
||||
break;
|
||||
case TX_HIQ_DOMAIN:
|
||||
cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
|
||||
break;
|
||||
case TX_MIQ_DOMAIN:
|
||||
cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
|
||||
break;
|
||||
case RX_RXFIFO_DOMAIN:
|
||||
cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK));
|
||||
break;
|
||||
default:
|
||||
cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
|
||||
break;
|
||||
|
||||
}
|
||||
return cmdaddr;
|
||||
}
|
||||
|
||||
void sdio_write_tx_fifo(ADAPTER *Adapter, unsigned char *buf, int reallen, unsigned int fifo)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned char *mem = buf;
|
||||
int free_mem = 0;
|
||||
int status;
|
||||
unsigned int cnt = (unsigned int)reallen;
|
||||
unsigned int page_num = 0;
|
||||
unsigned int wait_num = 100;
|
||||
unsigned int use_page = 0;
|
||||
|
||||
_func_enter_;
|
||||
use_page = (cnt + TX_FIFO_PAGE_SZ - 1) / TX_FIFO_PAGE_SZ;
|
||||
|
||||
if (cnt > 512)
|
||||
cnt = _RND(cnt, 512);
|
||||
else
|
||||
cnt = _RND(cnt, 4);
|
||||
|
||||
if (((u32)buf) % 4) {
|
||||
mem = rtw_zmalloc(cnt);
|
||||
while(!mem) {
|
||||
DBG_871X("rtw_zmalloc fail, cannot write tx fifo now\n");
|
||||
rtw_yield_os();
|
||||
mem = rtw_zmalloc(cnt);
|
||||
}
|
||||
|
||||
free_mem = 1;
|
||||
//DBG_871X("sdio_write_tx_fifo tem_buf:%p ", mem);
|
||||
rtw_memcpy(mem, buf, reallen);
|
||||
|
||||
} else {
|
||||
mem = buf;
|
||||
}
|
||||
|
||||
if (((u32)mem) % 4) {
|
||||
DBG_871X("sdio_write_tx_fifo: Oops mem %p not 4 byte Alignment this will cause DMA wrong \n", mem);
|
||||
}
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
|
||||
|
||||
if (fifo == TX_HIQ_DOMAIN)
|
||||
page_num = psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX];
|
||||
else if (fifo == TX_LOQ_DOMAIN)
|
||||
page_num = psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX];
|
||||
else
|
||||
page_num = psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX];
|
||||
|
||||
if (page_num + psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] < use_page) {
|
||||
spi_query_status_info(Adapter->dvobj);
|
||||
}
|
||||
|
||||
while (page_num + psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] < use_page) {
|
||||
DBG_871X("Oops: spi_write_tx_fifo(): page_num is %d, padapter->pub_page is %d, wait_num is %d",
|
||||
page_num, psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX], wait_num);
|
||||
|
||||
rtw_msleep_os(1);
|
||||
//rtw_udelay_os(20);
|
||||
spi_query_status_info(Adapter->dvobj);
|
||||
|
||||
if (fifo == TX_HIQ_DOMAIN)
|
||||
page_num = psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX];
|
||||
else if (fifo == TX_LOQ_DOMAIN)
|
||||
page_num = psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX];
|
||||
else
|
||||
page_num = psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX];
|
||||
|
||||
if (wait_num <= 2) {
|
||||
DBG_871X("%s(): wait_num is <= 2 drop", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
wait_num --;
|
||||
}
|
||||
|
||||
if (fifo == TX_HIQ_DOMAIN) {
|
||||
if (use_page <= page_num) {
|
||||
psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX] -= page_num;
|
||||
} else {
|
||||
psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX] = 0;
|
||||
psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= use_page - psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX];
|
||||
}
|
||||
} else if (fifo == TX_LOQ_DOMAIN) {
|
||||
if (use_page <= page_num) {
|
||||
psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX] -= page_num;
|
||||
} else {
|
||||
psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = 0;
|
||||
psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= use_page - psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX];
|
||||
}
|
||||
} else {
|
||||
if (use_page <= page_num) {
|
||||
psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX] -= page_num;
|
||||
} else {
|
||||
psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX] = 0;
|
||||
psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= use_page - psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX];
|
||||
}
|
||||
}
|
||||
|
||||
//must reallen here or tx will wrong when RND(512)
|
||||
ftaddr = _fifoqueue2ftaddr(fifo, reallen >> 2);
|
||||
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
status = rtw_sdio_bus_ops.memcpy_toio(psdiodev->intf_data.func, ftaddr, mem, cnt);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
|
||||
if (free_mem) {
|
||||
rtw_mfree(mem, cnt);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
DBG_871X("sdio_write_tx_fifo:status:%x ftaddr:%x Length:%d fifo:%x ", status, ftaddr, cnt, fifo);
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void sdio_read_rx_fifo(ADAPTER *Adapter, unsigned char *buf, int reallen)
|
||||
{
|
||||
struct dvobj_priv *psdiodev;
|
||||
unsigned int ftaddr;
|
||||
unsigned char *mem = buf;
|
||||
int free_mem = 0;
|
||||
int status;
|
||||
unsigned int cnt = (unsigned int)reallen;
|
||||
static unsigned int sdio_rxfifo_cnt = 0;
|
||||
unsigned int fifo = RX_RXFIFO_DOMAIN;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
if (cnt > 512)
|
||||
cnt = _RND(cnt, 512);
|
||||
else
|
||||
cnt = _RND(cnt, 4);
|
||||
|
||||
mem = rtw_zmalloc(cnt);
|
||||
if (mem) {
|
||||
free_mem = 1;
|
||||
//DBG_871X("sdio_read_rx_fifo tem_buf:%p ", mem);
|
||||
} else {
|
||||
//DBG_871X("sdio_read_rx_fifo tem_buf:Oops %p ", mem);
|
||||
mem = buf;
|
||||
}
|
||||
|
||||
if (mem == NULL) {
|
||||
DBG_871X("sdio_read_rx_fifo: Oops mem is NULL \n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((u32)mem) % 4) {
|
||||
DBG_871X("sdio_read_rx_fifo: Oops mem %p not 4 byte Alignment this will cause DMA wrong \n", mem);
|
||||
}
|
||||
|
||||
psdiodev = adapter_to_dvobj(Adapter);
|
||||
|
||||
ftaddr = _fifoqueue2ftaddr(fifo, sdio_rxfifo_cnt++);
|
||||
|
||||
rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func);
|
||||
status = rtw_sdio_bus_ops.memcpy_fromio(psdiodev->intf_data.func, mem, ftaddr, cnt);
|
||||
rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func);
|
||||
|
||||
if (free_mem) {
|
||||
if (buf)
|
||||
rtw_memcpy(buf, mem, reallen);
|
||||
rtw_mfree(mem, cnt);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
//error
|
||||
DBG_871X("rtw_sdio_read_rx_fifo error 0x%x\n"
|
||||
"***** Addr = %x *****\n"
|
||||
"***** Length = %d *****\n", status, ftaddr, cnt);
|
||||
}
|
||||
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sdio_cmd52_read(ADAPTER *Adapter, u32 addr, u32 cnt, u8 *pdata, int *err)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
pdata[i] = sdio_read8(Adapter, addr + i, err);
|
||||
if (err && *err)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sdio_cmd52_write(ADAPTER *Adapter, u32 addr, u32 cnt, u8 *pdata, int *err)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
sdio_write8(Adapter, addr + i, pdata[i], err);
|
||||
if (err && *err)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 _sdio_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err)
|
||||
{
|
||||
u8 val;
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
val = sdio_read8(Adapter, addr, err);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
u16 _sdio_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err)
|
||||
{
|
||||
u8 bMacPwrCtrlOn = _FALSE;
|
||||
u16 val;
|
||||
u8 cmd52_io = 0;
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
_func_enter_;
|
||||
/* we should use CMD 52 before bMacPwrCtrlOn */
|
||||
rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
|
||||
cmd52_io = !bMacPwrCtrlOn;
|
||||
#ifdef SDIO_CMD52_IO
|
||||
cmd52_io = 1;
|
||||
#endif
|
||||
if (cmd52_io) {
|
||||
sdio_cmd52_read(Adapter, addr, 2, (u8*)&val, err);
|
||||
val = le16_to_cpu(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
val = sdio_read16(Adapter, addr, err);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
u32 _sdio_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err)
|
||||
{
|
||||
u8 bMacPwrCtrlOn = _FALSE;
|
||||
u32 val;
|
||||
u8 cmd52_io = 0;
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
/* we should use CMD 52 before bMacPwrCtrlOn */
|
||||
rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
|
||||
cmd52_io = !bMacPwrCtrlOn;
|
||||
#ifdef SDIO_CMD52_IO
|
||||
cmd52_io = 1;
|
||||
#endif
|
||||
if (cmd52_io) {
|
||||
sdio_cmd52_read(Adapter, addr, 4, (u8*)&val, err);
|
||||
val = le32_to_cpu(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
val = sdio_read32(Adapter, addr, err);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
s32 _sdio_write8(struct dvobj_priv *pdvobj, u32 addr, u8 val, s32 *err)
|
||||
{
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
sdio_write8(Adapter, addr, (u32)val, err);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
s32 _sdio_write16(struct dvobj_priv *pdvobj, u32 addr, u16 val, s32 *err)
|
||||
{
|
||||
u8 bMacPwrCtrlOn = _FALSE;
|
||||
u8 cmd52_io = 0;
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
_func_enter_;
|
||||
/* we should use CMD 52 before bMacPwrCtrlOn */
|
||||
rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
|
||||
cmd52_io = !bMacPwrCtrlOn;
|
||||
#ifdef SDIO_CMD52_IO
|
||||
cmd52_io = 1;
|
||||
#endif
|
||||
if (cmd52_io) {
|
||||
val = cpu_to_le16(val);
|
||||
sdio_cmd52_write(Adapter, addr, 2, (u8*)&val, err);
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
sdio_write16(Adapter, addr, (u32)val, err);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
s32 _sdio_write32(struct dvobj_priv *pdvobj, u32 addr, u32 val, s32 *err)
|
||||
{
|
||||
u8 bMacPwrCtrlOn = _FALSE;
|
||||
u8 cmd52_io = 0;
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
_func_enter_;
|
||||
/* we should use CMD 52 before bMacPwrCtrlOn */
|
||||
rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
|
||||
cmd52_io = !bMacPwrCtrlOn;
|
||||
#ifdef SDIO_CMD52_IO
|
||||
cmd52_io = 1;
|
||||
#endif
|
||||
if (cmd52_io) {
|
||||
val = cpu_to_le32(val);
|
||||
sdio_cmd52_write(Adapter, addr, 4, (u8*)&val, err);
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
sdio_write32(Adapter, addr, val, err);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 int _sdio_read_rx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *mem, u32 cnt, struct fifo_more_data *pmore_data)
|
||||
{
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
//struct spi_more_data more_data = {0};
|
||||
|
||||
//DBG_8192C("%s \n", __func__);
|
||||
rtw_memset(pmore_data, 0, sizeof(struct fifo_more_data));
|
||||
|
||||
sdio_read_rx_fifo(Adapter, mem, cnt);
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* Translate sdio fifo address to Domain ID in each WLAN FIFO
|
||||
*/
|
||||
static u32 hwaddr2txfifo(u32 addr)
|
||||
{
|
||||
u32 fifo_domain_id;
|
||||
switch (addr)
|
||||
{
|
||||
case WLAN_TX_HIQ_DEVICE_ID:
|
||||
fifo_domain_id = TX_HIQ_DOMAIN;
|
||||
break;
|
||||
|
||||
case WLAN_TX_MIQ_DEVICE_ID:
|
||||
fifo_domain_id = TX_MIQ_DOMAIN;
|
||||
break;
|
||||
|
||||
case WLAN_TX_LOQ_DEVICE_ID:
|
||||
fifo_domain_id = TX_LOQ_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
fifo_domain_id = TX_LOQ_DOMAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
return fifo_domain_id;
|
||||
}
|
||||
|
||||
|
||||
static int _sdio_write_tx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *mem, u32 cnt)
|
||||
{
|
||||
u8 remain_len = 0;
|
||||
u32 w_sz = cnt;
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
|
||||
remain_len = w_sz%4;
|
||||
if (remain_len != 0)
|
||||
w_sz += 4 -remain_len;
|
||||
|
||||
#if 0//ndef LZM_TEST
|
||||
if (1) {
|
||||
int i = 0;
|
||||
for(i = 0; i < w_sz; i += 4) {
|
||||
DBG_871X("_sdio_write_port[%d]: 0x%08x ", i, *(u32*)(mem + i));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{
|
||||
static u32 write_test = 0;
|
||||
u32 now_time = 0;
|
||||
write_test++;
|
||||
if(write_test==1000) {
|
||||
now_time = xTaskGetTickCount() * portTICK_RATE_MS;
|
||||
DBG_8192C("%s fifo:%d cnt:%d w_sz:%d mem:%p, now time:%d\n", __func__, addr, cnt, w_sz, mem, now_time);
|
||||
write_test = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sdio_write_tx_fifo(Adapter, mem, w_sz, hwaddr2txfifo(addr));
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
static int sdio_io_priv(struct dvobj_priv *pdvobj)
|
||||
{
|
||||
ADAPTER *Adapter = pdvobj->if1;
|
||||
//struct dvobj_priv *pdvobj = &Adapter->dvobjpriv;
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
void sdio_set_intf_ops(struct _io_ops *pops)
|
||||
{
|
||||
pops->init_io_priv = &sdio_io_priv;
|
||||
pops->write8_endian = NULL;
|
||||
|
||||
pops->_read8 = &_sdio_read8;
|
||||
pops->_read16 = &_sdio_read16;
|
||||
pops->_read32 = &_sdio_read32;
|
||||
|
||||
pops->_write8 = &_sdio_write8;
|
||||
pops->_write16 = &_sdio_write16;
|
||||
pops->_write32 = &_sdio_write32;
|
||||
|
||||
pops->read_rx_fifo = &_sdio_read_rx_fifo;
|
||||
pops->write_tx_fifo = &_sdio_write_tx_fifo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 _GSPI_INTF_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
#include "wifi_io.h" //from sdio_driver
|
||||
|
||||
#ifndef CONFIG_SDIO_HCI
|
||||
#error "CONFIG_SDIO_HCI should be on!\n"
|
||||
#endif
|
||||
|
||||
struct dvobj_priv *gspi_dvobj_init(void)
|
||||
{
|
||||
// int status = _FAIL;
|
||||
struct dvobj_priv *dvobj = NULL;
|
||||
PGSPI_DATA pgspi_data;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
dvobj = (struct dvobj_priv*)rtw_zmalloc(sizeof(*dvobj));
|
||||
if (NULL == dvobj) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pgspi_data = &dvobj->intf_data;
|
||||
|
||||
rtw_mutex_init(&pgspi_data->spi_mutex);
|
||||
//pgspi_data->block_transfer_len = 512; //512 blocks r/w is not required for GSPI interface
|
||||
//pgspi_data->tx_block_mode = 0;
|
||||
//pgspi_data->rx_block_mode = 0;
|
||||
|
||||
// status = _SUCCESS;
|
||||
|
||||
if(wifi_sdio_func) {
|
||||
DBG_871X("[gspi_dvobj_init] get wifi_func:%p\n", wifi_sdio_func);
|
||||
dvobj->intf_data.func = wifi_sdio_func;
|
||||
} else {
|
||||
DBG_871X("[gspi_dvobj_init] Oops: get wifi sdio function fail");
|
||||
}
|
||||
|
||||
exit:
|
||||
_func_exit_;
|
||||
|
||||
return dvobj;
|
||||
}
|
||||
|
||||
void gspi_dvobj_deinit(struct dvobj_priv *dvobj)
|
||||
{
|
||||
//TODO
|
||||
// struct dvobj_priv *dvobj = spi_get_drvdata(spi);
|
||||
|
||||
_func_enter_;
|
||||
//TODO
|
||||
// spi_set_drvdata(spi, NULL);
|
||||
if (dvobj) {
|
||||
//TODO
|
||||
// gspi_deinit(dvobj);
|
||||
rtw_mutex_free(&dvobj->intf_data.spi_mutex);
|
||||
rtw_mfree((u8*)dvobj, sizeof(*dvobj));
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
}
|
||||
|
||||
void sdio_dvobj_interrupt_entry(struct sdio_func *func)
|
||||
{
|
||||
//DBG_871X("[sdio_wifi_interrupt_entry] func :%p\n", func);
|
||||
|
||||
//sdio irq have claim host, we should release it
|
||||
//and claim it after SDIO IO, or SDIO IO will deadlock
|
||||
rtw_sdio_bus_ops.release_host(func);
|
||||
rtw_hci_interrupt_handler(func->drv_priv);
|
||||
rtw_sdio_bus_ops.claim_host(func);
|
||||
}
|
||||
|
||||
void sdio_dvobj_request_irq(struct dvobj_priv *dvobj)
|
||||
{
|
||||
_func_enter_;
|
||||
if(dvobj->intf_data.func) {
|
||||
dvobj->intf_data.func->drv_priv = (void*)dvobj->if1;
|
||||
|
||||
rtw_sdio_bus_ops.claim_host(dvobj->intf_data.func);
|
||||
rtw_sdio_bus_ops.claim_irq(dvobj->intf_data.func, sdio_dvobj_interrupt_entry);
|
||||
rtw_sdio_bus_ops.release_host(dvobj->intf_data.func);
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
}
|
||||
|
||||
void sdio_dvobj_free_irq(struct dvobj_priv *dvobj)
|
||||
{
|
||||
_func_enter_;
|
||||
if(dvobj->intf_data.func) {
|
||||
dvobj->intf_data.func->drv_priv = (void*)dvobj->if1;
|
||||
|
||||
rtw_sdio_bus_ops.claim_host(dvobj->intf_data.func);
|
||||
rtw_sdio_bus_ops.release_irq(dvobj->intf_data.func);
|
||||
rtw_sdio_bus_ops.release_host(dvobj->intf_data.func);
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
}
|
||||
|
||||
|
||||
static inline u32 ffaddr2deviceId(struct dvobj_priv *pdvobj, u32 addr)
|
||||
{
|
||||
return pdvobj->Queue2Pipe[addr];
|
||||
}
|
||||
|
||||
static s32 rtw_xmit_xmitbuf(_adapter * padapter, struct xmit_buf *pxmitbuf)
|
||||
{
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
u32 deviceId;
|
||||
|
||||
RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("@@@rtw_xmit_xmitbuf(): pxmitbuf->len=%d\n", pxmitbuf->len));
|
||||
//translate queue index to Device Id
|
||||
deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);
|
||||
|
||||
rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8*)pxmitbuf->pbuf);
|
||||
|
||||
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
s32 sdio_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe)
|
||||
{
|
||||
s32 ret = _SUCCESS;
|
||||
struct pkt_attrib *pattrib;
|
||||
struct xmit_buf *pxmitbuf;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
u8 *pframe = NULL;
|
||||
|
||||
RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("+rtw_xmit_mgnt()\n"));
|
||||
|
||||
pattrib = &pmgntframe->attrib;
|
||||
pxmitbuf = pmgntframe->pxmitbuf;
|
||||
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
|
||||
|
||||
//rtw_hal_update_txdesc(padapter, pmgntframe, pmgntframe->buf_addr);
|
||||
|
||||
pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
|
||||
//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);
|
||||
|
||||
//RT_TRACE(_module_rtl871x_xmit_c_, _drv_always_, ("+rtw_xmit_mgnt(): type=%d\n", GetFrameSubType(pframe)));
|
||||
if(GetFrameSubType(pframe)==WIFI_BEACON) //dump beacon directly
|
||||
{
|
||||
//When using dedicated xmit frame for issue bcn on ap mode
|
||||
//free xmit frame for bcn reserved page on station mode - Alex Fang
|
||||
#if USE_DEDICATED_BCN_TX
|
||||
if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) {
|
||||
rtw_free_xmitframe(pxmitpriv, pmgntframe);
|
||||
pxmitbuf->priv_data = NULL;
|
||||
}
|
||||
rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, pxmitbuf->pbuf);
|
||||
|
||||
if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
|
||||
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
|
||||
#else
|
||||
rtw_free_xmitframe(pxmitpriv, pmgntframe);
|
||||
pxmitbuf->priv_data = NULL;
|
||||
rtw_xmit_xmitbuf(padapter, pxmitbuf);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
rtw_free_xmitframe(pxmitpriv, pmgntframe);
|
||||
pxmitbuf->priv_data = NULL;
|
||||
rtw_xmit_xmitbuf(padapter, pxmitbuf);
|
||||
}
|
||||
|
||||
if (ret != _SUCCESS)
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
|
||||
|
||||
RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("-rtw_xmit_mgnt\n"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 sdio_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe)
|
||||
{
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
_irqL irql;
|
||||
s32 err;
|
||||
|
||||
#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
|
||||
|
||||
#if USE_SKB_AS_XMITBUF
|
||||
rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
|
||||
#endif
|
||||
|
||||
rtw_enter_critical_bh(&pxmitpriv->lock, &irql);
|
||||
#if 1 //FIX_XMITFRAME_FAULT, move from rtw_xmit().
|
||||
#ifdef CONFIG_AP_MODE
|
||||
if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE)
|
||||
{
|
||||
rtw_exit_critical_bh(&pxmitpriv->lock, &irql);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
err = rtw_xmitframe_enqueue(padapter, pxmitframe);
|
||||
rtw_exit_critical_bh(&pxmitpriv->lock, &irql);
|
||||
|
||||
if (err != _SUCCESS) {
|
||||
RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmit_data(): enqueue xmitframe fail\n"));
|
||||
rtw_free_xmitframe(pxmitpriv, pxmitframe);
|
||||
|
||||
// Trick, make the statistics correct
|
||||
pxmitpriv->tx_pkts--;
|
||||
pxmitpriv->tx_drop++;
|
||||
return _TRUE;
|
||||
}
|
||||
#ifdef CONFIG_CONCURRENT_MODE
|
||||
if (padapter->adapter_type > PRIMARY_ADAPTER){
|
||||
padapter = padapter->pbuddy_adapter;
|
||||
}
|
||||
#endif
|
||||
|
||||
rtw_wakeup_task(&padapter->xmitThread);
|
||||
|
||||
return _FALSE;
|
||||
}
|
||||
|
||||
const struct host_ctrl_intf_ops hci_ops = {
|
||||
gspi_dvobj_init,
|
||||
gspi_dvobj_deinit,
|
||||
sdio_dvobj_request_irq,
|
||||
sdio_dvobj_free_irq
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 _GSPI_ISR_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
extern struct recv_buf* rtw_recv_rxfifo(_adapter * padapter, u32 size, struct fifo_more_data* more_data);
|
||||
|
||||
void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr)
|
||||
{
|
||||
struct dvobj_priv *pdvobj = padapter->dvobj;
|
||||
|
||||
#ifdef CONFIG_LPS_LCLK
|
||||
if (sdio_hisr & HCI_HISR_CPWM1)
|
||||
{
|
||||
struct reportpwrstate_parm report;
|
||||
|
||||
report.state = rtw_read8(padapter, LOCAL_REG_HCPWM1);
|
||||
cpwm_int_hdl(padapter, &report);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sdio_hisr & HCI_HISR_TXERR)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
status = rtw_read32(padapter, REG_TXDMA_STATUS);
|
||||
rtw_write32(padapter, REG_TXDMA_STATUS, status);
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, status));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN
|
||||
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
|
||||
if (sdio_hisr & HCI_HISR_BCNERLY_INT)
|
||||
#endif
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
|
||||
if (sdio_hisr & (HCI_HISR_TXBCNOK|HCI_HISR_TXBCNERR))
|
||||
#endif
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
#if 0 //for debug
|
||||
if (sdio_hisr & SDIO_HISR_BCNERLY_INT)
|
||||
DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__);
|
||||
|
||||
if (sdio_hisr & SDIO_HISR_TXBCNOK)
|
||||
DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
|
||||
|
||||
if (sdio_hisr & SDIO_HISR_TXBCNERR) {
|
||||
u1Byte v422, v550, v419;
|
||||
v422 = rtw_read8(padapter, 0x422);
|
||||
v419 = rtw_read8(padapter, 0x419);
|
||||
v550 = rtw_read8(padapter, 0x550);
|
||||
|
||||
DBG_8192C("%s: SDIO_HISR_TXBCNERR 422=%02x, 419=%02x, 550=%02x\n", __func__, v422, v419, v550);
|
||||
}
|
||||
#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
|
||||
|
||||
if (sdio_hisr & HCI_HISR_C2HCMD)
|
||||
{
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: C2H Command\n", __func__));
|
||||
//TODO
|
||||
// rtw_c2h_wk_cmd(padapter);
|
||||
}
|
||||
|
||||
if (sdio_hisr & HCI_HISR_RX_REQUEST)// || sdio_hisr & SPI_HISR_RXFOVW)
|
||||
{
|
||||
struct recv_buf *precvbuf;
|
||||
struct fifo_more_data more_data = {0};
|
||||
|
||||
//RT_TRACE(_module_hci_ops_c_,_drv_info_, ("%s: RX Request, size=%d\n", __func__, pdvobj->SdioRxFIFOSize));
|
||||
|
||||
sdio_hisr ^= HCI_HISR_RX_REQUEST;
|
||||
|
||||
do {
|
||||
more_data.more_data = 0;
|
||||
more_data.len = 0;
|
||||
|
||||
if (pdvobj->SdioRxFIFOSize == 0)
|
||||
{
|
||||
u16 val = 0;
|
||||
//s32 ret; //LZM_TODO
|
||||
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize));
|
||||
|
||||
val = rtw_read16(padapter, LOCAL_REG_RX0_REQ_LEN_1_BYTE);
|
||||
//if (!ret) {
|
||||
pdvobj->SdioRxFIFOSize = val;
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize again size=%d\n", __func__, pdvobj->SdioRxFIFOSize));
|
||||
//} else {
|
||||
// RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize ERROR!!\n", __func__));
|
||||
//}
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize));
|
||||
}
|
||||
|
||||
if (pdvobj->SdioRxFIFOSize != 0)
|
||||
{
|
||||
#ifdef RTL8723A_SDIO_LOOPBACK
|
||||
sd_recv_loopback(padapter, pdvobj->SdioRxFIFOSize);
|
||||
#else
|
||||
if (sdio_hisr & HCI_HISR_RXFOVW)
|
||||
RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s RXFOVW RX\n", __func__));
|
||||
|
||||
precvbuf = rtw_recv_rxfifo(padapter, pdvobj->SdioRxFIFOSize, &more_data);
|
||||
if (precvbuf)
|
||||
rtw_rxhandler(padapter, precvbuf);
|
||||
|
||||
if (more_data.more_data) {
|
||||
pdvobj->SdioRxFIFOSize = more_data.len;
|
||||
} else {
|
||||
pdvobj->SdioRxFIFOSize = 0;
|
||||
}
|
||||
#endif
|
||||
//If Rx_request ISR is set, execute receive tasklet (sdio_hisr & SPI_HISR_RX_REQUEST)
|
||||
#if defined(CONFIG_ISR_THREAD_MODE_INTERRUPT) && defined(CONFIG_RECV_TASKLET_THREAD)
|
||||
rtw_wakeup_task(&padapter->recvtasklet_thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTERRUPT_BASED_TXBCN
|
||||
{
|
||||
//Prevent BCN update not realtime in ap mode - Alex Fang
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
if((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) && (pmlmepriv->update_bcn == _TRUE))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
} while (more_data.more_data || pdvobj->SdioRxFIFOSize);
|
||||
#ifdef PLATFORM_LINUX
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
tasklet_schedule(&padapter->recvpriv.recv_tasklet);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void spi_int_hdl(PADAPTER padapter)
|
||||
{
|
||||
struct dvobj_priv *pdvobj = padapter->dvobj;
|
||||
u32 sdio_hisr = 0;
|
||||
//s32 ret;
|
||||
|
||||
if ((padapter->bDriverStopped == _TRUE) ||
|
||||
(padapter->bSurpriseRemoved == _TRUE))
|
||||
return;
|
||||
|
||||
sdio_hisr = rtw_read32(padapter, LOCAL_REG_HISR);//, &ret);
|
||||
//if (!ret) {
|
||||
// RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SDIO_REG_HISR FAIL!!\n", __func__));
|
||||
// return;
|
||||
//}
|
||||
pdvobj->SdioRxFIFOSize = rtw_read16(padapter, LOCAL_REG_RX0_REQ_LEN_1_BYTE);//, &ret);
|
||||
|
||||
//if (!ret) {
|
||||
// RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SPI_REG_RX0_REQ_LEN FAIL!!\n", __func__));
|
||||
// return;
|
||||
//}
|
||||
|
||||
if (sdio_hisr & pdvobj->sdio_himr)
|
||||
{
|
||||
u32 v32;
|
||||
|
||||
sdio_hisr &= pdvobj->sdio_himr;
|
||||
|
||||
// clear HISR
|
||||
v32 = sdio_hisr & MASK_SPI_HISR_CLEAR;
|
||||
if (v32) {
|
||||
rtw_write32(padapter, LOCAL_REG_HISR, v32);//, &ret);
|
||||
}
|
||||
|
||||
spi_int_dpc(padapter, sdio_hisr);
|
||||
} else {
|
||||
//RT_TRACE(_module_hci_ops_c_, _drv_err_,
|
||||
// ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
|
||||
// __FUNCTION__, sdio_hisr, pdvobj->sdio_himr));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __GSDIO_SPEC_H__
|
||||
#define __GSDIO_SPEC_H__
|
||||
|
||||
|
||||
#define SPI_LOCAL_DOMAIN 0x0
|
||||
#define WLAN_IOREG_DOMAIN 0x8
|
||||
#define FW_FIFO_DOMAIN 0x4
|
||||
#define TX_HIQ_DOMAIN 0xc
|
||||
#define TX_MIQ_DOMAIN 0xd
|
||||
#define TX_LOQ_DOMAIN 0xe
|
||||
#define RX_RXFIFO_DOMAIN 0x1f
|
||||
|
||||
//IO Bus domain address mapping
|
||||
#define DEFUALT_OFFSET 0x0
|
||||
#define SPI_LOCAL_OFFSET 0x10250000
|
||||
#define WLAN_IOREG_OFFSET 0x10260000
|
||||
#define FW_FIFO_OFFSET 0x10270000
|
||||
#define TX_HIQ_OFFSET 0x10310000
|
||||
#define TX_MIQ_OFFSET 0x1032000
|
||||
#define TX_LOQ_OFFSET 0x10330000
|
||||
#define RX_RXOFF_OFFSET 0x10340000
|
||||
|
||||
#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13]
|
||||
#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13]
|
||||
#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13]
|
||||
#define WLAN_TX_EXQ_DEVICE_ID 3 // 0b[16], 011b[15:13]
|
||||
#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13]
|
||||
#define WLAN_IOREG_DEVICE_ID 8 // 1b[16]
|
||||
|
||||
//SPI Tx Free Page Index
|
||||
#define HI_QUEUE_IDX 0
|
||||
#define MID_QUEUE_IDX 1
|
||||
#define LOW_QUEUE_IDX 2
|
||||
#define PUBLIC_QUEUE_IDX 3
|
||||
|
||||
#define MAX_TX_QUEUE 3 // HIQ, MIQ and LOQ
|
||||
#define MAX_RX_QUEUE 1
|
||||
|
||||
//SPI Local registers
|
||||
#define SPI_REG_TX_CTRL (SPI_LOCAL_OFFSET | 0x0000) // SPI Tx Control
|
||||
#define SPI_REG_STATUS_RECOVERY (SPI_LOCAL_OFFSET | 0x0004)
|
||||
#define SPI_REG_INT_TIMEOUT (SPI_LOCAL_OFFSET | 0x0006)
|
||||
#define SPI_REG_HIMR (SPI_LOCAL_OFFSET | 0x0014) // SPI Host Interrupt Mask
|
||||
#define SPI_REG_HISR (SPI_LOCAL_OFFSET | 0x0018) // SPI Host Interrupt Service Routine
|
||||
#define SPI_REG_RX0_REQ_LEN (SPI_LOCAL_OFFSET | 0x001C) // RXDMA Request Length
|
||||
#define SPI_REG_FREE_TXPG (SPI_LOCAL_OFFSET | 0x0020) // Free Tx Buffer Page
|
||||
#define SPI_REG_HCPWM1 (SPI_LOCAL_OFFSET | 0x0024) // HCI Current Power Mode 1
|
||||
#define SPI_REG_HCPWM2 (SPI_LOCAL_OFFSET | 0x0026) // HCI Current Power Mode 2
|
||||
#define SPI_REG_HTSFR_INFO (SPI_LOCAL_OFFSET | 0x0030) // HTSF Informaion
|
||||
#define SPI_REG_HRPWM1 (SPI_LOCAL_OFFSET | 0x0080) // HCI Request Power Mode 1
|
||||
#define SPI_REG_HRPWM2 (SPI_LOCAL_OFFSET | 0x0082) // HCI Request Power Mode 2
|
||||
#define SPI_REG_HPS_CLKR (SPI_LOCAL_OFFSET | 0x0084) // HCI Power Save Clock
|
||||
#define SPI_REG_HSUS_CTRL (SPI_LOCAL_OFFSET | 0x0086) // SPI HCI Suspend Control
|
||||
#define SPI_REG_HIMR_ON (SPI_LOCAL_OFFSET | 0x0090) //SPI Host Extension Interrupt Mask Always
|
||||
#define SPI_REG_HISR_ON (SPI_LOCAL_OFFSET | 0x0091) //SPI Host Extension Interrupt Status Always
|
||||
#define SPI_REG_CFG (SPI_LOCAL_OFFSET | 0x00F0) //SPI Configuration Register
|
||||
|
||||
#define LOCAL_REG_TX_CTRL (SPI_REG_TX_CTRL |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_STATUS_RECOVERY (SPI_REG_STATUS_RECOVERY |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_INT_TIMEOUT (SPI_REG_INT_TIMEOUT |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HIMR (SPI_REG_HIMR |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HISR (SPI_REG_HISR |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_RX0_REQ_LEN_1_BYTE (SPI_REG_RX0_REQ_LEN |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_FREE_TXPG (SPI_REG_FREE_TXPG |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HRPWM1 (SPI_REG_HRPWM1 |SPI_LOCAL_OFFSET)
|
||||
#define LOCAL_REG_HCPWM1 (SPI_REG_HCPWM1 |SPI_LOCAL_OFFSET)
|
||||
|
||||
#define HCI_HIMR_DISABLED 0
|
||||
|
||||
//SPI HIMR MASK diff with SDIO
|
||||
#define HCI_HISR_RX_REQUEST BIT(0)
|
||||
#define HCI_HISR_AVAL BIT(1)
|
||||
#define HCI_HISR_TXERR BIT(2)
|
||||
#define HCI_HISR_RXERR BIT(3)
|
||||
#define HCI_HISR_TXFOVW BIT(4)
|
||||
#define HCI_HISR_RXFOVW BIT(5)
|
||||
#define HCI_HISR_TXBCNOK BIT(6)
|
||||
#define HCI_HISR_TXBCNERR BIT(7)
|
||||
#define HCI_HISR_BCNERLY_INT BIT(16)
|
||||
#define HCI_HISR_C2HCMD BIT(17)
|
||||
#define HCI_HISR_CPWM1 BIT(18)
|
||||
#define HCI_HISR_CPWM2 BIT(19)
|
||||
#define HCI_HISR_HSISR_IND BIT(20)
|
||||
#define HCI_HISR_GTINT3_IND BIT(21)
|
||||
#define HCI_HISR_GTINT4_IND BIT(22)
|
||||
#define HCI_HISR_PSTIMEOUT BIT(23)
|
||||
#define HCI_HISR_OCPINT BIT(24)
|
||||
#define HCI_HISR_ATIMEND BIT(25)
|
||||
#define HCI_HISR_ATIMEND_E BIT(26)
|
||||
#define HCI_HISR_CTWEND BIT(27)
|
||||
|
||||
//SPI HIMR MASK diff with SDIO
|
||||
#define HCI_HIMR_RX_REQUEST BIT(0)
|
||||
#define HCI_HIMR_AVAL BIT(1)
|
||||
#define HCI_HIMR_TXERR BIT(2)
|
||||
#define HCI_HIMR_RXERR BIT(3)
|
||||
#define HCI_HIMR_TXFOVW BIT(4)
|
||||
#define HCI_HIMR_RXFOVW BIT(5)
|
||||
#define HCI_HIMR_TXBCNOK BIT(6)
|
||||
#define HCI_HIMR_TXBCNERR BIT(7)
|
||||
#define HCI_HIMR_BCNERLY_INT BIT(16)
|
||||
#define HCI_HIMR_ATIMEND BIT(17)
|
||||
#define HCI_HIMR_ATIMEND_E BIT(18)
|
||||
#define HCI_HIMR_CTWEND BIT(19)
|
||||
#define HCI_HIMR_C2HCMD BIT(20)
|
||||
#define HCI_HIMR_CPWM1 BIT(21)
|
||||
#define HCI_HIMR_CPWM2 BIT(22)
|
||||
#define HCI_HIMR_HSISR_IND BIT(23)
|
||||
#define HCI_HIMR_GTINT3_IND BIT(24)
|
||||
#define HCI_HIMR_GTINT4_IND BIT(25)
|
||||
#define HCI_HIMR_PSTIMEOUT BIT(26)
|
||||
#define HCI_HIMR_OCPINT BIT(27)
|
||||
#define HCI_HIMR_TSF_BIT32_TOGGLE BIT(29)
|
||||
|
||||
#define MASK_SPI_HISR_CLEAR (HCI_HIMR_TXERR |\
|
||||
HCI_HIMR_RXERR |\
|
||||
HCI_HIMR_TXFOVW |\
|
||||
HCI_HIMR_RXFOVW |\
|
||||
HCI_HIMR_TXBCNOK |\
|
||||
HCI_HIMR_TXBCNERR |\
|
||||
HCI_HIMR_C2HCMD |\
|
||||
HCI_HIMR_CPWM1 |\
|
||||
HCI_HIMR_CPWM2 |\
|
||||
HCI_HIMR_HSISR_IND |\
|
||||
HCI_HIMR_GTINT3_IND |\
|
||||
HCI_HIMR_GTINT4_IND |\
|
||||
HCI_HIMR_PSTIMEOUT |\
|
||||
HCI_HIMR_OCPINT)
|
||||
|
||||
#define REG_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 8, x)//(x<<(unsigned int)24)
|
||||
#define REG_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16)
|
||||
#define REG_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0)
|
||||
#define REG_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5)
|
||||
#define REG_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7)
|
||||
|
||||
#define FIFO_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 16, x)//(x<<(unsigned int)24)
|
||||
//#define FIFO_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16)
|
||||
#define FIFO_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0)
|
||||
#define FIFO_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5)
|
||||
#define FIFO_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7)
|
||||
|
||||
|
||||
//get status dword0
|
||||
#define GET_STATUS_PUB_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 24, 8)
|
||||
#define GET_STATUS_HI_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 18, 6)
|
||||
#define GET_STATUS_MID_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 12, 6)
|
||||
#define GET_STATUS_LOW_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 6, 6)
|
||||
#define GET_STATUS_HISR_HI6BIT(status) LE_BITS_TO_4BYTE(status, 0, 6)
|
||||
|
||||
//get status dword1
|
||||
#define GET_STATUS_HISR_MID8BIT(status) LE_BITS_TO_4BYTE(status + 4, 24, 8)
|
||||
#define GET_STATUS_HISR_LOW8BIT(status) LE_BITS_TO_4BYTE(status + 4, 16, 8)
|
||||
#define GET_STATUS_ERROR(status) LE_BITS_TO_4BYTE(status + 4, 17, 1)
|
||||
#define GET_STATUS_INT(status) LE_BITS_TO_4BYTE(status + 4, 16, 1)
|
||||
#define GET_STATUS_RX_LENGTH(status) LE_BITS_TO_4BYTE(status + 4, 0, 16)
|
||||
|
||||
|
||||
#define RXDESC_SIZE 24
|
||||
|
||||
#define TX_FREE_PG_QUEUE 4 // The number of Tx FIFO free page
|
||||
#define TX_FIFO_PAGE_SZ 128
|
||||
|
||||
struct spi_more_data {
|
||||
unsigned long more_data;
|
||||
unsigned long len;
|
||||
};
|
||||
|
||||
extern BUS_DRV_OPS_T bus_driver_ops;
|
||||
|
||||
extern u8 spi_query_status_info(struct dvobj_priv *pdvobj);
|
||||
|
||||
extern void sdio_set_intf_ops(struct _io_ops *pops);
|
||||
|
||||
#endif //__GSPI_SPEC_H__
|
||||
Loading…
Add table
Add a link
Reference in a new issue