Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/common/mtsdio_data.c
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

746 lines
21 KiB
C

/*
***************************************************************************
* MediaTek Inc.
*
* All rights reserved. source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of MediaTek. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of MediaTek, Inc. is obtained.
***************************************************************************
Module Name:
mtsdio_data.c
*/
#include "rt_config.h"
/* <-------------- to be removed to another header file */
void MTSDIOProcessSoftwareInterrupt(IN RTMP_ADAPTER *pAd);
void MTSDIOProcessFwOwnBackInterrupt(IN RTMP_ADAPTER *pAd);
void MTSDIOProcessAbnormalInterrupt(IN RTMP_ADAPTER *pAd);
void MTSDIOProcessTxInterrupt(IN RTMP_ADAPTER *pAd);
void MTSDIOProcessRxInterrupt(IN RTMP_ADAPTER *pAd);
INT32 MTSDIOSingleProcessRx0(RTMP_ADAPTER *pAd, INT32 Length);
INT32 MTSDIOSingleProcessRx1(RTMP_ADAPTER *pAd, INT32 Length);
typedef struct _INT_EVENT_MAP_T {
UINT32 u4Int;
UINT32 u4Event;
} INT_EVENT_MAP_T, *P_INT_EVENT_MAP_T;
typedef VOID (*IST_EVENT_FUNCTION)(RTMP_ADAPTER *);
enum ENUM_INT_EVENT_T {
INT_EVENT_ABNORMAL,
INT_EVENT_SW_INT,
INT_EVENT_TX,
INT_EVENT_RX,
INT_EVENT_NUM
};
#define PORT_INDEX_LMAC 0
#define PORT_INDEX_MCU 1
/* MCU quque index */
typedef enum _ENUM_MCU_Q_INDEX_T {
MCU_Q0_INDEX = 0,
MCU_Q1_INDEX,
MCU_Q2_INDEX,
MCU_Q3_INDEX,
MCU_Q_NUM
} ENUM_MCU_Q_INDEX_T;
/* LMAC Tx queue index */
typedef enum _ENUM_MAC_TXQ_INDEX_T {
MAC_TXQ_AC0_INDEX = 0,
MAC_TXQ_AC1_INDEX,
MAC_TXQ_AC2_INDEX,
MAC_TXQ_AC3_INDEX,
MAC_TXQ_AC4_INDEX,
MAC_TXQ_AC5_INDEX,
MAC_TXQ_AC6_INDEX,
MAC_TXQ_BMC_INDEX,
MAC_TXQ_BCN_INDEX,
MAC_TXQ_AC10_INDEX,
MAC_TXQ_AC11_INDEX,
MAC_TXQ_AC12_INDEX,
MAC_TXQ_AC13_INDEX,
MAC_TXQ_AC14_INDEX,
MAC_TXQ_NUM
} ENUM_MAC_TXQ_INDEX_T;
/* HIF Tx interrupt status queue index*/
typedef enum _ENUM_HIF_TX_INDEX_T {
HIF_TX_AC0_INDEX = 0, /* HIF TX: AC0 packets */
HIF_TX_AC1_INDEX, /* HIF TX: AC1 packets */
HIF_TX_AC2_INDEX, /* HIF TX: AC2 packets */
HIF_TX_AC3_INDEX, /* HIF TX: AC3 packets */
HIF_TX_AC4_INDEX, /* HIF TX: AC4 packets */
HIF_TX_AC5_INDEX, /* HIF TX: AC5 packets */
HIF_TX_AC6_INDEX, /* HIF TX: AC6 packets */
HIF_TX_BMC_INDEX, /* HIF TX: BMC packets */
HIF_TX_BCN_INDEX, /* HIF TX: BCN packets */
HIF_TX_AC10_INDEX, /* HIF TX: AC10 packets */
HIF_TX_AC11_INDEX, /* HIF TX: AC11 packets */
HIF_TX_AC12_INDEX, /* HIF TX: AC12 packets */
HIF_TX_AC13_INDEX, /* HIF TX: AC13 packets */
HIF_TX_AC14_INDEX, /* HIF TX: AC14 packets */
HIF_TX_FFA_INDEX, /* HIF TX: free-for-all */
HIF_TX_CPU_INDEX, /* HIF TX: CPU */
HIF_TX_NUM /* Maximum number of HIF TX port. */
} ENUM_HIF_TX_INDEX_T;
typedef struct _TX_RESOURCE_CONTROL_T {
/* HW TX queue definition */
UINT8 ucDestPortIndex;
UINT8 ucDestQueueIndex;
/* HIF Interrupt status index*/
UINT8 ucHifTxQIndex;
} TX_RESOURCE_CONTROL_T, *PTX_RESOURCE_CONTROL_T;
static const TX_RESOURCE_CONTROL_T arTcResourceControl[TC_NUM] = {
/* dest port index, dest queue index, HIF TX queue index */
/* First HW queue */
{PORT_INDEX_LMAC, MAC_TXQ_AC0_INDEX, HIF_TX_AC0_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC1_INDEX, HIF_TX_AC1_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC2_INDEX, HIF_TX_AC2_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC3_INDEX, HIF_TX_AC3_INDEX},
{PORT_INDEX_MCU, MCU_Q1_INDEX, HIF_TX_CPU_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC4_INDEX, HIF_TX_AC4_INDEX},
/* Second HW queue */
{PORT_INDEX_LMAC, MAC_TXQ_AC10_INDEX, HIF_TX_AC10_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC11_INDEX, HIF_TX_AC11_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC12_INDEX, HIF_TX_AC12_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC13_INDEX, HIF_TX_AC13_INDEX},
{PORT_INDEX_LMAC, MAC_TXQ_AC14_INDEX, HIF_TX_AC14_INDEX},
};
static INT_EVENT_MAP_T arIntEventMapTable[] = {
{ABNORMAL_INT, INT_EVENT_ABNORMAL},
{D2H_SW_INT, INT_EVENT_SW_INT},
{TX_DONE_INT, INT_EVENT_TX},
{(RX0_DONE_INT | RX1_DONE_INT), INT_EVENT_RX}
};
#define SDIO_TX_DESC_LONG_FORMAT_LENGTH_DW 7 //in unit of double word
#define SDIO_TX_DESC_LONG_FORMAT_LENGTH (SDIO_TX_DESC_LONG_FORMAT_LENGTH_DW << 2)
#define SDIO_TX_DESC_PADDING_LENGTH_DW 0 //in unit of double word
#define SDIO_TX_DESC_PADDING_LENGTH (SDIO_TX_DESC_PADDING_LENGTH_DW << 2)
#define SDIO_TX_PAGE_SIZE_IS_POWER_OF_2 TRUE
#define SDIO_TX_PAGE_SIZE_IN_POWER_OF_2 7
#define SDIO_TX_PAGE_SIZE 128
#define SDIO_TX_MAX_PAGE_PER_FRAME MAX_AGGREGATION_SIZE
#define SDIO_TX_BUFF_COUNT_TC0 1
#define SDIO_TX_BUFF_COUNT_TC1 34
#define SDIO_TX_BUFF_COUNT_TC2 1
#define SDIO_TX_BUFF_COUNT_TC3 1
#define SDIO_TX_BUFF_COUNT_TC4 4
#define SDIO_TX_BUFF_COUNT_TC5 1
#define SDIO_TX_PAGE_COUNT_TC0 (SDIO_TX_BUFF_COUNT_TC0 * SDIO_TX_MAX_PAGE_PER_FRAME / SDIO_TX_PAGE_SIZE)
#define SDIO_TX_PAGE_COUNT_TC1 (SDIO_TX_BUFF_COUNT_TC0 * SDIO_TX_MAX_PAGE_PER_FRAME / SDIO_TX_PAGE_SIZE)
#define SDIO_TX_PAGE_COUNT_TC2 (SDIO_TX_BUFF_COUNT_TC0 * SDIO_TX_MAX_PAGE_PER_FRAME / SDIO_TX_PAGE_SIZE)
#define SDIO_TX_PAGE_COUNT_TC3 (SDIO_TX_BUFF_COUNT_TC0 * SDIO_TX_MAX_PAGE_PER_FRAME / SDIO_TX_PAGE_SIZE)
#define SDIO_TX_PAGE_COUNT_TC4 (SDIO_TX_BUFF_COUNT_TC0 * SDIO_TX_MAX_PAGE_PER_FRAME / SDIO_TX_PAGE_SIZE)
#define SDIO_TX_PAGE_COUNT_TC5 (SDIO_TX_BUFF_COUNT_TC0 * SDIO_TX_MAX_PAGE_PER_FRAME / SDIO_TX_PAGE_SIZE)
/* --------------- end ----------------------------------> */
static const UINT8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T));
static IST_EVENT_FUNCTION apfnEventFuncTable[] = {
MTSDIOProcessAbnormalInterrupt, /*!< INT_EVENT_ABNORMAL */
MTSDIOProcessSoftwareInterrupt, /*!< INT_EVENT_SW_INT */
MTSDIOProcessTxInterrupt, /*!< INT_EVENT_TX */
MTSDIOProcessRxInterrupt, /*!< INT_EVENT_RX */
};
VOID
MTSDIOTxResetResource (
IN RTMP_ADAPTER *pAd
)
{
P_TX_CTRL_T prTxCtrl = NULL;
unsigned long flags = 0;
ASSERT(pAd);
prTxCtrl = &pAd->rTxCtrl;
RTMP_SPIN_LOCK_IRQSAVE(&pAd->TcCountLock, &flags);
NdisZeroMemory(prTxCtrl->rTc.au2TxDonePageCount, sizeof(prTxCtrl->rTc.au2TxDonePageCount));
prTxCtrl->rTc.ucNextTcIdx = TC0_INDEX;
prTxCtrl->rTc.u2AvailiablePageCount = 0;
prTxCtrl->rTc.au2MaxNumOfBuffer[TC0_INDEX] = SDIO_TX_BUFF_COUNT_TC0;
prTxCtrl->rTc.au2FreeBufferCount[TC0_INDEX] = SDIO_TX_BUFF_COUNT_TC0;
prTxCtrl->rTc.au2MaxNumOfBuffer[TC1_INDEX] = SDIO_TX_BUFF_COUNT_TC1;
prTxCtrl->rTc.au2FreeBufferCount[TC1_INDEX] = SDIO_TX_BUFF_COUNT_TC1;
prTxCtrl->rTc.au2MaxNumOfBuffer[TC2_INDEX] = SDIO_TX_BUFF_COUNT_TC2;
prTxCtrl->rTc.au2FreeBufferCount[TC2_INDEX] = SDIO_TX_BUFF_COUNT_TC2;
prTxCtrl->rTc.au2MaxNumOfBuffer[TC3_INDEX] = SDIO_TX_BUFF_COUNT_TC3;
prTxCtrl->rTc.au2FreeBufferCount[TC3_INDEX] = SDIO_TX_BUFF_COUNT_TC3;
prTxCtrl->rTc.au2MaxNumOfBuffer[TC4_INDEX] = SDIO_TX_BUFF_COUNT_TC4;
prTxCtrl->rTc.au2FreeBufferCount[TC4_INDEX] = SDIO_TX_BUFF_COUNT_TC4;
prTxCtrl->rTc.au2MaxNumOfBuffer[TC5_INDEX] = SDIO_TX_BUFF_COUNT_TC5;
prTxCtrl->rTc.au2FreeBufferCount[TC5_INDEX] = SDIO_TX_BUFF_COUNT_TC5;
prTxCtrl->rTc.au2MaxNumOfPage[TC0_INDEX] = SDIO_TX_PAGE_COUNT_TC0;
prTxCtrl->rTc.au2FreePageCount[TC0_INDEX] = SDIO_TX_PAGE_COUNT_TC0;
prTxCtrl->rTc.au2MaxNumOfPage[TC1_INDEX] = SDIO_TX_PAGE_COUNT_TC1;
prTxCtrl->rTc.au2FreePageCount[TC1_INDEX] = SDIO_TX_PAGE_COUNT_TC1;
prTxCtrl->rTc.au2MaxNumOfPage[TC2_INDEX] = SDIO_TX_PAGE_COUNT_TC2;
prTxCtrl->rTc.au2FreePageCount[TC2_INDEX] = SDIO_TX_PAGE_COUNT_TC2;
prTxCtrl->rTc.au2MaxNumOfPage[TC3_INDEX] = SDIO_TX_PAGE_COUNT_TC3;
prTxCtrl->rTc.au2FreePageCount[TC3_INDEX] = SDIO_TX_PAGE_COUNT_TC3;
prTxCtrl->rTc.au2MaxNumOfPage[TC4_INDEX] = SDIO_TX_PAGE_COUNT_TC4;
prTxCtrl->rTc.au2FreePageCount[TC4_INDEX] = SDIO_TX_PAGE_COUNT_TC4;
prTxCtrl->rTc.au2MaxNumOfPage[TC5_INDEX] = SDIO_TX_PAGE_COUNT_TC5;
prTxCtrl->rTc.au2FreePageCount[TC5_INDEX] = SDIO_TX_PAGE_COUNT_TC5;
RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->TcCountLock, &flags);
return;
}
INT32
MTSDIOTxAcquireResource(
IN RTMP_ADAPTER *pAd,
IN UINT8 ucTC,
IN UINT8 ucPageCount
)
{
P_TX_CTRL_T prTxCtrl = NULL;
INT32 u4Ret = 0;
unsigned long flags = 0;
prTxCtrl = &pAd->rTxCtrl;
RTMP_SPIN_LOCK_IRQSAVE(&pAd->TcCountLock, &flags);
if (prTxCtrl->rTc.au2FreePageCount[ucTC] >= ucPageCount) {
prTxCtrl->rTc.au2FreePageCount[ucTC] -= ucPageCount;
prTxCtrl->rTc.au2FreeBufferCount[ucTC] = (prTxCtrl->rTc.au2FreePageCount[ucTC] / SDIO_TX_MAX_PAGE_PER_FRAME);
}
RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->TcCountLock, &flags);
return u4Ret;
}
UINT8
MTSDIOTxGetPageCount (
IN UINT32 u4FrameLength,
IN BOOLEAN fgIncludeDesc
)
{
UINT32 u4RequiredBufferSize = 0;
UINT8 ucPageCount = 0;
/* Frame Buffer
* |<--Tx Descriptor-->|<--Tx descriptor padding-->|<--802.3/802.11 Header-->|<--Header padding-->|<--Payload-->|
*/
if(fgIncludeDesc) {
u4RequiredBufferSize = u4FrameLength;
}
else {
u4RequiredBufferSize =
SDIO_TX_DESC_LONG_FORMAT_LENGTH +
SDIO_TX_DESC_PADDING_LENGTH +
u4FrameLength;
}
if(SDIO_TX_PAGE_SIZE_IS_POWER_OF_2) {
ucPageCount = (UINT8)((u4RequiredBufferSize + (SDIO_TX_PAGE_SIZE - 1)) >> SDIO_TX_PAGE_SIZE_IN_POWER_OF_2);
}
else {
ucPageCount = (UINT8)((u4RequiredBufferSize + (SDIO_TX_PAGE_SIZE - 1)) / SDIO_TX_PAGE_SIZE);
}
return ucPageCount;
}
VOID
MTSDIOTxAdjustTcq (
IN RTMP_ADAPTER *pAd
)
{
ASSERT(pAd);
// TODO: implement QM for adaptive quota control
}
BOOLEAN
MTSDIOTxCalculateResource(
IN RTMP_ADAPTER *pAd,
IN UINT16 *au2TxRlsCnt,
OUT UINT16 *au2FreeTcResource
)
{
P_TX_TCQ_STATUS_T prTcqStatus = NULL;
prTcqStatus = &pAd->rTxCtrl.rTc;
UINT16 u2TotalTxDonePageCount = 0;
UINT8 ucTcIdx = 0;
prTcqStatus = &pAd->rTxCtrl.rTc;
BOOLEAN bStatus = FALSE;
prTcqStatus->u2AvailiablePageCount += au2TxRlsCnt[HIF_TX_FFA_INDEX];
for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) {
prTcqStatus->au2TxDonePageCount[ucTcIdx] += au2TxRlsCnt[arTcResourceControl[ucTcIdx].ucHifTxQIndex];
u2TotalTxDonePageCount += prTcqStatus->au2TxDonePageCount[ucTcIdx];
}
DBGPRINT(RT_DEBUG_OFF, ("Tx Done INT result, FFA[%u] AC[%u:%u:%u:%u:%u] CPU[%u]\n",
au2TxRlsCnt[HIF_TX_FFA_INDEX],
au2TxRlsCnt[HIF_TX_AC0_INDEX],
au2TxRlsCnt[HIF_TX_AC1_INDEX],
au2TxRlsCnt[HIF_TX_AC2_INDEX],
au2TxRlsCnt[HIF_TX_AC3_INDEX],
au2TxRlsCnt[HIF_TX_AC4_INDEX],
au2TxRlsCnt[HIF_TX_CPU_INDEX]));
if (prTcqStatus->u2AvailiablePageCount) {
if (prTcqStatus->u2AvailiablePageCount >= u2TotalTxDonePageCount) {
NdisCopyMemory(au2FreeTcResource, prTcqStatus->au2TxDonePageCount,
sizeof(prTcqStatus->au2TxDonePageCount));
NdisZeroMemory(prTcqStatus->au2TxDonePageCount,
sizeof(prTcqStatus->au2TxDonePageCount));
prTcqStatus->u2AvailiablePageCount -= u2TotalTxDonePageCount;
if (prTcqStatus->u2AvailiablePageCount) {
}
} else {
ucTcIdx = prTcqStatus->ucNextTcIdx;
while (prTcqStatus->u2AvailiablePageCount) {
if (prTcqStatus->u2AvailiablePageCount >= prTcqStatus->au2TxDonePageCount[ucTcIdx]) {
au2FreeTcResource[ucTcIdx] = prTcqStatus->au2TxDonePageCount[ucTcIdx];
prTcqStatus->u2AvailiablePageCount -= prTcqStatus->au2TxDonePageCount[ucTcIdx];
ucTcIdx++;
ucTcIdx %= TC_NUM;
} else {
au2FreeTcResource[ucTcIdx] = prTcqStatus->u2AvailiablePageCount;
prTcqStatus->au2TxDonePageCount[ucTcIdx] -= prTcqStatus->u2AvailiablePageCount;
prTcqStatus->u2AvailiablePageCount = 0;
}
prTcqStatus->ucNextTcIdx = ucTcIdx;
}
bStatus = TRUE;
}
} else {
DBGPRINT(RT_DEBUG_OFF, ("No FFA count to release\n"));
}
return bStatus;
}
BOOLEAN
MTSDIOTxReleaseResource(
IN RTMP_ADAPTER *pAd,
IN UINT16 *au2TxRlsCnt
)
{
P_TX_TCQ_STATUS_T prTcqStatus = NULL;
BOOLEAN bStatus = FALSE;
UINT16 au2FreeTcResource[TC_NUM] = {0};
UINT32 u4BufferCountToBeFeed = 0;
UINT8 i = 0;
unsigned long flags = 0;
prTcqStatus = &pAd->rTxCtrl.rTc;
if (MTSDIOTxCalculateResource(pAd, au2TxRlsCnt, au2FreeTcResource)) {
RTMP_SPIN_LOCK_IRQSAVE(&pAd->TcCountLock, &flags);
for (i = TC0_INDEX; i < TC_NUM; i++) {
/* Real page counter */
prTcqStatus->au2FreePageCount[i] += au2FreeTcResource[i];
/* Buffer counter. For development only */
/* Convert page count to buffer count */
u4BufferCountToBeFeed = (prTcqStatus->au2FreePageCount[i] / SDIO_TX_MAX_PAGE_PER_FRAME);
prTcqStatus->au2FreeBufferCount[i] = u4BufferCountToBeFeed;
if (au2FreeTcResource[i]) {
DBGPRINT(RT_DEBUG_OFF, ("Release: TC%lu ReturnPageCnt[%u] FreePageCnt[%u] FreeBufferCnt[%u]\n",
i,
au2FreeTcResource[i],
prTcqStatus->au2FreePageCount[i],
prTcqStatus->au2FreeBufferCount[i]));
}
}
RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->TcCountLock, &flags);
bStatus = TRUE;
}
return bStatus;
}
VOID
MTSDIOProcessIST_impl (
IN RTMP_ADAPTER *pAd,
IN UINT32 u4IntStatus
)
{
UINT32 u4Status = 0;
UINT32 u4IntCount = 0;
P_INT_EVENT_MAP_T prIntEventMap = NULL;
//unsigned long flags = 0;
ASSERT(pAd);
//pAd->IntStatus = u4IntStatus;
#if 0
prIntEventMap = &arIntEventMapTable[0];
for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) {
if (prIntEventMap->u4Int & pAd->IntStatus) {
if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) {
DBGPRINT(RT_DEBUG_OFF, ("Process IST !"));
apfnEventFuncTable[prIntEventMap->u4Event](pAd);
} else {
DBGPRINT(RT_DEBUG_OFF, ("Empty INT handler !"));
ASSERT(0);
}
//RTMP_SPIN_LOCK_IRQSAVE(&pAd->IntStatusLock, &flags);
pAd->IntStatus &= ~prIntEventMap->u4Int;
//RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->IntStatusLock, &flags);
}
}
#else
if (pAd->IntStatus & ABNORMAL_INT)
{
}
if (pAd->IntStatus & (RX0_DONE_INT | RX1_DONE_INT))
{
MTSDIOProcessRxInterrupt(pAd);
}
if (pAd->IntStatus & TX_DONE_INT)
{
}
#endif
}
VOID
MTSDIOProcessIST (IN RTMP_ADAPTER *pAd)
{
UINT32 u4IntStatus = 0;
unsigned long flags = 0;
#if 0 // CFG_SDIO_INTR_ENHANCE
#else
//MTSDIORead32(pAd, WHISR, &u4IntStatus);
//u4IntStatus = pAd->IntStatus;
#endif
DBGPRINT(RT_DEBUG_ERROR, ("MTSDIOProcessIST pAd->IntStatus: %x\n",pAd->IntStatus));
if (pAd->IntStatus & ~(WHIER_DEFAULT | FW_OWN_BACK_INT_EN)) {
//RTMP_SPIN_LOCK_IRQSAVE(&pAd->IntStatusLock, &flags);
pAd->IntStatus = pAd->IntStatus & WHIER_DEFAULT;
//RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->IntStatusLock, &flags);
}
MTSDIOProcessIST_impl(pAd, pAd->IntStatus);
}
VOID
MTSDIOProcessSoftwareInterrupt(IN RTMP_ADAPTER *pAd)
{
return;
}
VOID
MTSDIOProcessFwOwnBackInterrupt(IN RTMP_ADAPTER *pAd)
{
return;
}
VOID
MTSDIOProcessAbnormalInterrupt(IN RTMP_ADAPTER *pAd)
{
return;
}
VOID
MTSDIOProcessTxInterrupt(IN RTMP_ADAPTER *pAd)
{
P_TX_CTRL_T prTxCtrl = NULL;
#if 0 //CFG_SDIO_INTR_ENHANCE
#else
UINT32 au4TxCount[8];
#endif
#if 0 //CFG_SDIO_INTR_ENHANCE
#else
MTSDIORead32(pAd, &au4TxCount[0], WTQCR0); // AC0
MTSDIORead32(pAd, &au4TxCount[1], WTQCR1); // AC1
MTSDIORead32(pAd, &au4TxCount[2], WTQCR2); // AC2
MTSDIORead32(pAd, &au4TxCount[3], WTQCR3); // AC3
MTSDIORead32(pAd, &au4TxCount[4], WTQCR4); // AC4
MTSDIORead32(pAd, &au4TxCount[5], WTQCR5); // AC5
MTSDIORead32(pAd, &au4TxCount[6], WTQCR6); // AC6
MTSDIORead32(pAd, &au4TxCount[7], WTQCR7); // AC7
//MTSDIOTxReleaseResource(pAd, (PUINT8) au4TxCount);
#endif
//MTSDIOTxAdjustTcq(pAd);
/* TODO: Check if there's any packets */
return;
}
void MTSDIOProcessRxInterrupt(IN RTMP_ADAPTER *pAd)
{
UINT32 Value = 0;
UINT32 RX0PacketLen = 0, RX1PacketLen = 0;
ASSERT(pAd);
#if 0 //CFG_SDIO_INTR_ENHANCE
#else
MTSDIORead32(pAd, WRPLR, &Value);
RX0PacketLen = GET_RX0_PACKET_LENGTH(Value);
RX1PacketLen = GET_RX1_PACKET_LENGTH(Value);
if (RX0PacketLen != 0) {
MTSDIOSingleProcessRx0(pAd, RX0PacketLen);
}
if (RX1PacketLen != 0) {
MTSDIOSingleProcessRx1(pAd, RX1PacketLen);
}
#endif
}
INT32 MTSDIOCmdTx(RTMP_ADAPTER *pAd, UCHAR *Buf, UINT32 Length)
{
INT32 Ret;
Ret = MTSDIOMultiWrite(pAd, WTDR1, Buf, Length);
return Ret;
}
INT32 MTSDIODataTx(RTMP_ADAPTER *pAd, UCHAR *Buf, UINT32 Length)
{
INT32 Ret;
Ret = MTSDIOMultiWrite(pAd, WTDR1, Buf, Length);
return Ret;
}
INT32 MTSDIODataRx0(RTMP_ADAPTER *pAd, UCHAR *Buf, UINT32 Length)
{
INT32 Ret;
Ret = MTSDIOMultiRead(pAd, WRDR0, Buf, Length);
return Ret;
}
INT32 MTSDIODataRx1(RTMP_ADAPTER *pAd, UCHAR *Buf, UINT32 Length)
{
INT32 Ret;
Ret = MTSDIOMultiRead(pAd, WRDR1, Buf, Length);
return Ret;
}
VOID MTSDIOAddWorkerTaskList(RTMP_ADAPTER *pAd)
{
SDIOWorkTask *NewTask;
unsigned long flags;
os_alloc_mem(pAd, (UCHAR **)&NewTask, sizeof(*NewTask));
if (NewTask == NULL)
return;
RTMP_SPIN_LOCK_IRQSAVE(&pAd->SdioWorkTaskLock, &flags);
DlListAddTail(&pAd->SdioWorkTaskList, &NewTask->List);
RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->SdioWorkTaskLock, &flags);
}
INT32 MTSDIOSingleProcessRx0(RTMP_ADAPTER *pAd, INT32 Length)
{
DBGPRINT(RT_DEBUG_OFF, ("%s: =============>\n", __FUNCTION__));
UINT32 i;
PUCHAR buf;
if (Length >= pAd->BlockSize)
Length = (Length + ((-Length) & (pAd->BlockSize - 1)));
pAd->SDIORxPacket = RTMP_AllocateFragPacketBuffer(pAd, Length);
DBGPRINT(RT_DEBUG_OFF, ("%s: =============>\n", __FUNCTION__));
if (!pAd->SDIORxPacket)
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: allocate net packet fail\n",
__FUNCTION__));
return;
}
MTSDIODataRx0(pAd, GET_OS_PKT_DATAPTR(pAd->SDIORxPacket), Length);
#if 1
SET_OS_PKT_LEN(pAd->SDIORxPacket, Length);
buf = GET_OS_PKT_DATAPTR(pAd->SDIORxPacket);
DBGPRINT(RT_DEBUG_OFF, ("%s: ================len = %x ===\n", __FUNCTION__, Length));
for(i=0;i<Length;i++){
printk("%x,",*(buf+i));
}
printk("\n");
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS |
fRTMP_ADAPTER_NIC_NOT_EXIST))
{
RTMPFreeNdisPacket(pAd, pAd->SDIORxPacket);
return;
}
rtmp_rx_done_handle(pAd);
#endif
}
INT32 MTSDIOSingleProcessRx1(RTMP_ADAPTER *pAd, INT32 Length)
{
UINT32 i;
PUCHAR buf;
if (Length >= pAd->BlockSize)
Length = (Length + ((-Length) & (pAd->BlockSize - 1)));
pAd->SDIORxPacket = RTMP_AllocateFragPacketBuffer(pAd, Length);
if (!pAd->SDIORxPacket)
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: allocate net packet fail\n",
__FUNCTION__));
return;
}
MTSDIODataRx1(pAd, GET_OS_PKT_DATAPTR(pAd->SDIORxPacket), Length);
SET_OS_PKT_LEN(pAd->SDIORxPacket, Length);
buf = GET_OS_PKT_DATAPTR(pAd->SDIORxPacket);
DBGPRINT(RT_DEBUG_OFF, ("%s: ================len = %x ===\n", __FUNCTION__, Length));
for(i=0;i<Length;i++){
printk("%x,",*(buf+i));
}
printk("\n");
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS |
fRTMP_ADAPTER_NIC_NOT_EXIST))
{
RTMPFreeNdisPacket(pAd, pAd->SDIORxPacket);
return;
}
rtmp_rx_done_handle(pAd);
}
VOID MTSDIODataWorkerTask(RTMP_ADAPTER *pAd)
{
//UINT32 IntStatus;
void* handle = pAd->OS_Cookie;
struct sdio_func *dev_func = ((POS_COOKIE)handle)->sdio_dev;
UINT32 Value;
//MTSDIORead32(pAd, WHISR, &pAd->IntStatus);
//IntStatus = pAd->IntStatus;
/* Process RX0/RX1, Abnormal, TX done ISR */
if (pAd->IntStatus & WHIER_DEFAULT) {
MTSDIOProcessIST(pAd);
pAd->IntStatus =0;
/* Enable Interrupt */
RTMP_SDIO_WRITE32(pAd, WHLPCR, W_INT_EN_SET);
}
/* Process Command */
AndesMTSendCmdMsgToSdio(pAd);
/* Process TX */
}
VOID MTSDIODataIsr(RTMP_ADAPTER *pAd)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
UINT32 Value;
unsigned long flags;
struct sdio_func *dev_func =pObj->sdio_dev;
INT32 Ret = 0;
/* Disable Interrupt */
RTMP_SDIO_WRITE32(pAd, WHLPCR, W_INT_EN_CLR);
Value = sdio_readl(dev_func, WHISR, &Ret);
if (Ret) {
DBGPRINT(RT_DEBUG_ERROR, ("RTSDIORead32 failure!\n"));
}
if (Value) {
// DBGPRINT(RT_DEBUG_ERROR, ("%s()!!!! WHISR:%x \n", __FUNCTION__,Value));
//RTMP_SPIN_LOCK_IRQSAVE(&pAd->IntStatusLock, &flags);
pAd->IntStatus |= Value;
//RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->IntStatusLock, &flags);
DBGPRINT(RT_DEBUG_TRACE, ("%s() disbale interrupt \n", __FUNCTION__));
DBGPRINT(RT_DEBUG_OFF, ("%s() ======================> \n", __FUNCTION__));
MTSDIOAddWorkerTaskList(pAd);
queue_work(pObj->SdioWq, &pObj->SdioWork);
}
}