📄 mac.c
字号:
// Initialize MAC Controller
void MacInitialize(int num)
{
//UART_printf("MacInitialize()\n");
if (num==0)
{
// MAC interrupt vector setup.
SetIntISR(EMCTXINT0, MAC0_Tx_isr) ;
SetIntISR(EMCRXINT0, MAC0_Rx_isr) ;
// Set the Tx and Rx Frame Descriptor
TxFDInitialize(num) ;
RxFDInitialize(num) ;
// Set the CAM Control register and the MAC address value
FillCamEntry(0, 0, gCam0M_0, gCam0L_0);
CAMCMR_0 = gCAMCMR ;
// Enable MAC Tx and Rx interrupt.
Enable_Int(EMCTXINT0);
Enable_Int(EMCRXINT0);
// Configure the MAC control registers.
ReadyMac(num) ;
}
else if (num==1)
{
// MAC interrupt vector setup.
SetIntISR(EMCTXINT1, MAC1_Tx_isr) ;
SetIntISR(EMCRXINT1, MAC1_Rx_isr) ;
// Set the Tx and Rx Frame Descriptor
TxFDInitialize(num) ;
RxFDInitialize(num) ;
// Set the CAM Control register and the MAC address value
FillCamEntry(1, 0, gCam0M_1, gCam0L_1);
CAMCMR_1 = gCAMCMR ;
// Enable MAC Tx and Rx interrupt.
Enable_Int(EMCTXINT1);
Enable_Int(EMCRXINT1);
// Configure the MAC control registers.
ReadyMac(num) ;
}
}
// Initialize Tx frame descriptor area-buffers.
void TxFDInitialize(int num)
{
sFrameDescriptor *pFrameDescriptor;
sFrameDescriptor *pStartFrameDescriptor;
sFrameDescriptor *pLastFrameDescriptor = NULL;
U32 FrameDataAddr;
U32 i;
if (num==0)
{
// Get Frame descriptor's base address.
TXDLSA_0 = (U32)TxFDBaseAddr0;
gWTxFDPtr[0] = gCTxFDPtr[0] = TXDLSA_0;
// Get Transmit buffer base address.
FrameDataAddr = (U32)TxFBABaseAddr0;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[0];
pStartFrameDescriptor = pFrameDescriptor;
for(i=0; i < MaxTxFrameDescriptors; i++)
{
if (pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else
pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;
pFrameDescriptor->Status1 = 0;
pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
pFrameDescriptor->Status2 = (U32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
pLastFrameDescriptor = pFrameDescriptor;
pFrameDescriptor++;
FrameDataAddr += sizeof(sMACFrame);
}
// Make Frame descriptor to ring buffer type.
pFrameDescriptor--;
pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
}
else if (num==1)
{
// Get Frame descriptor's base address.
TXDLSA_1 = (U32)TxFDBaseAddr1;
gWTxFDPtr[1] = gCTxFDPtr[1] = TXDLSA_1;
// Get Transmit buffer base address.
FrameDataAddr = (U32)TxFBABaseAddr1;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[1];
pStartFrameDescriptor = pFrameDescriptor;
for(i=0; i < MaxTxFrameDescriptors; i++)
{
if (pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else
pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;
pFrameDescriptor->Status1 = 0;
pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
pFrameDescriptor->Status2 = (U32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
pLastFrameDescriptor = pFrameDescriptor;
pFrameDescriptor++;
FrameDataAddr += sizeof(sMACFrame);
}
// Make Frame descriptor to ring buffer type.
pFrameDescriptor--;
pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
}
}
// Initialize Rx frame descriptor area-buffers.
void RxFDInitialize(int num)
{
sFrameDescriptor *pFrameDescriptor;
sFrameDescriptor *pStartFrameDescriptor;
sFrameDescriptor *pLastFrameDescriptor = NULL;
U32 FrameDataAddr;
U32 i;
if (num==0)
{
// Get Frame descriptor's base address.
RXDLSA_0 = (U32)RxFDBaseAddr0;
gCRxFDPtr[0] = RXDLSA_0;
// Get Transmit buffer base address.
FrameDataAddr = (U32)RxFBABaseAddr0;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCRxFDPtr[0];
pStartFrameDescriptor = pFrameDescriptor;
for(i=0; i < MaxRxFrameDescriptors; i++)
{
if (pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else
pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;
pFrameDescriptor->Status1 = RXfOwnership_DMA;
pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
pFrameDescriptor->Status2 = (U32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
pLastFrameDescriptor = pFrameDescriptor;
pFrameDescriptor++;
FrameDataAddr += sizeof(sMACFrame);
}
// Make Frame descriptor to ring buffer type.
pFrameDescriptor--;
pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
}
else if (num==1)
{
// Get Frame descriptor's base address.
RXDLSA_1 = (U32)RxFDBaseAddr1;
gCRxFDPtr[1] = RXDLSA_1;
// Get Transmit buffer base address.
FrameDataAddr = (U32)RxFBABaseAddr1;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCRxFDPtr[1];
pStartFrameDescriptor = pFrameDescriptor;
for(i=0; i < MaxRxFrameDescriptors; i++)
{
if (pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else
pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;
pFrameDescriptor->Status1 = RXfOwnership_DMA;
pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
pFrameDescriptor->Status2 = (U32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
pLastFrameDescriptor = pFrameDescriptor;
pFrameDescriptor++;
FrameDataAddr += sizeof(sMACFrame);
}
// Make Frame descriptor to ring buffer type.
pFrameDescriptor--;
pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
}
}
// set Registers related with MAC.
void ReadyMac(int num)
{
if (num==0)
{
if (EXTERNAL_LOOPBACK_PORT == 0)
{
MIEN_0 = gMIEN | EnTDU | EnTXEMP | EnRXOV | EnCRCE | EnRDU;
MCMDR_0 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_ALP | MCMDR_ARP;
}
else
{
MIEN_0 = gMIEN ;
//MCMDR_0 = gMCMDR ;
//CMN
MCMDR_0 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_SPCRC;
}
}
else if (num==1)
{
if (EXTERNAL_LOOPBACK_PORT == 1)
{
MIEN_1 = gMIEN | EnTDU | EnTXEMP | EnRXOV | EnCRCE | EnRDU;
//MCMDR_0 = gMCMDR ;
//CMN
//Collect ANY packet (Runt, Long and CRC error) !!!
MCMDR_1 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_ALP | MCMDR_ARP;
}
else
{
MIEN_1 = gMIEN ;
MCMDR_1 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_SPCRC;
}
}
}
// MAC Transfer Start for interactive mode
void MacTxGo(int num)
{
if (num==0)
{
if (!(MCMDR_0&MCMDR_TXON))
MCMDR_0 |= MCMDR_TXON ;
TSDR_0 = 0;
}
else if (num==1)
{
if (!(MCMDR_1&MCMDR_TXON))
MCMDR_1 |= MCMDR_TXON ;
TSDR_1 = 0;
}
}
// Mac Rx Off and disable all interrupts
void MacRxOff(int num)
{
if (num==0)
MCMDR_0 &= ~MCMDR_RXON ;
else
MCMDR_1 &= ~MCMDR_RXON ;
}
//CMN
void CheckTxFDStatus(int port, sFrameDescriptor *pTxFDptr)
{
U32 Status;
Status = (pTxFDptr->Status2 >> 16) & 0xffff;
if (Status & TXFD_TXCP)
{
gsMacTxStatus[port].TXCP++ ;
gsMacTxStatus[port].TxBytes += pTxFDptr->Status2 & 0xFFFF;
TxPktSeq = *((volatile U32 *) (pTxFDptr->FrameDataPtr + 16));
if (TxPktSeq != TxPktSeqWanted)
{
*((volatile unsigned int *) 0xFFF03210) = 0x43;
TxPktSeqErr++;
TxPktSeqWanted = TxPktSeq+1;
}
else
TxPktSeqWanted++;
}
else
gTxErrPacketCnt[port]++;
// Save Error status
if (Status & TXFD_TXABT) gsMacTxStatus[port].TXABT++ ;
if (Status & TXFD_DEF) gsMacTxStatus[port].DEF++ ;
if (Status & TXFD_PAU) gsMacTxStatus[port].PAU++ ;
if (Status & TXFD_EXDEF) gsMacTxStatus[port].EXDEF++ ;
if (Status & TXFD_NCS) gsMacTxStatus[port].NCS++ ;
if (Status & TXFD_SQE) gsMacTxStatus[port].SQE++ ;
if (Status & TXFD_LC) gsMacTxStatus[port].LC++ ;
if (Status & TXFD_TXHA) gsMacTxStatus[port].TXHA++ ;
pTxFDptr->Status2 &= (U32) 0x0000FFFF;
gCTxFDPtr[port] = (U32)pTxFDptr->NextFrameDescriptor ;
}
// Interrupt Service Routine for MAC0 Tx
void MAC0_Tx_isr(void)
{
sFrameDescriptor *pTxFDptr;
U32 *pFrameDataPtr ;
U32 Status, RdValue;
U32 CTxPtr ;
RdValue=MISTA_0;
if (RdValue & 0x00800000)
gsMacTxStatus[0].TDU++;
if (RdValue & 0x00020000)
gsMacTxStatus[0].EMP++;
MISTA_0=RdValue&0xffff0000;
#ifdef TxInt_Msg
UART_printf("MAC0_Tx_isr(%x)\n",RdValue) ;
#endif
if (RdValue & MISTA_TxBErr)
{
FIFOTHD_0|=SWR;
LanInitialize(0);
MacRxDoneFlagForLoopBackCheck[0] = 1 ;
gsMacTxStatus[0].TxBErr++ ; //CMN
}
else
{
CTxPtr = CTXDSA_0 ;
while ( gCTxFDPtr[0] != CTxPtr )
{
pTxFDptr = (sFrameDescriptor *) gCTxFDPtr[0];
// Check CPU ownership, if Owner is DMA then break
pFrameDataPtr = (U32 *)&pTxFDptr->Status1;
if ( (*pFrameDataPtr & TXfOwnership_DMA) )
break ;
Status = (pTxFDptr->Status2 >> 16) & 0xffff;
if (Status & TXFD_TXCP)
{
gsMacTxStatus[0].TXCP++ ;
gsMacTxStatus[0].TxBytes += pTxFDptr->Status2 & 0xFFFF; //CMN
#if 1
if (EXTERNAL_LOOPBACK_PORT == 0)
{
TxPktSeq = *((volatile U32 *) (pTxFDptr->FrameDataPtr + 16));
if (TxPktSeq != TxPktSeqWanted)
{
TxPktSeqErr++;
TxPktSeqWanted = TxPktSeq+1;
}
else
TxPktSeqWanted++;
}
#endif
}
else
gTxErrPacketCnt[0]++;
// Save Error status
if (Status & TXFD_TXABT) gsMacTxStatus[0].TXABT++ ;
if (Status & TXFD_DEF) gsMacTxStatus[0].DEF++ ;
if (Status & TXFD_PAU) gsMacTxStatus[0].PAU++ ;
if (Status & TXFD_EXDEF) gsMacTxStatus[0].EXDEF++ ;
if (Status & TXFD_NCS) gsMacTxStatus[0].NCS++ ;
if (Status & TXFD_SQE) gsMacTxStatus[0].SQE++ ;
if (Status & TXFD_LC) gsMacTxStatus[0].LC++ ;
if (Status & TXFD_TXHA) gsMacTxStatus[0].TXHA++ ;
// Clear Framedata pointer already used.
pTxFDptr->Status2 &= (U32) 0x0000FFFF;
gCTxFDPtr[0] = (U32)pTxFDptr->NextFrameDescriptor ;
}
MacTxDoneFlagForLoopBackCheck[0] = 1 ;
}
}
// Interrupt Service Routine for MAC1 Tx
void MAC1_Tx_isr(void)
{
sFrameDescriptor *pTxFDptr;
U32 *pFrameDataPtr ;
U32 Status, RdValue;
U32 CTxPtr ;
RdValue=MISTA_1;
if (RdValue & 0x00800000)
gsMacTxStatus[1].TDU++;
if (RdValue & 0x00020000)
gsMacTxStatus[1].EMP++;
MISTA_1=RdValue&0xffff0000;
#ifdef TxInt_Msg
UART_printf("MAC1_Tx_isr(%x)\n",RdValue) ;
#endif
if (RdValue & MISTA_TxBErr)
{
FIFOTHD_1|=SWR;
LanInitialize(1);
MacTxDoneFlagForLoopBackCheck[1] = 1 ;
gsMacTxStatus[1].TxBErr++;
}
else
{
CTxPtr = CTXDSA_1 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -