rtmp_init.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,988 行 · 第 1/5 页
C
1,988 行
pRxD = (PRXD_STRUC) pAdapter->RxRing.Cell[index].AllocVa;
pRxD->BufPhyAddr = pDmaBuf->AllocPa;
// Rx owner bit assign to NIC immediately
pRxD->Owner = DESC_OWN_NIC;
#ifdef BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
#endif
}
DBGPRINT(RT_DEBUG_TRACE, "Rx Ring: total %d entry allocated\n", index);
} while (FALSE);
DBGPRINT(RT_DEBUG_TRACE, "<-- RTMPAllocDMAMemory\n");
return 0;
}
/*
========================================================================
Routine Description:
Free all DMA memory.
Arguments:
Adapter Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
VOID RTMPFreeDMAMemory(
IN PRTMP_ADAPTER pAdapter)
{
INT index, num;
DBGPRINT(RT_DEBUG_TRACE, "--> RTMPFreeDMAMemory\n");
//
// Free RX Ring related space
//
for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
{
if ((pAdapter->RxRing.Cell[index].DmaBuf.AllocVa) && (pAdapter->RxRing.Cell[index].DmaBuf.pSkb))
{
pci_unmap_single(pAdapter->pPci_Dev, pAdapter->RxRing.Cell[index].DmaBuf.AllocPa, pAdapter->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
RELEASE_NDIS_PACKET(pAdapter, pAdapter->RxRing.Cell[index].DmaBuf.pSkb);
}
}
NdisZeroMemory(pAdapter->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
if (pAdapter->RxDescRing.AllocVa)
{
pci_free_consistent(pAdapter->pPci_Dev, pAdapter->RxDescRing.AllocSize,
pAdapter->RxDescRing.AllocVa, pAdapter->RxDescRing.AllocPa);
}
NdisZeroMemory(&pAdapter->RxDescRing, sizeof(RTMP_DMABUF));
//
// Free MGMT Ring related space
//
if (pAdapter->MgmtDescRing.AllocVa)
{
pci_free_consistent(pAdapter->pPci_Dev, pAdapter->MgmtDescRing.AllocSize,
pAdapter->MgmtDescRing.AllocVa, pAdapter->MgmtDescRing.AllocPa);
}
NdisZeroMemory(&pAdapter->MgmtDescRing, sizeof(RTMP_DMABUF));
//
// Free TX Ring buffer
//
for (num = 0; num < NUM_OF_TX_RING; num++)
{
if (pAdapter->TxBufSpace[num].AllocVa)
{
pci_free_consistent(pAdapter->pPci_Dev, pAdapter->TxBufSpace[num].AllocSize,
pAdapter->TxBufSpace[num].AllocVa, pAdapter->TxBufSpace[num].AllocPa);
}
NdisZeroMemory(&pAdapter->TxBufSpace[num], sizeof(RTMP_DMABUF));
if (pAdapter->TxDescRing[num].AllocVa)
{
pci_free_consistent(pAdapter->pPci_Dev, pAdapter->TxDescRing[num].AllocSize,
pAdapter->TxDescRing[num].AllocVa, pAdapter->TxDescRing[num].AllocPa);
}
NdisZeroMemory(&pAdapter->TxDescRing[num], sizeof(RTMP_DMABUF));
}
//
// Free preallocated shared memory
//
NdisFreeSpinLock(&pAdapter->TxSwQueueLock);
NdisFreeSpinLock(&pAdapter->RxRingLock);
NdisFreeSpinLock(&pAdapter->MgmtRingLock);
NdisFreeSpinLock(&pAdapter->TxRingLock);
DBGPRINT(RT_DEBUG_TRACE, "<-- RTMPFreeDMAMemory\n");
}
inline VOID NICDisableInterrupt(
IN PRTMP_ADAPTER pAdapter)
{
RTMP_IO_WRITE32(pAdapter, INT_MASK_CSR, 0xffffff7f); // 0xffffff7f
RTMP_IO_WRITE32(pAdapter, MCU_INT_MASK_CSR, 0xffffffff);
RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}
inline VOID NICEnableInterrupt(
IN PRTMP_ADAPTER pAdapter,
IN UINT32 int_mask)
{
#ifdef THREAD_ISR
/*
* mask out pendding interrupt bit
* interrupt aggregation : 0x0000fe90
*/
RTMP_IO_WRITE32(pAdapter, INT_MASK_CSR, 0x0000fe90 | int_mask);
#else
RTMP_IO_WRITE32(pAdapter, INT_MASK_CSR, 0x0000ff10 | int_mask); // 0x0000fe90(interrupt aggregation, can be test in embedded platform while bad throughput)
#endif
RTMP_IO_WRITE32(pAdapter, MCU_INT_MASK_CSR, 0x00000200); // 0x000001ff
RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}
/*
========================================================================
Routine Description:
Initialize transmit data structures
Arguments:
Adapter Pointer to our adapter
Return Value:
None
Note:
Initialize all transmit releated private buffer, include those define
in RTMP_ADAPTER structure and all private data structures.
========================================================================
*/
VOID NICInitTxRxRingAndBacklogQueue(
IN PRTMP_ADAPTER pAdapter)
{
DBGPRINT(RT_DEBUG_TRACE, "<--> NICInitTxRxRingAndBacklogQueue\n");
// Initialize all transmit related software queues
InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_BE]);
InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_BK]);
InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_VI]);
InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_VO]);
InitializeQueueHeader(&pAdapter->TxSwQueue[QID_HCCA]);
// Init RX Ring index pointer
pAdapter->RxRing.CurRxIndex = 0;
// Init TX rings index pointer
{
INT i;
for (i=0; i<NUM_OF_TX_RING; i++)
{
pAdapter->TxRing[i].CurTxIndex = 0;
pAdapter->TxRing[i].NextTxDmaDoneIndex = 0;
}
}
// init MGMT ring index pointer
pAdapter->MgmtRing.CurTxIndex = 0;
pAdapter->MgmtRing.NextTxDmaDoneIndex = 0;
pAdapter->PrivateInfo.TxRingFullCnt = 0;
}
/*
========================================================================
Routine Description:
Read initial parameters from EEPROM
Arguments:
Adapter Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
VOID NICReadEEPROMParameters(
IN PRTMP_ADAPTER pAd)
{
ULONG data;
USHORT i, value, value2;
EEPROM_TX_PWR_STRUC Power;
EEPROM_VERSION_STRUC Version;
EEPROM_ANTENNA_STRUC Antenna;
EEPROM_LED_STRUC LedSetting;
UCHAR AModeGainValue = 0;
DBGPRINT(RT_DEBUG_TRACE, "--> NICReadEEPROMParameters\n");
// Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
if(data & 0x20)
pAd->EEPROMAddressNum = 6; // 93C46
else
pAd->EEPROMAddressNum = 8; // 93C66
// RT2660 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
// MAC address registers according to E2PROM setting
{
USHORT Addr01,Addr23,Addr45 ;
MAC_CSR2_STRUC csr2;
MAC_CSR3_STRUC csr3;
Addr01=RTMP_EEPROM_READ16(pAd, 0x04);
Addr23=RTMP_EEPROM_READ16(pAd, 0x06);
Addr45=RTMP_EEPROM_READ16(pAd, 0x08);
pAd->CurrentAddress[0] = (UCHAR)(Addr01 & 0xff);
pAd->CurrentAddress[1] = (UCHAR)(Addr01 >> 8);
pAd->CurrentAddress[2] = (UCHAR)(Addr23 & 0xff);
pAd->CurrentAddress[3] = (UCHAR)(Addr23 >> 8);
pAd->CurrentAddress[4] = (UCHAR)(Addr45 & 0xff);
pAd->CurrentAddress[5] = (UCHAR)(Addr45 >> 8);
csr2.field.Byte0 = pAd->CurrentAddress[0];
csr2.field.Byte1 = pAd->CurrentAddress[1];
csr2.field.Byte2 = pAd->CurrentAddress[2];
csr2.field.Byte3 = pAd->CurrentAddress[3];
RTMP_IO_WRITE32(pAd, MAC_CSR2, csr2.word);
csr3.word = 0;
csr3.field.Byte4 = pAd->CurrentAddress[4];
csr3.field.Byte5 = pAd->CurrentAddress[5];
csr3.field.U2MeMask = 0xff;
RTMP_IO_WRITE32(pAd, MAC_CSR3, csr3.word);
// Prepare MBSSID's mac addr, the mac addr will be the E2PROM's mac addr plus 0,1,2,3 as MBSSID[0],MBSSID[1],MBSSID[2],MBSSID[3]'s mac addr
for(i = 0; i < MAX_MBSSID_NUM; i++)
{
BOOLEAN bCarry = FALSE;
INT j;
for (j = (MAC_ADDR_LEN-1); j >= 0; j--)
{
if (j == (MAC_ADDR_LEN-1))
{
if (((pAd->CurrentAddress[j]+i) & 0xFF) < pAd->CurrentAddress[j])
bCarry = TRUE;
else
bCarry = FALSE;
pAd->PortCfg.MBSSID[i].Bssid[j] = (pAd->CurrentAddress[j]+i) & 0xFF;
}
else
{
if (bCarry == TRUE)
{
if (((pAd->CurrentAddress[j]+1) & 0xFF) < pAd->CurrentAddress[j])
bCarry = TRUE;
else
bCarry = FALSE;
pAd->PortCfg.MBSSID[i].Bssid[j] = (pAd->CurrentAddress[j]+1) & 0xFF;
}
else
pAd->PortCfg.MBSSID[i].Bssid[j] = pAd->CurrentAddress[j];
}
}
DBGPRINT(RT_DEBUG_TRACE,"MBSSID[%d] MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", i,
pAd->PortCfg.MBSSID[i].Bssid[0], pAd->PortCfg.MBSSID[i].Bssid[1],
pAd->PortCfg.MBSSID[i].Bssid[2], pAd->PortCfg.MBSSID[i].Bssid[3],
pAd->PortCfg.MBSSID[i].Bssid[4], pAd->PortCfg.MBSSID[i].Bssid[5]);
}
}
// Init the channel number for TX channel power
NdisZeroMemory(pAd->TxPower, sizeof(pAd->TxPower));
// 0. 11b/g
for (i = 0; i < 14; i++)
pAd->TxPower[i].Channel = i + 1;
// 1. UNI 36 - 64
for (i = 0; i < 8; i++)
pAd->TxPower[i + 14].Channel = 36 + i * 4;
// 2. HipperLAN 2 100 - 140
for (i = 0; i < 11; i++)
pAd->TxPower[i + 22].Channel = 100 + i * 4;
// 3. UNI 140 - 165
for (i = 0; i < 5; i++)
pAd->TxPower[i + 33].Channel = 149 + i * 4;
// if E2PROM version mismatch with driver's expectation, then skip
// all subsequent E2RPOM retieval and set a system error bit to notify GUI
Version.word = RTMP_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET);
pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
DBGPRINT(RT_DEBUG_TRACE, "E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber);
if (Version.field.Version > VALID_EEPROM_VERSION)
{
DBGPRINT_ERR("E2PROM: WRONG VERSION %d, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION);
// hard-code default value when no proper E2PROM installed
pAd->bAutoTxAgcA = FALSE;
pAd->bAutoTxAgcG = FALSE;
// Default the channel power
for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
pAd->RfIcType = RFIC_5225;
for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
pAd->EEPROMDefaultValue[i] = 0xffff;
return;
}
// Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
{
value = RTMP_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2);
pAd->EEPROMDefaultValue[i] = value;
}
// We have to parse NIC configuration 0 at here.
// If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
// Therefore, we have to read TxAutoAgc control beforehand.
// Read Tx AGC control bit
Antenna.word = pAd->EEPROMDefaultValue[0];
if (Antenna.field.DynamicTxAgcControl == 1)
pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
else
pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
//
// Reset PhyMode if we don't support 802.11a
//
if ((pAd->PortCfg.PhyMode == PHY_11ABG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11A))
{
//
// Only RFIC_5225 & RFIC_5325 support 802.11a
//
if ((Antenna.field.RfIcType != RFIC_5225) && (Antenna.field.RfIcType != RFIC_5325))
pAd->PortCfg.PhyMode = PHY_11BG_MIXED;
}
// Read Tx power value for all channels
// Value from 1 - 0x7f. Default value is 24.
// 0. 11b/g
// Power value 0xFA (-6) ~ 0x24 (36)
for (i = 0; i < 7; i++)
{
Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2);
if ((Power.field.Byte0 > 36) || (Power.field.Byte0 < -6))
pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2].Power = Power.field.Byte0;
if ((Power.field.Byte1 > 36) || (Power.field.Byte1 < -6))
pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
}
// 1. UNI 36 - 64, HipperLAN 2 100 - 140, UNI 140 - 165
for (i = 0; i < 12; i++)
{
Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2);
if ((Power.field.Byte0 > 36) || (Power.field.Byte0 < -6))
pAd->TxPower[i * 2 + 14].Power = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2 + 14].Power = Power.field.Byte0;
if ((Power.field.Byte1 > 36) || (Power.field.Byte1 < -6))
pAd->TxPower[i * 2 + 15].Power = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2 + 15].Power = Power.field.Byte1;
}
// Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
// 0. 11b/g
{
Power.word = RTMP_EEPROM_READ16(pAd, 0x54);
pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
Power.word = RTMP_EEPROM_READ16(pAd, 0x56);
pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
Power.word = RTMP_EEPROM_READ16(pAd, 0x58);
pAd->TssiPlusBoundaryG[1] = Power.field.Byte0;
pAd->TssiPlusBoundaryG[2] = Power.field.Byte1;
Power.word = RTMP_EEPROM_READ16(pAd, 0x5a);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?