📄 mac_au1000.c
字号:
t_MAC_AU1000_device *pdevice,
int reg
)
{
/* check link status, spin here till done */
while ( MACREG( pdevice->pAU1000CtrlRegs, MAC_MIICTRL)
& MAC_MIICTRL_MBUSY_MASK) ;
MACREG(pdevice->pAU1000CtrlRegs, MAC_MIICTRL) = (reg << 6);
/* check link status, spin here till done */
while ( MACREG( pdevice->pAU1000CtrlRegs, MAC_MIICTRL)
& MAC_MIICTRL_MBUSY_MASK) ;
return MACREG(pdevice->pAU1000CtrlRegs, MAC_MIIDATA);
}
static
INT32 MAC_AU1000_MII_init( t_MAC_AU1000_device *pdevice )
{
int i ;
INT32 rcode ;
#ifdef BE1000_CONFIG
DISP_STR("MII INIT");
MAC_MII_WRITE(pdevice,0,0x3200); // reset Autonegotiation
MAC_MII_WRITE(pdevice,17,0xffc0); // set LEDs to display correctly
#endif
#ifdef BOSPORUS_CONFIG
DISP_STR("SWITCH INIT");
bosporus_init_switch();
#endif
#ifdef PB1500_CONFIG
DISP_STR("MII INIT");
MAC_MII_WRITE(pdevice,0,0x3200); // reset Autonegotiation
MAC_MII_WRITE(pdevice,17,0xffc0); // set LEDs to display correctly
#endif
#ifdef PB1100_CONFIG
DISP_STR("MII INIT");
MAC_MII_WRITE(pdevice,0,0x3200); // reset Autonegotiation
MAC_MII_WRITE(pdevice,17,0xffc0); // set LEDs to display correctly
#endif
return(OK) ;
}
/************************************************************************
*
* MAC_AU1000_control_init
* Description :
* -------------
* This routine initialize the AU1000 Control Register
*
*
* Parameters :
* ------------
*
* 'pdevice', IN, reference for this device context
*
*
* Return values :
* ---------------
*
* 'OK'(=0)
*
*
*
************************************************************************/
static
INT32 MAC_AU1000_control_init( t_MAC_AU1000_device *pdevice )
{
INT32 rcode;
int i;
t_mac_addr mac_addr ;
/* get MAC address from board */
IF_ERROR( (rcode),
(SYSCON_read( SYSCON_COM_EN0_MAC_ADDR_ID,
&(mac_addr),
sizeof(mac_addr)) ) )
for(i=0;i<6;i++)
pdevice->PhysicalAddress[i] = mac_addr[i];
/* Bring MAC out of Reset */
/* Enable CLocks */
MACREG( pdevice->pAU1000EnReg, MAC_ENABLE) = SET(MAC_ENABLE_MACCLK) |
SET(MAC_ENABLE_DMARESET);
/* Bring out of reset */
MACREG( pdevice->pAU1000EnReg, MAC_ENABLE) = SETV(3, MAC_ENABLE_IPG_MIN) |
SET(MAC_ENABLE_TXEN) |
SET(MAC_ENABLE_MIIENAB) |
SET(MAC_ENABLE_MACINIT) |
SET(MAC_ENABLE_MACCLK);
/* Turn off promiscuous mode - other than that defaults should be OK */
MACREG( pdevice->pAU1000CtrlRegs, MAC_CONTROL) = SETV(0, MAC_CONTROL_PR) |
#ifdef EB
SET(MAC_CONTROL_EM) | /* Big Endian */
#endif
SET(MAC_CONTROL_DO) | /* Disable Receive Own */
SET(MAC_CONTROL_DB); /* Disable Broadcast Frames */
/* Program Address - The LSB of low address is the first bit to compare on receive
so this needs to contain the first byte to be compared */
MACREG( pdevice->pAU1000CtrlRegs, MAC_ADDRLO) = pdevice->PhysicalAddress[0] |
pdevice->PhysicalAddress[1] << 8 |
pdevice->PhysicalAddress[2] << 16|
pdevice->PhysicalAddress[3] << 24;
MACREG( pdevice->pAU1000CtrlRegs, MAC_ADDRHI) = pdevice->PhysicalAddress[4] |
pdevice->PhysicalAddress[5] << 8;
return( OK );
}
/************************************************************************
*
* MAC_AU1000_DMA_init
* Description :
* -------------
* Setup the AU1000 DMA registers
*
*
* Parameters :
* ------------
*
* 'pdevice', IN, reference for this device context
*
*
* Return values :
* ---------------
*
* 'OK'(=0)
*
*
*
************************************************************************/
static
INT32 MAC_AU1000_DMA_init( t_MAC_AU1000_device *pdevice )
{
int i;
/* The DMA registers will not be clobbered in reset. The MAC registers will be */
/* This means the DMA can be setup before the MAC is brought out of reset but the
MAC can not be */
/* Get next buffer location for DMA before setting EN=1 */
pdevice->NextRcvBufferIndex = (MACREG( pdevice->pAU1000DMARegs,
SETV(DMA_RECEIVE, MAC_DMA_TXRX) |
SETV(DMA_ADDRESS_EN,MAC_DMA_REG)) &
MAC_DMA_NEXTBUF_MASK) >> MAC_DMA_NEXTBUF;
/* Setup DMA Address for Rx */
for (i=0; i< MAC_AU1000_RX_BUFFERS ; i++) {
MACREG( pdevice->pAU1000DMARegs,
SETV(DMA_RECEIVE, MAC_DMA_TXRX) |
SETV(i,MAC_DMA_BUF) | /* i selects buffer */
SETV(DMA_ADDRESS_EN ,MAC_DMA_REG) )
|= pdevice->RcvBuffer[i] & MAC_DMA_ADDR_MASK; /* only upper 27 bits are used */
}
return( OK );
}
/************************************************************************
* Implementation : Device driver services
************************************************************************/
/************************************************************************
*
* MAC_AU1000_init
* Description :
* -------------
* This service initializes the lan driver and configures
* the MAC-address for the 'EN0' LAN interface.
* The MAC-address is read during 'init' via the 'syscon' parameter:
* -'SYSCON_COM_EN0_MAC_ADDR_ID'.
*
*
* Parameters :
* ------------
*
* 'major', IN, major device number
* 'minor', IN, not used
* 'p_param', INOUT, not used
*
*
* Return values :
* ---------------
*
* 'OK'(=0)
*
*
*
************************************************************************/
static
INT32 MAC_AU1000_init(
UINT32 major, /* IN: major device number */
UINT32 minor, /* IN: minor device number */
void *p_param ) /* INOUT: device parameter block */
{
INT32 rcode;
int i;
UINT32 prid;
prid = CP0_prid_read();
if ((prid & 0xFF000000) == 0x00000000 ) // Au1000
{
if (minor == MAC0_MINOR_AU1000_DEVICE)
{
minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
}
else if (minor == MAC1_MINOR_AU1000_DEVICE)
{
minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC1_AU1000_BASE;
minor_device[minor].pAU1000EnReg = (UINT32*) MAC1_AU1000_EN_BASE;
minor_device[minor].pAU1000DMARegs = (UINT32*) MAC1_AU1000_DMA_BASE;
}
}
else if ((prid & 0xFF000000) == 0x02000000 ) // Au1100
{
minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
}
else if ((prid & 0xFF000000) == 0x03000000 ) // Au1550
{
if (minor == MAC0_MINOR_AU1000_DEVICE)
{
minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
}
else if (minor == MAC1_MINOR_AU1000_DEVICE)
{
minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC1_AU1000_BASE;
minor_device[minor].pAU1000EnReg = (UINT32*) MAC1_AU1000_EN_BASE;
minor_device[minor].pAU1000DMARegs = (UINT32*) MAC1_AU1000_DMA_BASE;
}
}
else if( (prid & 0xff000000) == 0x01000000 ) // if running on Au1500
{
if (minor == MAC0_MINOR_AU1000_DEVICE)
{
minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
}
else if (minor == MAC1_MINOR_AU1000_DEVICE)
{
minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC1_AU1000_BASE;
minor_device[minor].pAU1000EnReg = (UINT32*) MAC1_AU1000_EN_BASE;
minor_device[minor].pAU1000DMARegs = (UINT32*) MAC1_AU1000_DMA_BASE;
}
(long)(minor_device[minor].pAU1000CtrlRegs) |= Au1500_PBUS1_OFFSET;
(long)(minor_device[minor].pAU1000EnReg) |= Au1500_PBUS1_OFFSET;
}
#ifdef ETH_DEBUG
sprintf( msg, "\n\r MAC_AU1000_init: %08x\n\r", (UINT32) minor_device[minor].pAU1000CtrlRegs ) ;
PUTS( DEFAULT_PORT, msg ) ;
#endif
/* allocate MAC RX/TX frame buffer space */
IF_ERROR( (rcode),
(MAC_AU1000_allocate_buffers(&minor_device[minor])) )
/* Stop any active DMA */
IF_ERROR( (rcode),
(MAC_AU1000_stop(&minor_device[minor])) )
/* Reset MAC out of reset and program address */
IF_ERROR( (rcode),
(MAC_AU1000_control_init(&minor_device[minor])) )
/* initialize AU1000 DMA context registers */
IF_ERROR( (rcode),
(MAC_AU1000_DMA_init(&minor_device[minor])) )
/* initialize AU1000 MII */
IF_ERROR( (rcode),
(MAC_AU1000_MII_init(&minor_device[minor])) )
/* Enable All 4 Receive DMA Here */
/* Revise: Since all processing is polled, we are assuming that receives will be solicited and
will not occur at unknown times, this is an assumption */
for (i=0; i< MAC_AU1000_RX_BUFFERS ; i++) {
MACREG( minor_device[minor].pAU1000DMARegs,
SETV(DMA_RECEIVE, MAC_DMA_TXRX) |
SETV(i,MAC_DMA_BUF) | /* i selects buffer to enable */
SETV(DMA_ADDRESS_EN ,MAC_DMA_REG) )
|= MAC_DMA_ENABLE_MASK;
}
/* Enable TX and RX */
MACREG( minor_device[minor].pAU1000CtrlRegs, MAC_CONTROL ) |= SET(MAC_CONTROL_TE) | SET(MAC_CONTROL_RE);
#ifdef ETH_DEBUG
/* dump AU1000 LAN controller registers */
IF_ERROR( (rcode),
(MAC_AU1000_dump_regs(&minor_device[minor])) )
#endif
MAC_AU1000_state = MAC_AU1000_DRIVER_IS_STARTED;
return( OK ) ;
}
/************************************************************************
*
* MAC_AU1000_open
* Description :
* -------------
* This service registers a mac-layer defined receive-handler in the
* LAN-drivers ISR-context to allow for interrupt controlled receive
* frame processing in the network stack. No external buffer
* administration is required as the protocol-layers are responsible for
* handling buffer-allocation and data copy-ing to the allocated buffer
* payload area. At return from 'receive' handler, the LAN-drivers
* local RX-buffer (packet) is released for re-use. After 'open'
* has been called, the LAN-driver's 'read' service will call the
* registered receive-handler by any frame reception with direct
* reference to the LAN-drivers packet space and no read data will be
* delivered in the IO-descriptor.
*
*
*
* Parameters :
* ------------
*
* 'major', IN, major device number
* 'minor', IN, not used
* 'p_param', IN, LAN variable of type, t_LAN_IO_desc.
*
*
* Return values :
* ---------------
* 'OK'(=0)
*
*
*
************************************************************************/
static
INT32 MAC_AU1000_open(
UINT32 major, /* IN: major device number */
UINT32 minor, /* IN: minor device number */
t_LAN_OPEN_desc *p_param ) /* IN: receive handler reference */
{
/* register user defined receive handler */
usr_receive = p_param->receive ;
return( OK ) ;
}
/************************************************************************
*
* MAC_AU1000_read
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -