📄 bcm11dbg.c
字号:
// Stop the DMA channel
SETPORT32(&g_bcm11.pRxDmaRegs->CFG, DMA_CFG_STALL);
while ((INPORT32(&g_bcm11.pRxDmaRegs->CFG) & DMA_CFG_STALL) == 0);
OUTPORT32(&g_bcm11.pRxDmaRegs->CFG, DMA_CFG_HALT);
while ((INPORT32(&g_bcm11.pRxDmaRegs->CFG) & DMA_CFG_ENABLE) != 0);
// Disable interrupts
CLRPORT32(&g_bcm11.pIntcRegs->MASK, 1 << IRQ_DMA_EMAC_RX);
// Operate in chaining mode with wrapping controlled by length register
OUTPORT32(&g_bcm11.pRxDmaRegs->CFG, DMA_CFG_CHAIN);
// Set max burst length
OUTPORT32(&g_bcm11.pRxDmaRegs->MAXBURST, RX_BURST_MAX);
// Set descriptor info
OUTPORT32(&g_bcm11.pRxDmaRegs->ADDRESS, OALVAtoPA(g_bcm11.pRxDescFirst));
OUTPORT32(&g_bcm11.pRxDmaRegs->LENGTH, g_bcm11.rxBuffers);
// Interested in packet interrupts
OUTPORT32(&g_bcm11.pRxDmaRegs->INTMASK, DMA_INT_PDONE);
OUTPORT32(&g_bcm11.pRxDmaRegs->INTSTAT, DMA_INT_PDONE);
// Set misc info
OUTPORT32(&g_bcm11.pRxDmaRegs->STATUS, 0);
OUTPORT32(&g_bcm11.pRxDmaRegs->FLOW_CTRL_TH, 0);
OUTPORT32(&g_bcm11.pRxDmaRegs->FLOW_CTRL_LEN, 0);
// Enable operation
SETPORT32(&g_bcm11.pRxDmaRegs->CFG, DMA_CFG_ENABLE);
rc = TRUE;
cleanUp:
CHECKCOOKIE(3);
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-BCM11EdbgInit(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
UINT16 BCM11EdbgSendFrame(UINT8 *pData, UINT32 length)
{
UINT16 status;
OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
L"+BCM11EdbgSendFrame(0x%08x, %d)\r\n", pData, length
));
CHECKCOOKIE(4);
// Wait until actual position is busy
while ((INREG32(&g_bcm11.pTxDescPos->status) & SWAP16(DMA_DESC_OWN)) != 0);
// Check if packet has minimal size
if (
length < MAC_TYPE_OFFSET || length >= (TX_BUFFER_SIZE - MAC_TYPE_SIZE)
) {
OALMSGS(OAL_ERROR, (L"ERROR: BCM11EdbgSendFrame: "
L"Incorrect packet length %d\r\n", length
));
return 1;
}
memcpy(g_bcm11.pTxBufferPos, pData, MAC_TYPE_OFFSET);
memcpy(
g_bcm11.pTxBufferPos + MAC_TYPE_OFFSET + MAC_TYPE_SIZE,
pData + MAC_TYPE_OFFSET, length - MAC_TYPE_OFFSET
);
if (length < 64) {
memset(g_bcm11.pTxBufferPos + MAC_TYPE_SIZE + length, 0xff, 64 - length);
length = 64;
}
// Set TX DMA descriptor
length += MAC_TYPE_SIZE;
status = DMA_DESC_OWN|DMA_DESC_SOP|DMA_DESC_EOP|DMA_DESC_ETHCRC;
g_bcm11.pTxDescPos->length = SWAP16(length);
g_bcm11.pTxDescPos->status = SWAP16(status);
// Start transmission
SETREG32(&g_bcm11.pTxDmaRegs->CFG, DMA_CFG_ENABLE);
// Move to next buffer position
g_bcm11.pTxDescPos++;
g_bcm11.pTxBufferPos += TX_BUFFER_SIZE;
if (g_bcm11.pTxDescPos > g_bcm11.pTxDescLast) {
g_bcm11.pTxDescPos = g_bcm11.pTxDescFirst;
g_bcm11.pTxBufferPos = g_bcm11.pTxBuffers;
}
CHECKCOOKIE(5);
OALMSGS(OAL_ETHER&&OAL_VERBOSE, (L"-BCM11EdbgSendFrame(rc = 0)\r\n"));
return 0;
}
//------------------------------------------------------------------------------
UINT16 BCM11EdbgGetFrame(UINT8 *pData, UINT16 *pLength)
{
UINT32 length;
CHECKCOOKIE(6);
length = 0;
while ((INREG32(&g_bcm11.pRxDescPos->status) & SWAP16(DMA_DESC_OWN)) == 0) {
length = SWAP16(g_bcm11.pRxDescPos->length);
if (length > 2 * MAC_CRC_SIZE + MAC_TYPE_SIZE) {
// Fix length
length -= 2 * MAC_CRC_SIZE + MAC_TYPE_SIZE;
// When packet fits to buffer copy it, else skip
if (length <= *pLength) {
memcpy(pData, g_bcm11.pRxBufferPos, MAC_TYPE_OFFSET);
memcpy(
pData + MAC_TYPE_OFFSET,
g_bcm11.pRxBufferPos + MAC_TYPE_OFFSET + MAC_TYPE_SIZE,
length - MAC_TYPE_OFFSET
);
} else {
length = 0;
}
} else {
length = 0;
}
// Return descriptor to ring
g_bcm11.pRxDescPos->length = SWAP16(RX_BUFFER_SIZE);
g_bcm11.pRxDescPos->status = SWAP16(DMA_DESC_OWN);
// Start DMA in case it is stopped
SETREG32(&g_bcm11.pRxDmaRegs->CFG, DMA_CFG_ENABLE);
// Move to next descriptor
if (++g_bcm11.pRxDescPos <= g_bcm11.pRxDescLast) {
g_bcm11.pRxBufferPos += RX_BUFFER_SIZE;
} else {
g_bcm11.pRxDescPos = g_bcm11.pRxDescFirst;
g_bcm11.pRxBufferPos = g_bcm11.pRxBuffers;
}
// Clear interrupt
OUTREG32(&g_bcm11.pRxDmaRegs->INTSTAT, DMA_INT_PDONE);
// If length is non zero we get a packet
if (length > 0) break;
}
CHECKCOOKIE(7);
*pLength = (USHORT)length;
return *pLength;
}
//------------------------------------------------------------------------------
VOID BCM11EdbgEnableInts()
{
SETPORT32(&g_bcm11.pIntcRegs->MASK, 1 << IRQ_DMA_EMAC_RX);
}
//------------------------------------------------------------------------------
VOID BCM11EdbgDisableInts()
{
CLRPORT32(&g_bcm11.pIntcRegs->MASK, 1 << IRQ_DMA_EMAC_RX);
}
//------------------------------------------------------------------------------
VOID BCM11EdbgCurrentPacketFilter(UINT32 filter)
{
// Disable multicast & broadcast
CLRREG32(&g_bcm11.pEthRegs->CTRL_SMP, CTRL_SMP_BCST|CTRL_SMP_MCST);
if ((filter & PACKET_TYPE_ALL_MULTICAST) != 0) {
// Enable multicast flooding
SETREG32(&g_bcm11.pEthRegs->CTRL_SMP, CTRL_SMP_MCST);
}
if ((filter & PACKET_TYPE_BROADCAST) != 0) {
// Enable broadcast flooding
SETREG32(&g_bcm11.pEthRegs->CTRL_SMP, CTRL_SMP_BCST);
}
}
//------------------------------------------------------------------------------
BOOL BCM11EdbgMulticastList(UINT8 *pAddresses, UINT32 count)
{
UINT32 i;
// Add multicast address as static entry to ARL table
for (i = 0; i < count; i++) {
arlWrite((UINT16*)pAddresses, 10, TRUE, TRUE, FALSE);
pAddresses += MAC_ADDR_SIZE;
}
return TRUE;
}
//------------------------------------------------------------------------------
static UINT8 reverseByte(UINT8 data)
{
UINT8 result, mask;
result = 0;
for (mask = 0x80; mask != 0; mask >>= 1) {
result >>= 1;
if ((data & mask) != 0) result |= 0x80;
}
return result;
}
//------------------------------------------------------------------------------
static VOID ssramWrite(UINT32 address, UINT32 hiData, UINT32 loData)
{
BCM11_ETH_REGS *pEthRegs = OALPAtoUA(BCM11_ETH_REGS_PA);
// make sure that address isn't too big
address &= 0x1FFF;
// set data
OUTREG32(&pEthRegs->SSRAM_DATA_LSW, loData);
OUTREG32(&pEthRegs->SSRAM_DATA_MSW, hiData);
// put SSRAM into read mode
OUTREG32(&pEthRegs->SSRAM_ADDR, 0);
// set SSRAM address
OUTREG32(&pEthRegs->SSRAM_ADDR, address);
// start read
OUTREG32(&pEthRegs->SSRAM_ADDR, SSRAM_START|address);
// wait for read done
while ((INREG32(&pEthRegs->SSRAM_ADDR) & SSRAM_START) != 0);
}
//------------------------------------------------------------------------------
static VOID ssramRead(UINT32 address, UINT32 *pHiData, UINT32 *pLoData)
{
BCM11_ETH_REGS *pEthRegs = OALPAtoUA(BCM11_ETH_REGS_PA);
// make sure that address isn't too big
address &= 0x1FFF;
// put SSRAM into read mode
OUTREG32(&pEthRegs->SSRAM_ADDR, SSRAM_READ);
// set SSRAM address
OUTREG32(&pEthRegs->SSRAM_ADDR, SSRAM_READ|address);
// start read
OUTREG32(&pEthRegs->SSRAM_ADDR, SSRAM_READ|SSRAM_START|address);
// wait for read done
while ((INREG32(&pEthRegs->SSRAM_ADDR) & SSRAM_START) != 0);
// read data
*pLoData = INREG32(&pEthRegs->SSRAM_DATA_LSW);
*pHiData = INREG32(&pEthRegs->SSRAM_DATA_MSW);
}
//------------------------------------------------------------------------------
static VOID arlInit()
{
UINT32 i, address;
// Clear ARL
for (i = 0; i < SSRAM_ARL_ENTRIES; i++) {
address = ((i & 0x03E0) << 3)|0x00E0|(i & 0x001F);
ssramWrite(address, 0, 0);
}
}
//------------------------------------------------------------------------------
//
// This function write to entry 0 only, entry 1 is cleared....
//
static VOID arlWrite(
UINT16 mac[3], UINT32 port, BOOL valid, BOOL stat, BOOL learn
) {
BCM11_ETH_REGS *pEthRegs = OALPAtoUA(BCM11_ETH_REGS_PA);
UINT32 hi, lo, opt;
UINT32 i;
UINT16 mcx[3];
// First reverse MAC address bits & swap half words
for (i = 0; i < 3; i++) {
mcx[i] = reverseByte(mac[i] & 0xFF) << 8;
mcx[i] |= reverseByte(mac[i] >> 8) & 0xFF;
}
// Then prepare values for write
hi = mcx[0];
lo = (mcx[1] << 16) | mcx[2];
// Calculate options
opt = ARLA_VALID|((port & 0xF) << 16);
if (stat) opt |= ARLA_STATIC;
if (learn) opt |= ARLA_AGE;
// Write it to entry 0
OUTREG32(&pEthRegs->ARLA_ENTRY0_LSW, lo);
OUTREG32(&pEthRegs->ARLA_ENTRY0_MSW, hi | opt);
OUTREG32(&pEthRegs->ARLA_ENTRY1_LSW, 0);
OUTREG32(&pEthRegs->ARLA_ENTRY1_MSW, 0);
OUTREG32(&pEthRegs->ARLA_ADDR_LSW, lo);
OUTREG32(&pEthRegs->ARLA_ADDR_MSW, hi);
// Start write
OUTREG32(&pEthRegs->ARLA_RW, ARLA_RW_START|ARLA_RW_WRITE);
// Wait until finished
while ((INREG32(&pEthRegs->ARLA_RW) & ARLA_RW_START) != 0);
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -