📄 bcm11dbg.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// File: bcm11dbg.c
//
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <ethdbg.h>
#include <oal.h>
#include <bcm11.h>
//------------------------------------------------------------------------------
#define SWAP32(x) ( \
(((x)&0xff000000)>>24)|(((x)&0x00ff0000)>>8)| \
(((x)&0x0000ff00)<<8)|(((x)&0x000000ff)<<24) \
)
#define SWAP16(x) ((((x)&0xff00)>>8)|(((x)&0x00ff)<<8))
//------------------------------------------------------------------------------
#define CHECKCOOKIE(x) \
if ( \
g_bcm11.pCookie[0] != 0x17011964 || g_bcm11.pCookie[1] != 0x25111964 || \
g_bcm11.pCookie[2] != 0x01020304 || g_bcm11.pCookie[3] != 0x05060708 \
) { \
OALMSGS(OAL_ERROR, ( \
L"COOKIE problem %08x %08x %08x %08x @%d\r\n", g_bcm11.pCookie[0], \
g_bcm11.pCookie[1], g_bcm11.pCookie[2], g_bcm11.pCookie[3], x \
)); \
g_bcm11.pCookie[0] = 0x17011964; \
g_bcm11.pCookie[1] = 0x25111964; \
g_bcm11.pCookie[2] = 0x01020304; \
g_bcm11.pCookie[3] = 0x05060708; \
}
//------------------------------------------------------------------------------
#define MAC_ADDR_SIZE 6
#define MAC_TYPE_OFFSET 12
#define MAC_TYPE_SIZE 6
#define MAC_TYPE_BRCM 0x8874
#define MAC_CRC_SIZE 4
#define TX_BUFFER_SIZE 1536
#define TX_BUFFERS 4
#define RX_BUFFER_SIZE 1536
#define RX_BUFFERS 12
#define RX_BURST_MAX 8
#define TX_BURST_MAX 8
//------------------------------------------------------------------------------
typedef struct {
UINT32 dmaAddress;
UINT32 dmaSize;
BCM11_ETH_REGS *pEthRegs;
BCM11_INTC_REGS *pIntcRegs;
UINT32 txBuffers;
BCM11_DMA_DESC *pTxDescFirst;
BCM11_DMA_DESC *pTxDescLast;
BCM11_DMA_DESC *pTxDescPos;
UINT8 *pTxBuffers;
UINT8 *pTxBufferPos;
BCM11_DMA_REGS *pTxDmaRegs;
UINT32 rxBuffers;
BCM11_DMA_DESC *pRxDescFirst;
BCM11_DMA_DESC *pRxDescLast;
BCM11_DMA_DESC *pRxDescPos;
UINT8 *pRxBuffers;
UINT8 *pRxBufferPos;
BCM11_DMA_REGS *pRxDmaRegs;
UINT16 mac[3];
UINT32 *pCookie;
} BCM11DBG;
static BCM11DBG g_bcm11;
//------------------------------------------------------------------------------
// Local Functions;
static VOID ssramWrite(UINT32 address, UINT32 hiData, UINT32 loData);
static VOID ssramRead(UINT32 address, UINT32 *pHiData, UINT32 *pLoData);
static VOID arlInit();
static VOID arlWrite(
UINT16 mac[3], UINT32 port, BOOL valid, BOOL stat, BOOL learn
);
//------------------------------------------------------------------------------
BOOL BCM11EdbgInitDMABuffer(UINT32 address, UINT32 size)
{
BOOL rc = FALSE;
UINT32 offset, minSize, txSize, rxSize, dmaBuffer, i;
BCM11_DMA_DESC *pDmaDesc;
UINT16 *pTag;
OALMSGS(OAL_ETHER&&OAL_FUNC, (
L"+BCM11EdbgInitDMABuffer(0x%08x, 0x%08x)\r\n", address, size
));
// Allign buffers to 4 bytes boundary
offset = address & 0x03;
if (offset != 0) {
address = address + 0x04 - offset;
size = size + 0x04 - offset;
}
g_bcm11.pCookie = OALCAtoUA((VOID*)address);
g_bcm11.pCookie[0] = 0x17011964;
g_bcm11.pCookie[1] = 0x25111964;
g_bcm11.pCookie[2] = 0x01020304;
g_bcm11.pCookie[3] = 0x05060708;
address += 0x10;
size -= 0x10;
CHECKCOOKIE(0);
// Get tx & tx buffer size per packet
txSize = sizeof(BCM11_DMA_DESC) + TX_BUFFER_SIZE;
rxSize = sizeof(BCM11_DMA_DESC) + RX_BUFFER_SIZE;
minSize = txSize * TX_BUFFERS + txSize * RX_BUFFERS;
// If need at least one packet for send and one for receive
if (size < minSize) {
OALMSGS(OAL_ERROR, (
L"ERROR: BCM11EdbgInitDMABuffer: Too small buffer (min size %d)\r\n",
minSize
));
goto cleanUp;
}
// Divide buffer to descriptors & buffers
g_bcm11.dmaAddress = OALVAtoPA((VOID*)address);
g_bcm11.dmaSize = size;
g_bcm11.txBuffers = TX_BUFFERS;
g_bcm11.rxBuffers = (size - txSize * TX_BUFFERS)/rxSize;
g_bcm11.pTxDescFirst = OALCAtoUA((VOID*)address);
address += sizeof(BCM11_DMA_DESC) * g_bcm11.txBuffers;
g_bcm11.pTxBuffers = OALCAtoUA((VOID*)address);
address += TX_BUFFER_SIZE * g_bcm11.txBuffers;
g_bcm11.pRxDescFirst = OALCAtoUA((VOID*)address);
address += sizeof(BCM11_DMA_DESC) * g_bcm11.rxBuffers;
g_bcm11.pRxBuffers = OALCAtoUA((VOID*)address);
address += RX_BUFFER_SIZE * g_bcm11.rxBuffers;
// Set up the TX DMA descriptor data & Broadcom tag in the buffer
pDmaDesc = g_bcm11.pTxDescFirst;
dmaBuffer = OALVAtoPA(g_bcm11.pTxBuffers);
for (i = 0; i < g_bcm11.txBuffers; i++) {
pDmaDesc->status = 0;
pDmaDesc->length = 0;
pDmaDesc->buffer = SWAP32(dmaBuffer);
pTag = OALPAtoUA(dmaBuffer + MAC_TYPE_OFFSET);
pTag[0] = SWAP16(MAC_TYPE_BRCM);
pTag[1] = 0;
pTag[2] = 0;
pDmaDesc++;
dmaBuffer += TX_BUFFER_SIZE;
}
pDmaDesc--;
g_bcm11.pTxDescLast = pDmaDesc;
g_bcm11.pTxDescPos = g_bcm11.pTxDescFirst;
g_bcm11.pTxBufferPos = g_bcm11.pTxBuffers;
// Set up the RX DMA descriptor ring
pDmaDesc = g_bcm11.pRxDescFirst;
dmaBuffer = OALVAtoPA(g_bcm11.pRxBuffers);
for (i = 0; i < g_bcm11.rxBuffers; i++) {
pDmaDesc->length = SWAP16(RX_BUFFER_SIZE);
pDmaDesc->status = SWAP16(DMA_DESC_OWN);
pDmaDesc->buffer = SWAP32(dmaBuffer);
pDmaDesc++;
dmaBuffer += RX_BUFFER_SIZE;
}
// Close ring
pDmaDesc--;
pDmaDesc->status = SWAP16(DMA_DESC_OWN|DMA_DESC_WRAP);
g_bcm11.pRxDescLast = pDmaDesc;
g_bcm11.pRxDescPos = g_bcm11.pRxDescFirst;
g_bcm11.pRxBufferPos = g_bcm11.pRxBuffers;
// We are done
rc = TRUE;
cleanUp:
CHECKCOOKIE(1);
OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-BCM11EdbgInitDMABuffer(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
BOOL BCM11EdbgInit(UINT8 *pAddress, UINT32 offset, UINT16 mac[3])
{
BOOL rc = FALSE;
OALMSGS(OAL_ETHER&&OAL_FUNC, (
L"+BCM11EdbgInit(0x%X, 0x%X, %02x:%02x:%02x:%02x:%02x:%02x)\r\n",
pAddress, offset, mac[0]&0xFF, mac[0]>>8, mac[1]&0xFF, mac[1]>>8,
mac[2]&0xFF, mac[2]>>8
));
CHECKCOOKIE(2);
// Address must be correct
if (pAddress != OALPAtoUA(BCM11_ETH_REGS_PA)) {
OALMSGS(OAL_ERROR, (
L"ERROR: BCM11EdbgInit: Invalid device address\r\n"
));
goto cleanUp;
}
// And DMA buffer must be initialized
if (g_bcm11.dmaSize == 0) {
OALMSGS(OAL_ERROR, (
L"ERROR: BCM11EdbgInit: Invalid DMA buffer size\r\n"
));
goto cleanUp;
}
// Save registers virtual addresses
g_bcm11.pEthRegs = OALPAtoUA(BCM11_ETH_REGS_PA);
g_bcm11.pIntcRegs = OALPAtoUA(BCM11_INTC_REGS_PA);
// Save MAC address
g_bcm11.mac[0] = mac[0];
g_bcm11.mac[1] = mac[1];
g_bcm11.mac[2] = mac[2];
// Enable ethernet chip clock
SETREG32(&g_bcm11.pIntcRegs->CHIP_CTRL, INTC_CHIP_ETH);
// Check BIST results
if (INREG32(&g_bcm11.pEthRegs->STAT_BIST) != 0) {
OALMSG(OAL_ERROR, (L"ERROR: BCM11EdbgInit: BIST error\r\n"));
goto cleanUp;
}
// Enable gamma 1/8 for both MII port
SETPORT16(&g_bcm11.pEthRegs->PORT0_MII_RSVD4, 1 << 1);
SETPORT16(&g_bcm11.pEthRegs->PORT1_MII_RSVD4, 1 << 1);
// Clear ARL
arlInit();
// Configure SMP as the management port
OUTPORT32(&g_bcm11.pEthRegs->MGMT_GLB, MGMT_GLB_PORT_SMP);
OUTPORT32(&g_bcm11.pEthRegs->MGMT_PORTID, MGMT_PORTID_SMP);
// Enable span tree
OUTPORT32(&g_bcm11.pEthRegs->CTRL_PORT0, CTRL_STATE_FORWARDING);
OUTPORT32(&g_bcm11.pEthRegs->CTRL_PORT1, CTRL_STATE_FORWARDING);
OUTPORT32(&g_bcm11.pEthRegs->CTRL_MODE, CTRL_MODE_FWD_EN);
SETPORT32(&g_bcm11.pEthRegs->CTRL_MODE, CTRL_MODE_FWD_MANAGE);
// Reset MIB
SETPORT32(&g_bcm11.pEthRegs->MGMT_GLB, MGMT_GLB_RST_MIB);
CLRPORT32(&g_bcm11.pEthRegs->MGMT_GLB, MGMT_GLB_RST_MIB);
// No MIB autocast
OUTPORT32(&g_bcm11.pEthRegs->MIBA_PORT, 0);
// Enable broadcast
SETPORT32(&g_bcm11.pEthRegs->CTRL_SMP, CTRL_SMP_BCST);
// Add own MAC address as static entry to ARL table
arlWrite(mac, 10, TRUE, TRUE, FALSE);
// Set Tx DMA registers
g_bcm11.pTxDmaRegs = OALPAtoUA(BCM11_DMA_EMAC_TX_REGS_PA);
// Stop the DMA channel
SETPORT32(&g_bcm11.pTxDmaRegs->CFG, DMA_CFG_STALL);
while ((INPORT32(&g_bcm11.pTxDmaRegs->CFG) & DMA_CFG_STALL) == 0);
OUTPORT32(&g_bcm11.pTxDmaRegs->CFG, DMA_CFG_HALT);
while ((INPORT32(&g_bcm11.pTxDmaRegs->CFG) & DMA_CFG_ENABLE) != 0);
// Disable interrupts
CLRPORT32(&g_bcm11.pIntcRegs->MASK, 1 << IRQ_DMA_EMAC_TX);
// Operate in chaining mode with wrapping controlled by length register
OUTPORT32(&g_bcm11.pTxDmaRegs->CFG, DMA_CFG_CHAIN);
// Set max burst length
OUTPORT32(&g_bcm11.pTxDmaRegs->MAXBURST, TX_BURST_MAX);
// Set descriptor info
OUTPORT32(&g_bcm11.pTxDmaRegs->ADDRESS, OALVAtoPA(g_bcm11.pTxDescFirst));
OUTPORT32(&g_bcm11.pTxDmaRegs->LENGTH, g_bcm11.txBuffers);
// Not interested in any interrupt
OUTPORT32(&g_bcm11.pTxDmaRegs->INTMASK, 0);
// Set misc info
OUTPORT32(&g_bcm11.pTxDmaRegs->STATUS, 0);
OUTPORT32(&g_bcm11.pTxDmaRegs->FLOW_CTRL_TH, 0);
OUTPORT32(&g_bcm11.pTxDmaRegs->FLOW_CTRL_LEN, 0);
// Set Rx DMA registers
g_bcm11.pRxDmaRegs = OALPAtoUA(BCM11_DMA_EMAC_RX_REGS_PA);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -