⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcm11dbg.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -