mirror of
https://github.com/amazingfate/rtl8723ds.git
synced 2025-09-11 12:36:04 +01:00
This repository contains the Realtek driver V5.1.1.5_20523.20161209_BTCOEX20161208-1212. At inclusion, the only changes from the Realtek version were to fix any compile warnings or errors. With these changes, the driver builds on kernels through 4.11. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
375 lines
10 KiB
C
375 lines
10 KiB
C
#include "mp_precomp.h"
|
|
#include "phydm_precomp.h"
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
|
|
#if ((RTL8197F_SUPPORT == 1)||(RTL8822B_SUPPORT == 1))
|
|
#include "rtl8197f/Hal8197FPhyReg.h"
|
|
#include "WlanHAL/HalMac88XX/halmac_reg2.h"
|
|
#else
|
|
#include "WlanHAL/HalHeader/HalComReg.h"
|
|
#endif
|
|
#endif
|
|
|
|
#if (PHYDM_LA_MODE_SUPPORT == 1)
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
BOOLEAN
|
|
ADCSmp_BufferAllocate(
|
|
IN PADAPTER Adapter,
|
|
IN PRT_ADCSMP AdcSmp
|
|
)
|
|
{
|
|
PRT_ADCSMP_STRING ADCSmpBuf = &(AdcSmp->ADCSmpBuf);
|
|
|
|
if (ADCSmpBuf->Length == 0) {
|
|
if (PlatformAllocateMemoryWithZero(Adapter, (void **)&(ADCSmpBuf->Octet), ADCSmpBuf->buffer_size) == RT_STATUS_SUCCESS)
|
|
ADCSmpBuf->Length = ADCSmpBuf->buffer_size;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
VOID
|
|
ADCSmp_GetTxPktBuf(
|
|
IN PVOID pDM_VOID,
|
|
IN PRT_ADCSMP_STRING ADCSmpBuf
|
|
)
|
|
{
|
|
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
|
|
u4Byte i = 0, value32, DataL = 0, DataH = 0;
|
|
u4Byte Addr, Finish_Addr;
|
|
u4Byte End_Addr = (ADCSmpBuf->start_pos + ADCSmpBuf->buffer_size)-1; /*End_Addr = 0x3ffff;*/
|
|
BOOLEAN bRoundUp;
|
|
static u4Byte page = 0xFF;
|
|
u4Byte while_cnt = 0;
|
|
|
|
ODM_Memory_Set(pDM_Odm, ADCSmpBuf->Octet, 0, ADCSmpBuf->Length);
|
|
ODM_Write1Byte(pDM_Odm, 0x0106, 0x69);
|
|
|
|
DbgPrint("%s\n", __func__);
|
|
|
|
value32 = ODM_Read4Byte(pDM_Odm, 0x7c0);
|
|
bRoundUp = (BOOLEAN)((value32 & BIT31) >> 31);
|
|
Finish_Addr = (value32 & 0x7FFF0000) >> 16; /*Reg7C0[30:16]: finish addr (unit: 8byte)*/
|
|
|
|
if (bRoundUp)
|
|
Addr = (Finish_Addr+1)<<3;
|
|
else
|
|
Addr = ADCSmpBuf->start_pos;
|
|
|
|
DbgPrint("bRoundUp = %d, Finish_Addr=0x%x, value32=0x%x\n", bRoundUp, Finish_Addr, value32);
|
|
DbgPrint("End_Addr = %x, ADCSmpBuf->start_pos = 0x%x, ADCSmpBuf->buffer_size = 0x%x\n", End_Addr, ADCSmpBuf->start_pos, ADCSmpBuf->buffer_size);
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
|
|
watchdog_stop(pDM_Odm->priv);
|
|
#endif
|
|
|
|
if (pDM_Odm->SupportICType & ODM_RTL8197F) {
|
|
for (Addr = 0x0, i = 0; Addr < End_Addr; Addr += 8, i += 2) { /*64K byte*/
|
|
if ((Addr&0xfff) == 0)
|
|
ODM_SetBBReg(pDM_Odm, 0x0140, bMaskLWord, 0x780+(Addr >> 12));
|
|
DataL = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff), bMaskDWord);
|
|
DataH = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff)+4, bMaskDWord);
|
|
|
|
DbgPrint("%08x%08x\n", DataH, DataL);
|
|
}
|
|
} else {
|
|
while (Addr != (Finish_Addr<<3)) {
|
|
if (page != (Addr >> 12)) {
|
|
/*Reg140=0x780+(Addr>>12), Addr=0x30~0x3F, total 16 pages*/
|
|
page = (Addr >> 12);
|
|
}
|
|
ODM_SetBBReg(pDM_Odm, 0x0140, bMaskLWord, 0x780+page);
|
|
|
|
/*pDataL = 0x8000+(Addr&0xfff);*/
|
|
DataL = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff), bMaskDWord);
|
|
DataH = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff)+4, bMaskDWord);
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
ADCSmpBuf->Octet[i] = DataH;
|
|
ADCSmpBuf->Octet[i+1] = DataL;
|
|
#endif
|
|
DbgPrint("%08x%08x\n", DataH, DataL);
|
|
i = i + 2;
|
|
|
|
if ((Addr+8) >= End_Addr)
|
|
Addr = ADCSmpBuf->start_pos;
|
|
else
|
|
Addr = Addr + 8;
|
|
|
|
while_cnt = while_cnt + 1;
|
|
if (while_cnt > ((ADCSmpBuf->buffer_size)>>3))
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
|
|
watchdog_resume(pDM_Odm->priv);
|
|
#endif
|
|
}
|
|
|
|
|
|
VOID
|
|
ADCSmp_Start(
|
|
IN PVOID pDM_VOID,
|
|
IN PRT_ADCSMP AdcSmp
|
|
)
|
|
{
|
|
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
|
|
u1Byte tmpU1b;
|
|
PRT_ADCSMP_STRING Buffer = &(AdcSmp->ADCSmpBuf);
|
|
RT_ADCSMP_TRIG_SIG_SEL TrigSigSel = AdcSmp->ADCSmpTrigSigSel;
|
|
u1Byte backup_DMA, while_cnt = 0;
|
|
|
|
DbgPrint("%s\n", __func__);
|
|
|
|
if (pDM_Odm->SupportICType & ODM_RTL8197F)
|
|
ODM_SetBBReg(pDM_Odm, 0x9a0, 0xf00, AdcSmp->ADCSmpDmaDataSigSel); /*0x9A0[11:8]*/
|
|
else
|
|
ODM_SetBBReg(pDM_Odm , ODM_ADC_TRIGGER_Jaguar2, 0xf00, AdcSmp->ADCSmpDmaDataSigSel); /*0x95C[11:8]*/
|
|
|
|
ODM_Write1Byte(pDM_Odm, 0x7c0+1, AdcSmp->ADCSmpTriggerTime);
|
|
|
|
|
|
if (pDM_Odm->SupportICType & ODM_RTL8197F)
|
|
ODM_SetBBReg(pDM_Odm, 0xd00, BIT26, 0x1);
|
|
else { /*for 8814A and 8822B?*/
|
|
ODM_Write1Byte(pDM_Odm, 0x198c, 0x7);
|
|
ODM_Write1Byte(pDM_Odm, 0x8b4, 0x80);
|
|
}
|
|
|
|
if (AdcSmp->ADCSmpTrigSel == ADCSMP_MAC_TRIG) { /* trigger by MAC*/
|
|
if (TrigSigSel == ADCSMP_TRIG_REG) { /* manual trigger 0x7C0[5] = 0 -> 1*/
|
|
ODM_Write1Byte(pDM_Odm, 0x7c0, 0xCB); /*0x7C0[7:0]=8'b1100_1011*/
|
|
ODM_Write1Byte(pDM_Odm, 0x7c0, 0xEB); /*0x7C0[7:0]=8'b1110_1011*/
|
|
} else if (TrigSigSel == ADCSMP_TRIG_CCA)
|
|
ODM_Write1Byte(pDM_Odm, 0x7c0, 0x8B); /*0x7C0[7:0]=8'b1000_1011*/
|
|
else if (TrigSigSel == ADCSMP_TRIG_CRCFAIL)
|
|
ODM_Write1Byte(pDM_Odm, 0x7c0, 0x4B); /*0x7C0[7:0]=8'b0100_1011*/
|
|
else if (TrigSigSel == ADCSMP_TRIG_CRCOK)
|
|
ODM_Write1Byte(pDM_Odm, 0x7c0, 0x0B); /*0x7C0[7:0]=8'b0000_1011*/
|
|
} else { /*trigger by BB*/
|
|
if (pDM_Odm->SupportICType & ODM_RTL8197F)
|
|
ODM_SetBBReg(pDM_Odm, 0x9a0, 0x1f, TrigSigSel); /*0x9A0[4:0]*/
|
|
else
|
|
ODM_SetBBReg(pDM_Odm , ODM_ADC_TRIGGER_Jaguar2, 0x1f, TrigSigSel); /*0x95C[4:0], 0x1F: trigger by CCA*/
|
|
ODM_Write1Byte(pDM_Odm, 0x7c0, 0x03); /*0x7C0[7:0]=8'b0000_0011*/
|
|
}
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
|
|
watchdog_stop(pDM_Odm->priv);
|
|
#endif
|
|
|
|
/*Polling time always use 100ms, when it exceed 2s, break while loop*/
|
|
do {
|
|
tmpU1b = ODM_Read1Byte(pDM_Odm, 0x7c0);
|
|
|
|
if (AdcSmp->ADCSmpState != ADCSMP_STATE_SET) {
|
|
DbgPrint("ADCSmpState != ADCSMP_STATE_SET\n");
|
|
break;
|
|
|
|
} else if (tmpU1b & BIT1) {
|
|
ODM_delay_ms(100);
|
|
while_cnt = while_cnt + 1;
|
|
continue;
|
|
} else {
|
|
DbgPrint("%s Query OK\n", __func__);
|
|
if (pDM_Odm->SupportICType & ODM_RTL8197F)
|
|
ODM_SetBBReg(pDM_Odm, 0x7c0, BIT0, 0x0);
|
|
break;
|
|
}
|
|
} while (while_cnt < 20);
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
|
|
watchdog_resume(pDM_Odm->priv);
|
|
#if (RTL8197F_SUPPORT == 1)
|
|
if (pDM_Odm->SupportICType & ODM_RTL8197F) {
|
|
/*Stop DMA*/
|
|
backup_DMA = ODM_GetMACReg(pDM_Odm, 0x300, bMaskLWord);
|
|
ODM_SetMACReg(pDM_Odm, 0x300, 0x7fff, backup_DMA|0x7fff);
|
|
|
|
/*move LA mode content from IMEM to TxPktBuffer
|
|
Src : OCPBASE_IMEM 0x00000000
|
|
Dest : OCPBASE_TXBUF 0x18780000
|
|
Len : 64K*/
|
|
GET_HAL_INTERFACE(pDM_Odm->priv)->InitDDMAHandler(pDM_Odm->priv, OCPBASE_IMEM, OCPBASE_TXBUF, 0x10000);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
if (AdcSmp->ADCSmpState == ADCSMP_STATE_SET)
|
|
ADCSmp_GetTxPktBuf(pDM_Odm, Buffer);
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
|
|
if (pDM_Odm->SupportICType & ODM_RTL8197F)
|
|
ODM_SetMACReg(pDM_Odm, 0x300, 0x7fff, backup_DMA); /*Resume DMA*/
|
|
#endif
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
if (AdcSmp->ADCSmpState == ADCSMP_STATE_SET)
|
|
AdcSmp->ADCSmpState = ADCSMP_STATE_QUERY;
|
|
#endif
|
|
|
|
DbgPrint("%s Status %d\n", __func__, AdcSmp->ADCSmpState);
|
|
}
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
VOID
|
|
ADCSmpWorkItemCallback(
|
|
IN PVOID pContext
|
|
)
|
|
{
|
|
PADAPTER Adapter = (PADAPTER)pContext;
|
|
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
|
|
PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
|
|
PRT_ADCSMP AdcSmp = &(pDM_Odm->adcsmp);
|
|
|
|
ADCSmp_Start(pDM_Odm, AdcSmp);
|
|
ADCSmp_Stop(pDM_Odm);
|
|
}
|
|
#endif
|
|
|
|
VOID
|
|
ADCSmp_Set(
|
|
IN PVOID pDM_VOID,
|
|
IN RT_ADCSMP_TRIG_SEL TrigSel,
|
|
IN RT_ADCSMP_TRIG_SIG_SEL TrigSigSel,
|
|
IN u1Byte DmaDataSigSel,
|
|
IN u1Byte TriggerTime,
|
|
IN u2Byte PollingTime
|
|
)
|
|
{
|
|
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
|
|
BOOLEAN retValue = TRUE;
|
|
PRT_ADCSMP AdcSmp = &(pDM_Odm->adcsmp);
|
|
|
|
AdcSmp->ADCSmpTrigSel = TrigSel;
|
|
AdcSmp->ADCSmpTrigSigSel = TrigSigSel;
|
|
AdcSmp->ADCSmpDmaDataSigSel = DmaDataSigSel;
|
|
AdcSmp->ADCSmpTriggerTime = TriggerTime;
|
|
AdcSmp->ADCSmpPollingTime = PollingTime;
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
if (AdcSmp->ADCSmpState != ADCSMP_STATE_IDLE)
|
|
retValue = FALSE;
|
|
else if (AdcSmp->ADCSmpBuf.Length == 0)
|
|
retValue = ADCSmp_BufferAllocate(pDM_Odm->Adapter, AdcSmp);
|
|
#endif
|
|
|
|
if (retValue) {
|
|
AdcSmp->ADCSmpState = ADCSMP_STATE_SET;
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
ODM_ScheduleWorkItem(&(AdcSmp->ADCSmpWorkItem));
|
|
#else
|
|
ADCSmp_Start(pDM_Odm, AdcSmp);
|
|
#endif
|
|
}
|
|
|
|
DbgPrint("ADCSmpState %d Return Status %d\n", AdcSmp->ADCSmpState, retValue);
|
|
}
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
RT_STATUS
|
|
ADCSmp_Query(
|
|
IN PVOID pDM_VOID,
|
|
IN ULONG InformationBufferLength,
|
|
OUT PVOID InformationBuffer,
|
|
OUT PULONG BytesWritten
|
|
)
|
|
{
|
|
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
|
|
PRT_ADCSMP AdcSmp = &(pDM_Odm->adcsmp);
|
|
RT_STATUS retStatus = RT_STATUS_SUCCESS;
|
|
PRT_ADCSMP_STRING ADCSmpBuf = &(AdcSmp->ADCSmpBuf);
|
|
|
|
DbgPrint("%s ADCSmpState %d", __func__, AdcSmp->ADCSmpState);
|
|
|
|
if (InformationBufferLength != ADCSmpBuf->buffer_size) {
|
|
*BytesWritten = 0;
|
|
retStatus = RT_STATUS_RESOURCE;
|
|
} else if (ADCSmpBuf->Length != ADCSmpBuf->buffer_size) {
|
|
*BytesWritten = 0;
|
|
retStatus = RT_STATUS_RESOURCE;
|
|
} else if (AdcSmp->ADCSmpState != ADCSMP_STATE_QUERY) {
|
|
*BytesWritten = 0;
|
|
retStatus = RT_STATUS_PENDING;
|
|
} else {
|
|
ODM_MoveMemory(pDM_Odm, InformationBuffer, ADCSmpBuf->Octet, ADCSmpBuf->buffer_size);
|
|
*BytesWritten = ADCSmpBuf->buffer_size;
|
|
|
|
AdcSmp->ADCSmpState = ADCSMP_STATE_IDLE;
|
|
}
|
|
|
|
DbgPrint("Return Status %d\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
#endif
|
|
|
|
VOID
|
|
ADCSmp_Stop(
|
|
IN PVOID pDM_VOID
|
|
)
|
|
{
|
|
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
|
|
PRT_ADCSMP AdcSmp = &(pDM_Odm->adcsmp);
|
|
|
|
AdcSmp->ADCSmpState = ADCSMP_STATE_IDLE;
|
|
|
|
DbgPrint("%s status %d\n", __func__, AdcSmp->ADCSmpState);
|
|
}
|
|
|
|
VOID
|
|
ADCSmp_Init(
|
|
IN PVOID pDM_VOID
|
|
)
|
|
{
|
|
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
|
|
PRT_ADCSMP AdcSmp = &(pDM_Odm->adcsmp);
|
|
PRT_ADCSMP_STRING ADCSmpBuf = &(AdcSmp->ADCSmpBuf);
|
|
|
|
AdcSmp->ADCSmpState = ADCSMP_STATE_IDLE;
|
|
|
|
if (pDM_Odm->SupportICType & ODM_RTL8814A) {
|
|
ADCSmpBuf->start_pos = 0x30000;
|
|
ADCSmpBuf->buffer_size = 0x10000;
|
|
} else if (pDM_Odm->SupportICType & ODM_RTL8822B) {
|
|
ADCSmpBuf->start_pos = 0x20000;
|
|
ADCSmpBuf->buffer_size = 0x20000;
|
|
} else if (pDM_Odm->SupportICType & ODM_RTL8197F) {
|
|
ADCSmpBuf->start_pos = 0x00000;
|
|
ADCSmpBuf->buffer_size = 0x10000;
|
|
} else if (pDM_Odm->SupportICType & ODM_RTL8821C) {
|
|
ADCSmpBuf->start_pos = 0x8000;
|
|
ADCSmpBuf->buffer_size = 0x8000;
|
|
}
|
|
|
|
}
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
|
|
VOID
|
|
ADCSmp_DeInit(
|
|
IN PVOID pDM_VOID
|
|
)
|
|
{
|
|
PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
|
|
PRT_ADCSMP AdcSmp = &(pDM_Odm->adcsmp);
|
|
PRT_ADCSMP_STRING ADCSmpBuf = &(AdcSmp->ADCSmpBuf);
|
|
|
|
ADCSmp_Stop(pDM_Odm);
|
|
|
|
if (ADCSmpBuf->Length != 0x0) {
|
|
ODM_FreeMemory(pDM_Odm, ADCSmpBuf->Octet, ADCSmpBuf->Length);
|
|
ADCSmpBuf->Length = 0x0;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|