📄 am79c973.c
字号:
// Buffers must be aligned to 32 bytes boundary
offset = address & 0x1F;
if (offset != 0) {
address = address + 0x20 - offset;
size = size + 0x20 - offset;
}
// Check if buffer is big enough to accomodate all
buffers = TX_BUFFERS + RX_BUFFERS;
if (size < ((BUFFER_SIZE + DESC_SIZE) * buffers + INIT_SIZE)) {
OALMSGS(OAL_ERROR, (
L"ERROR: AM79C973InitDMABuffer: Buffer too small\r\n"
));
goto cleanUp;
}
// Store address and size
g_dmaAddress = (UINT32)OALCAtoUA(address);
g_dmaSize = size;
// Done
rc = TRUE;
cleanUp:
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973InitDMABuffer(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
BOOL AM79C973Init(UINT8 *pAddress, UINT32 offset, UINT16 mac[3])
{
BOOL rc = FALSE;
OALMSGS(OAL_ETHER&&OAL_FUNC, (
L"+AM79C973Init(0x%08x, 0x%08x, 0x%08x)\r\n", pAddress, offset, mac
));
g_base = (UINT32)pAddress;
if (!HWInit()) goto cleanUp;
// Set mac parameters
mac[0] = g_pInit[1] & 0xFFFF;
mac[1] = g_pInit[1] >> 16;
mac[2] = g_pInit[2] & 0xFFFF;
// Done
rc = TRUE;
cleanUp:
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973Init(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
VOID AM79C973PowerOff()
{
UINT32 exCtrl;
// First we must go to suspend mode
exCtrl = ReadCSR(5);
exCtrl |= 0x0001;
WriteCSR(5, exCtrl);
// Wait until we get there
while ((ReadCSR(5) & 0x0001) == 0) OALStall(10);
// Res
}
//------------------------------------------------------------------------------
VOID AM79C973PowerOn()
{
HWInit();
}
//------------------------------------------------------------------------------
UINT16 AM79C973SendFrame(UINT8 *pData, UINT32 length)
{
UINT32 start;
volatile UINT32 *pos;
OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
L"+AM79C973SendFrame(0x%08x, %d)\r\n", pData, length
));
// Check if packet fit to buffer
if (length > BUFFER_SIZE) return 1;
// Wait until buffer is done
pos = (volatile UINT32*)&g_pTxRing[g_txPos << 2];
// Wait for transmit buffer available
start = OALGetTickCount();
while ((pos[1] & TMD1_OWN) != 0) {
if ((OALGetTickCount() - start) > 2000) {
OALMSGS(OAL_ERROR, (L"ERROR: AM79C973SendFrame: Send timeout\r\n"));
return 1;
}
}
// Copy data to buffer
memcpy((VOID*)pos[3], pData, length);
pos[0] = 0;
pos[1] = TMD1_OWN|TMD1_STP|TMD1_ENP|TMD1_ONES|(4096 - length);
// Force controller to read tx descriptor
WriteCSR(0, (ReadCSR(0) & 0x0040) | 0x0008);
// Move to next possition
if (++g_txPos == TX_BUFFERS) g_txPos = 0;
OALMSGS(OAL_ETHER&&OAL_VERBOSE, (L"-RAM79C973SendFrame(rc = 0)\r\n"));
return 0;
}
//------------------------------------------------------------------------------
UINT16 AM79C973GetFrame(UINT8 *pData, UINT16 *pLength)
{
UINT32 rmd1, rmd2, length;
volatile UINT32 *pos;
OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
L"+AM79C973GetFrame(0x%08x, %d)\r\n", pData, *pLength
));
pos = (volatile UINT32 *)&g_pRxRing[g_rxPos << 2];
length = 0;
// Check if there is received frame
if ((ReadCSR(0) & 0x0400) != 0) {
// When packet is in buffer hardware doesn own descriptor
while (((rmd1 = pos[1]) & RMD1_OWN) == 0) {
rmd2 = pos[0];
// Is packet received ok?
length = rmd2 & 0x0FFF;
if (length > 4) length -= 4;
if ((rmd1 & RMD1_ERR) == 0 && length < *pLength) {
// Copy packet if there is no problem
memcpy(pData, (VOID*)pos[3], length);
} else {
OALMSGS(OAL_WARN, (
L"AM79C973GetFrame - %X/%X %d\n", rmd1, rmd2, *pLength
));
length = 0;
}
// Reinitialize descriptor
pos[0] = 0;
pos[1] = RMD1_OWN | RMD1_ONES | (4096 - BUFFER_SIZE);
// Move to next possition
if (++g_rxPos == RX_BUFFERS) g_rxPos = 0;
// Calculate position
pos = (volatile UINT32 *)&g_pRxRing[g_rxPos << 2];
// If this descriptor is owned by hardware clear interrupt
if ((pos[1] & RMD1_OWN) != 0) {
WriteCSR (0, (ReadCSR(0) & 0x0040) | 0x0400);
}
// If we get a packet break loop
if (length > 0) break;
}
}
// Return size
*pLength = (USHORT)length;
OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
L"-AM79C973GetFrame(length = %d)\r\n", length
));
return *pLength;
}
//------------------------------------------------------------------------------
void AM79C973EnableInts()
{
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"+AM79C973EnableInts\r\n"));
WriteCSR(3, ReadCSR(3) & 0xFBFF); // clear RINT mask
WriteCSR(0, 0x40);
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973EnableInts\r\n"));
}
//------------------------------------------------------------------------------
void AM79C973DisableInts()
{
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"+AM79C973DisableInts\r\n"));
WriteCSR(0, 0);
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973DisableInts\r\n"));
}
//------------------------------------------------------------------------------
VOID AM79C973CurrentPacketFilter(UINT32 filter)
{
UINT32 exCtrl, mode;
OALMSGS(OAL_ETHER&&OAL_FUNC, (
L"+AM79C973CurrentPacketFilter(0x%08x)\r\n", filter
));
// First we must go to suspend mode
exCtrl = ReadCSR(5);
exCtrl |= 0x0001;
WriteCSR(5, exCtrl);
// Wait until we get there
while ((ReadCSR(5) & 0x0001) == 0) OALStall(10);
// Just assume that we always receive direct & broadcast packets
if ((filter & PACKET_TYPE_ALL_MULTICAST) != 0) {
WriteCSR(8, 0xFFFF);
WriteCSR(9, 0xFFFF);
WriteCSR(10, 0xFFFF);
WriteCSR(11, 0xFFFF);
} else if ((filter & PACKET_TYPE_MULTICAST) == 0) {
WriteCSR(8, 0);
WriteCSR(9, 0);
WriteCSR(10, 0);
WriteCSR(11, 0);
}
mode = ReadCSR(15);
if ((filter & PACKET_TYPE_PROMISCUOUS) != 0) {
mode |= MODE_PROM;
} else {
mode &= ~MODE_PROM;
}
WriteCSR(15, mode);
// It is time to leave suspend mode
exCtrl = ReadCSR(5);
exCtrl &= ~0x0001;
WriteCSR(5, exCtrl);
// Wait until we get there
while ((ReadCSR(5) & 0x0001) != 0) OALStall(10);
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973CurrentPacketFilter\r\n"));
}
//------------------------------------------------------------------------------
BOOL AM79C973MulticastList(UINT8 *pAddresses, UINT32 count)
{
ULONG exCtrl, crc;
ULONG i, j, bit;
USHORT h[4];
OALMSGS(OAL_ETHER&&OAL_FUNC, (
L"+AM79C973MulticastList(0x%08x, %d)\r\n", pAddresses, count
));
// Calculate hash bits
h[0] = h[1] = h[2] = h[3] = 0;
for (i = 0; i < count; i++) {
crc = HashAddress(pAddresses);
bit = 0;
for (j = 0; j < 6; j++) bit = (bit << 1) + ((crc >> j) & 0x01);
h[bit >> 4] |= 1 << (bit & 0x0F);
pAddresses += ADDR_SIZE;
}
// Go to suspend mode
exCtrl = ReadCSR(5);
exCtrl |= 0x0001;
WriteCSR(5, exCtrl);
// Wait until we get there
while ((ReadCSR(5) & 0x0001) == 0) OALStall(10);
// And set hardware
WriteCSR(8, h[0]);
WriteCSR(9, h[1]);
WriteCSR(10, h[2]);
WriteCSR(11, h[3]);
// Leave suspend mode
exCtrl = ReadCSR(5);
exCtrl &= ~0x0001;
WriteCSR(5, exCtrl);
// Wait until we get there
while ((ReadCSR(5) & 0x0001) != 0) OALStall(10);
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973MulticastList(rc = 1)\r\n"));
return TRUE;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -