📄 dec21140.c
字号:
// We'll get into this loop only if we keep getting the descriptor in this while...
// localDEBUGMSG ("DEC21140SendFrame()::: Error Tx Loop Back...\r\n");
// Just forget about the whole sending and reset current descriptor to the first one...
pCurrentTxDesc = pFirstTxDescriptor;
return DEC21140_ERROR_TX_LOOPBACK;
}
// Remember the first descriptor...
if (pFirstTxDescriptor == (PTX_DESCRIPTOR_FORMAT) NULL)
pFirstTxDescriptor = pCurrentTxDesc;
dwNumberOfDescriptorUsed++;
if ((dwLength - dwTotalSent) > MAX_BUFFER_SIZE)
dwToSend = MAX_BUFFER_SIZE;
else
dwToSend = dwLength - dwTotalSent;
//localDEBUGMSG ("DEC21140SendFrame()::: Obtained descriptor %d - Filling: %d bytes.\r\n",
// (pCurrentTxDesc - pTxDesc), dwToSend);
memcpy ((PVOID)TO_VIRT(pCurrentTxDesc->TDES2), pbData + dwTotalSent, dwToSend);
pCurrentTxDesc->TDES1.Buffer1Size = dwToSend;
dwTotalSent += dwToSend;
// Advance to next descriptor...
pCurrentTxDesc = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pCurrentTxDesc->TDES3);
}
//printf ("NumberOfDescriptorUsed = %d\r\n", dwNumberOfDescriptorUsed);
// Now, let's update the descriptors...
while (i++ < dwNumberOfDescriptorUsed)
{
// If it is first segment, mark it, otherwise unmarked it.
// This descriptor may have been used in previous sending...
if (i == 1)
pFirstTxDescriptor->TDES1.FirstSegment = 1;
else
pFirstTxDescriptor->TDES1.FirstSegment = 0;
// Ditto for last segment.
if (i == dwNumberOfDescriptorUsed)
pFirstTxDescriptor->TDES1.LastSegment = 1;
else
pFirstTxDescriptor->TDES1.LastSegment = 0;
// Let 21140 owns it now... It will reset this when the buffer has been
// successfully sent...
if (i == 1)
{
// Don't release the descriptor yet until the complete frame is done.
pRememberingTheVeryFirstDescriptor = pFirstTxDescriptor;
}
else
pFirstTxDescriptor->TDES0.dwReg |= ~DESC_OWNED_BY_HOST;
// Advance to next descriptor...
pFirstTxDescriptor = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pFirstTxDescriptor->TDES3);
}
// Rock n Roll time...
pRememberingTheVeryFirstDescriptor->TDES0.dwReg |= ~DESC_OWNED_BY_HOST;
CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
CSR6.StartTransmit = 1;
WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);
WRITE_PORT_ULONG(CSR1_REG, 0xffffffff);
/*
for (;;)
{
int i = 1000000;
printf ("TDES0 = 0x%x \r\n", pRememberingTheVeryFirstDescriptor->TDES0.dwReg);
while (i--)
;
}
*/
return 0x00;
}
/////////////////////////////////////////////////////////////////////////////////
// DEC21140QueryBufferSize() & DEC21140QueryDescriptorSize()
// Caller can use these functions to figure out how many descriptors and buffer
// that can fit into its budget.
// DEC21140QueryBufferSize() simply returns the constant used by this libary in
// determining the size of each buffer.
// DEC21140QueryDescriptorSize() will return size of TX_DESCRIPTOR_FORMAT.
// These two dimensions can change, and caller should make sure that it uses these
// functions in determining the number of descriptor that the library can use.
//
DWORD DEC21140QueryBufferSize (void)
{
return MAX_BUFFER_SIZE;
} // DEC21140QueryBufferSize()
DWORD DEC21140QueryDescriptorSize (void)
{
return sizeof(TX_DESCRIPTOR_FORMAT);
} // DEC21140QueryDescriptorSize()
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// Misc Utility functions:
// DumpTxDescriptor()
// DumpRxDescriptor()
// DumpMemory()
//
/////////////////////////////////////////////////////////////////////////////////
// DumpTxDescriptor()
//
#ifdef __DEC21140_DUMP_TX_DESCRIPTOR__
static void DumpTxDescriptor (PTX_DESCRIPTOR_FORMAT pTxHead)
{
PTX_DESCRIPTOR_FORMAT pTxDesc;
int dwCount = 0;
pTxDesc = pTxHead;
localDEBUGMSG ("+-------- Dumping TX descriptor --------+\r\n");
localDEBUGMSG ("pTxHead = 0x%x \r\n", pTxHead);
while (1)
{
localDEBUGMSG ("%d ---> ", dwCount++);
localDEBUGMSG ("Addr = 0x%x | ", pTxDesc);
localDEBUGMSG ("T0 = 0x%x |", pTxDesc->TDES0.dwReg);
localDEBUGMSG ("T1 = 0x%x |", pTxDesc->TDES1.dwReg);
localDEBUGMSG ("T2 = 0x%x |", pTxDesc->TDES2);
localDEBUGMSG ("T3 = 0x%x \r\n", pTxDesc->TDES3);
if (TO_VIRT(pTxDesc->TDES3) == (DWORD) pTxHead)
{
// This must be the last descriptor before we loop back...
break;
}
else
pTxDesc = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pTxDesc->TDES3);
}
}
#endif // __DEC21140_DUMP_TX_DESCRIPTOR__
/////////////////////////////////////////////////////////////////////////////////
// DumpRxDescriptor()
//
#ifdef __DEC21140_DUMP_RX_DESCRIPTOR__
static void DumpRxDescriptor (PRX_DESCRIPTOR_FORMAT pRxHead)
{
PRX_DESCRIPTOR_FORMAT pRxDesc;
int dwCount = 0;
pRxDesc = pRxHead;
localDEBUGMSG ("+-------- Dumping RX descriptor --------+\r\n");
localDEBUGMSG ("pRxHead = 0x%x \r\n", pRxHead);
while (1)
{
localDEBUGMSG ("%d ---> ", dwCount++);
localDEBUGMSG ("Addr = 0x%x | ", pRxDesc);
localDEBUGMSG ("R0 = 0x%x |", pRxDesc->RDES0.dwReg);
localDEBUGMSG ("R1 = 0x%x |", pRxDesc->RDES1.dwReg);
localDEBUGMSG ("R2 = 0x%x |", pRxDesc->RDES2);
localDEBUGMSG ("R3 = 0x%x \r\n", pRxDesc->RDES3);
if (TO_VIRT(pRxDesc->RDES3) == (DWORD) pRxHead)
{
// This must be the last descriptor before we loop back...
break;
}
else
pRxDesc = (PRX_DESCRIPTOR_FORMAT) TO_VIRT(pRxDesc->RDES3);
}
} // DumpRxDescriptor()
#endif // __DEC21140_DUMP_RX_DEXCRIPTOR__
/////////////////////////////////////////////////////////////////////////////////
// DumpMemory()
//
#ifdef __DEC21140_DUMP_MEMORY__
//localDEBUGMSG ("0x%x\t", *pSource++);
void DisplayHex (BYTE data)
{
localDEBUGMSG ("0x");
if (data < 0x10)
localDEBUGMSG ("0");
localDEBUGMSG ("%x ", data);
} // DisplayHex()
void DumpMemory (PBYTE pSource, DWORD dwLength)
{
int i = 0;
localDEBUGMSG ("+---- MEM DUMP ----+\r\n");
localDEBUGMSG ("0x%x: ", pSource);
while (dwLength--)
{
DisplayHex (*pSource++);
if (++i == 16)
{
i = 0;
localDEBUGMSG ("\r\n0x%x: ", pSource);
}
}
localDEBUGMSG ("\r\n\r\n");
} // DumpMemory()
#endif // __DEC21140_DUMP_MEMORY__
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
WORD
EEPROMReadWord( BYTE bAddress )
{
UCHAR nCnt = 0;
CSR9_21140 localCSR9;
USHORT nVal = 0;
localCSR9.dwReg = 0;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg); // Clear.
Delay(100);
localCSR9.SerialRomSelect = 1; // Read from SROM.
localCSR9.ReadOperation = 1;
localCSR9.MiiManagementOperationMode = 1;
localCSR9.BootRomDataOrSerialRomCtrl = 0x001; // Setup.
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(100);
localCSR9.BootRomDataOrSerialRomCtrl = 0x011;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x001;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x101; // Command phase.
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x111;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x101;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x111;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x101;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x001;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x011;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x001;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
// Address phase.
for (nCnt = 0 ; nCnt < 8 ; nCnt++) // Assume a 2Kb - 4Kb SROM part (8 bits)
{
nVal = (USHORT)(((bAddress << nCnt) & 0x80) >> 5);
localCSR9.BootRomDataOrSerialRomCtrl = (0x001 | nVal);
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = (0x011 | nVal);
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = (0x001 | nVal);
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
}
Delay(1000);
// Data phase.
for (nCnt = 0, nVal = 0 ; nCnt < 16 ; nCnt++) // Data is 16-bits wide.
{
localCSR9.BootRomDataOrSerialRomCtrl = 0x011;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
nVal |= ((READ_PORT_ULONG(CSR9_REG) & 0x00000008) >> 3);
if (nCnt < (16 - 1))
nVal = nVal << 1;
Delay(1000);
localCSR9.BootRomDataOrSerialRomCtrl = 0x001;
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
}
localCSR9.BootRomDataOrSerialRomCtrl = 0x000; // Complete transaction.
WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
Delay(1000);
localDEBUGMSG("EEPROMReadWord: Address=0x%x Data=0x%x\r\n", bAddress, nVal);
return(nVal);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
EEPROMReadMAC(WORD *wMAC)
{
int i = 0;
for (i = 0; i < 3; i++)
{
wMAC[i] = EEPROMReadWord((BYTE)(i + 10)); // MAC address is 20 bytes
// (10 words) into SROM.
}
return(TRUE);
}
BOOL
DEC21140SetMACAddress(PUSHORT pMacAddr)
{
int n = 0;
PBYTE pDst = NULL;
PBYTE pSrc = NULL;
// Make a copy of the MAC address...
pSrc = (PBYTE)pMacAddr;
pDst = pbEthernetAddr;
for (n = 6; n ; n--)
{
*pDst++ = *pSrc++;
}
localDEBUGMSG ("INFO: Set DEC21140 MAC to %x-%x-%x", pbEthernetAddr[0], pbEthernetAddr[1], pbEthernetAddr[2]);
localDEBUGMSG ("-%x-%x-%x\r\n", pbEthernetAddr[3], pbEthernetAddr[4], pbEthernetAddr[5]);
return(TRUE);
}
void DEC21140CurrentPacketFilter(DWORD dwFilter)
{
CSR6_21140 CSR6;
// read the original value of CSR6
CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
// update the bits of interest
CSR6.PassAllMulticast = (dwFilter & PACKET_TYPE_ALL_MULTICAST)? 1 : 0;
CSR6.PromiscuousMode = (dwFilter & PACKET_TYPE_PROMISCUOUS)? 1 : 0;
// ignore other filter settings.
#if 0
localDEBUGMSG ("\nINFO: dwFilter = %s | %s, CSR6 = 0x%x\n",
(dwFilter & PACKET_TYPE_ALL_MULTICAST)? "ALLMULTICAST" : "NONE",
(dwFilter & PACKET_TYPE_PROMISCUOUS)? "PROMISCUOUS" : "NONE",
CSR6.dwReg
);
#endif
// update CSR6
WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);
}
BOOL DEC21140MulticastList (PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
#if 0
localDEBUGMSG ("INFO: pucMulticastAddresses = 0x%x | dwNoOfAddresses = %d\n", pucMulticastAddresses, dwNoOfAddresses);
#endif
return pucMulticastAddresses? DEC21140SetupPerfectFilter(pucMulticastAddresses, dwNoOfAddresses) : FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -