📄 am79c970.c
字号:
dwTotalCopied += dwBytesToCopy;
/////////////////////////////////////////////////////////////////////////
// See if I can proceed to next descriptor, if not do something to
// speed up the sending (error or whatever).
// If so, proceed to the next descriptor...
//
pNextTxDesc = GetNextTxDesc (pCurrentTxDesc);
while (pNextTxDesc->TMD1.OWN)
{
/////////////////////////////////////////////////////////////////////
// Need to do something here to figure out why sending is halted.
// Seems like we have loop back one round and data is still not
// yet sent... FM-FM-FM-FM
// For now just hang on here till I get the next descriptor...
//
// localDEBUGMSG ("Waiting for TX descriptor number = %d --- Last Descriptor = %d\r\n",
// pNextTxDesc - (PTX_DESCRIPTOR_FORMAT) dwTRANSMIT_DESCRIPTORS_HEAD,
// pLastTxDesc - (PTX_DESCRIPTOR_FORMAT) dwTRANSMIT_DESCRIPTORS_HEAD);
SleepLoop(10000000);
}
/////////////////////////////////////////////////////////////////////////
// If we get here means that we have secured next descriptor...
// Let's proceed...
// But before that, let's update all other fields in the descriptors.
// The only field we can't update is the OWN bit for the first descriptor..
//
if (pCurrentTxDesc == pFirstTxDesc)
pCurrentTxDesc->TMD1.STP = 0x01;
else
pCurrentTxDesc->TMD1.OWN = 0x01;
if (dwBytesToCopy < MAX_BUFFER_SIZE)
pCurrentTxDesc->TMD1.ENP = 0x01;
pCurrentTxDesc->TMD1.BCNT = SECOND_COMP(dwBytesToCopy);
pCurrentTxDesc = pNextTxDesc;
/////////////////////////////////////////////////////////////////////////
// Make sure we set the descriptor to a known state...
//
InitTxDescriptor (pCurrentTxDesc, 0);
}
/////////////////////////////////////////////////////////////////////////////
// Now that all the data been copied to the buffer, it's BOOGIE time...
//
pFirstTxDesc->TMD1.OWN = 0x01;
WriteCSR (0, ReadCSR(0) | CSR0_TDMD);
/////////////////////////////////////////////////////////////////////////////
// Oh well, the previous libraries need to return zero when sending
// successfully...
//
return 0;
} // AM79C970SendFrame()
/////////////////////////////////////////////////////////////////////////////////
// AM79C970InitTxDescriptor()
//
// Caller tells us where the descriptors and buffers should live.
// One descriptor should have one buffer.
// Hence the dwTotalTx applies to both decriptors and buffers.
// Furthermore, the size of buffer is fixed at MAX_BUFFER_SIZE.
// It is caller's responsibility to allocate enough memory...
// Note: Caller can use AM79C970QueryBufferSize() to find out the size of buffer
// used for each buffer and hence calculate the Total Buffer that can be
// allocated...
// AM79C970QueryDescriptorSize() will return size of descriptor...
// Input:
// - TxHead = Location where TX descriptors start (Physical or Virtual Address).
// - TxBuffSize = Size of buffer allocated by caller.
// - bVirt = Whether or not the address is Physical or Virtual.
// Bootloader and Ethdbg run in Kernel mode and hence will have this
// set to FALSE.
// However, NDIS mini driver may run in user mode and hence this
// library MAY need to use virtual address to access the
// descriptors and buffers...
// Provided the virtual address, the library will figure out the
// actual physical address...
//
// WARNING: IT IS CALLER RESPONSIBILITY TO GIVE PROPER DATA.
// NO SANITY CHECK HERE !!!
// THIS IS ONLY FOR INTERNAL USAGE...
//
//
void AM79C970InitTxDescriptor(DWORD TxHead, DWORD TxBuffSize, BOOL bVirt)
{
if (bVirt)
{
/////////////////////////////////////////////////////////////////////////
// Need to convert the virtual addresses to physical addresses.
// This library runs in user mode (example: NDIS).
//
localDEBUGMSG ("AM79C970InitTxDescriptor::: Getting physical addresses...NOT IMPLEMENTED.\r\n");
}
else
{
/////////////////////////////////////////////////////////////////////////
// Easy... Simply use the provided addresses and size to fit the
// maximum number of buffer and descriptors we can...
// We must have been called from Bootloader or Ethdbg.
//
BOOL bDone = FALSE;
int i = 1;
DWORD dwCostOfOneBuffer = sizeof(TX_DESCRIPTOR_FORMAT) + MAX_BUFFER_SIZE;
/////////////////////////////////////////////////////////////////////////
// Calculate the max number of descriptor + buffer that I can have
// for the given size and stuff the result to global variables used by
// this library..
//
i = TxBuffSize / dwCostOfOneBuffer;
dwTRANSMIT_DESCRIPTORS_HEAD = TxHead;
dwTRANSMIT_BUFFER_START = TxHead + i * sizeof(TX_DESCRIPTOR_FORMAT);
dwTRANSMIT_RING_SIZE = i;
localDEBUGMSG ("AM79C970InitTxDescriptor::: dwTRANSMIT_DESCRIPTORS_HEAD = 0x%x...\r\n", dwTRANSMIT_DESCRIPTORS_HEAD);
localDEBUGMSG ("AM79C970InitTxDescriptor::: dwTRANSMIT_BUFFER_START = 0x%x...\r\n", dwTRANSMIT_BUFFER_START);
localDEBUGMSG ("AM79C970InitTxDescriptor::: dwTRANSMIT_RING_SIZE = 0x%x...\r\n", dwTRANSMIT_RING_SIZE);
}
} // AM79C970InitTxDescriptor()
/////////////////////////////////////////////////////////////////////////////////
// AM79C970InitRxDescriptor()
// See AM79C970InitTxDescriptor()
//
void AM79C970InitRxDescriptor(DWORD RxHead, DWORD RxBuffSize, BOOL bVirt)
{
if (bVirt)
{
/////////////////////////////////////////////////////////////////////////
// Need to convert the virtual addresses to physical addresses.
// This library runs in user mode (example: NDIS).
//
localDEBUGMSG ("DEC21140InitRxDescriptor::: Getting physical addresses... NOT IMPLEMENTED !!!\r\n");
}
else
{
// Easy... Simply use the provided addresses and size to fit the maximum
// number of buffer and descriptors we can...
// We must have been called from Bootloader or Ethdbg.
BOOL bDone = FALSE;
int i = 1;
DWORD dwCostOfOneBuffer = sizeof(RX_DESCRIPTOR_FORMAT) + MAX_BUFFER_SIZE;
/////////////////////////////////////////////////////////////////////////
// Calculate the max number of descriptor + buffer that I can have
// for the given size and stuff the result to global variables used by
// this library..
//
i = RxBuffSize / dwCostOfOneBuffer;
dwRECEIVE_DESCRIPTORS_HEAD = RxHead;
dwRECEIVE_BUFFER_START = RxHead + i * sizeof(RX_DESCRIPTOR_FORMAT);
dwRECEIVE_RING_SIZE = i;
localDEBUGMSG ("AM79C970InitRxDescriptor::: dwRECEIVE_DESCRIPTORS_HEAD = 0x%x...\r\n", dwRECEIVE_DESCRIPTORS_HEAD);
localDEBUGMSG ("AM79C970InitRxDescriptor::: dwRECEIVE_BUFFER_START = 0x%x...\r\n", dwRECEIVE_BUFFER_START);
localDEBUGMSG ("AM79C970InitRxDescriptor::: dwRECEIVE_RING_SIZE = 0x%x...\r\n", dwRECEIVE_RING_SIZE);
}
} // AM79C970InitRxDescriptor()
/////////////////////////////////////////////////////////////////////////////////
// AM79C970QueryDescriptorSize(void) and AM79C970QueryBufferSize(void)
//
// Caller can use these functions to figure out how many descriptors and buffer
// that can fit into its budget.
// These two dimensions can change in the libary, caller should make sure that
// it uses these functions in determining the number of descriptor that this
// library will use given subsequent InitTxDescriptor() and InitRxDescriptor()
// calls.
//
DWORD AM79C970QueryDescriptorSize(void)
{
return sizeof(TX_DESCRIPTOR_FORMAT);
} // AM79C970QueryRxDescriptor()
DWORD AM79C970QueryBufferSize(void)
{
return MAX_BUFFER_SIZE;
} // AM79C970QueryDescriptorSize()
//------------------------------------------------------------------------------
BOOL AM79C970InitDMABuffer(UINT32 address, UINT32 size)
{
UINT32 ulHalfBufferSize = size >> 1;
AM79C970InitTxDescriptor(address, ulHalfBufferSize, FALSE);
AM79C970InitRxDescriptor(address+ulHalfBufferSize, ulHalfBufferSize, FALSE);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////
// Dump utilities...
//
/////////////////////////////////////////////////////////////////////////////////
// Dump TX descriptors...
//
void DumpOneTxDescriptor (PTX_DESCRIPTOR_FORMAT pTxDesc)
{
localDEBUGMSG ("TMD2 = 0x%x --- TMD1 = 0x%x --- Buffer = 0x%x \r\n",
pTxDesc->TMD2.dwReg, pTxDesc->TMD1.dwReg, pTxDesc->TBADR);
} // DumpOneTxDescriptor()
void DumpTxDescriptors()
{
PTX_DESCRIPTOR_FORMAT pTxDesc;
UINT i;
pTxDesc = (PTX_DESCRIPTOR_FORMAT) dwTRANSMIT_DESCRIPTORS_HEAD;
for (i = 0 ; i < dwTRANSMIT_RING_SIZE ; i++)
DumpOneTxDescriptor((PTX_DESCRIPTOR_FORMAT)(pTxDesc + i));
} // DumpTxDescriptors()
/////////////////////////////////////////////////////////////////////////////////
// DumpRxDescriptors...
//
void DumpOneRxDescriptor (PRX_DESCRIPTOR_FORMAT pRxDesc)
{
localDEBUGMSG ("RMD2 = 0x%x --- RMD1 = 0x%x --- Buffer = 0x%x \r\n",
pRxDesc->RMD2.dwReg, pRxDesc->RMD1.dwReg, pRxDesc->RBADR);
} // DumpOneTxDescriptor()
void DumpRxDescriptors()
{
PRX_DESCRIPTOR_FORMAT pRxDesc;
UINT i;
pRxDesc = (PRX_DESCRIPTOR_FORMAT) dwRECEIVE_DESCRIPTORS_HEAD;
for (i = 0 ; i < dwRECEIVE_RING_SIZE ; i++)
DumpOneRxDescriptor((PRX_DESCRIPTOR_FORMAT)(pRxDesc + i));
} // DumpRxDescriptors()
/////////////////////////////////////////////////////////////////////////////////
// Other dumps...
//
void AmdDisplayHex (BYTE data)
{
//localDEBUGMSG ("0x");
if (data < 0x10)
localDEBUGMSG ("0");
localDEBUGMSG ("%x ", data);
} // DisplayHex()
static void DumpMemory (PBYTE pSource, DWORD dwLength)
{
int i = 0;
localDEBUGMSG ("+---- MEM DUMP (%d bytes)----+\r\n", dwLength);
localDEBUGMSG ("0x%x: ", pSource);
while (dwLength--)
{
AmdDisplayHex (*pSource++);
if (++i == 16)
{
i = 0;
localDEBUGMSG ("\r\n0x%x: ", pSource);
}
}
localDEBUGMSG ("\r\n\r\n");
} // DumpMemory()
void PrintAddr (BYTE bData)
{
if (bData < 10)
localDEBUGMSG ("0");
localDEBUGMSG ("%x", bData);
}
void DumpSenderAddr (PBYTE pData)
{
PrintAddr (*pData++);
PrintAddr (*pData++);
PrintAddr (*pData++);
PrintAddr (*pData++);
PrintAddr (*pData++);
PrintAddr (*pData++);
localDEBUGMSG ("\r\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -