📄 packetdriver.c
字号:
/******************************************************************************
*
* Copyright (c) 2003 Windond Electronics Corp.
* All rights reserved.
* Winbond W90N740 Boot Loader
*
* Module Name: PACKETDRIVER.C
*
* Created by :
******************************************************************************/
#include "netbuf.h"
#include "w90n740.h"
#include "net.h"
//#define USE_RMII
//#define PHY
//#define MARVELL_6052
//#define IC_PLUS
INT _phy=NET_IC_PLUS;
INT _rmii=0;
volatile INT MAC_NUM = 0;
__align(16) static sFrameDescriptor RxFDBaseAddr0[MaxRxFrameDescriptors];
__align(16) static sFrameDescriptor RxFDBaseAddr1[MaxRxFrameDescriptors];
__align(16) static sFrameDescriptor TxFDBaseAddr0[MaxTxFrameDescriptors];
__align(16) static sFrameDescriptor TxFDBaseAddr1[MaxTxFrameDescriptors];
// Global variables used for MAC driver
#ifdef USE_RMII
volatile UINT32 gMCMDR = MCMDR_FDUP | MCMDR_SPCRC | MCMDR_RXON |
MCMDR_EnMDC | MCMDR_AEP | MCMDR_ACP | MCMDR_EnRMII;
#else
volatile UINT32 gMCMDR = MCMDR_FDUP | MCMDR_SPCRC | MCMDR_RXON |
MCMDR_EnMDC | MCMDR_AEP | MCMDR_ACP;
#endif
volatile UINT32 gMIEN = EnTXINTR | EnTXCP | EnRXINTR | EnTDU | EnRXGD |
EnCRCE | EnRP | EnPTLE | EnRXOV |
EnLC | EnTXABT | EnNCS | EnEXDEF | EnTXEMP |
EnTxBErr | EnRxBErr | EnRDU | EnCFR;
volatile UINT32 gCAMCMR = CAM_ECMP;
volatile UINT32 gCTxFDPtr[2], gWTxFDPtr[2], gCRxFDPtr[2];
volatile UINT32 gCam0M_0 = 0 , gCam0L_0 = 0;
volatile UINT32 gCam0M_1 = 0 , gCam0L_1 = 0;
volatile INT TDU_Flag0, TDU_Flag1;
volatile char TxReady0=1, TxReady1=1;
NETBUF *_TxQueue0 = NULL, *_TxQueue1 = NULL;
// Interrupt Handler Table
typedef void (*fptr)(); // function pointer
fptr IRQ_HandlerTable[19];
extern void MAC0_Tx_isr(void) ;
extern void MAC0_Rx_isr(void) ;
extern void MAC1_Tx_isr(void) ;
extern void MAC1_Rx_isr(void) ;
extern UCHAR _HostMAC[];
extern UCHAR _HostIP[];
void GetMacAddress(char *mac)
{
memcpy((char *)mac, (char *)_HostMAC, 6);
}
void SetMacAddress(char *mac)
{
memcpy((char *)_HostMAC, (char *)mac, 6);
}
void SetIpAddress(char *ip)
{
memcpy((char *)_HostIP, (char *)ip, 4);
}
void GetIpAddress(char *ip)
{
memcpy((char *)ip, (char *)_HostIP, 4);
}
void SetMacNumber(INT num)
{
if ((num==0)||(num==1))
MAC_NUM = num;
}
void SetPhyChip(INT num)
{
_phy=num;
}
void SetRMII(INT num)
{
if( num == 1)
_rmii = 1;
else
_rmii = 0;
}
// Setup Interrupt Handler Vector Table
void SysSetInterrupt(volatile UINT32 vector, void (*handler)())
{
IRQ_HandlerTable[vector] = handler;
}
// Interrupt Service Routine */
__irq void IRQ_IntHandler(void)
{
// UINT32 IPER, ISNR;
UINT32 irq;
// IPER = AIC_IPER >> 2;
// ISNR = AIC_ISNR;
irq=AIC_ISR;
if( irq & (0x1<<13) )
(*IRQ_HandlerTable[13])();
if( irq & (0x1<<14) )
(*IRQ_HandlerTable[14])();
if( irq & (0x1<<15) )
(*IRQ_HandlerTable[15])();
if( irq & (0x1<<16) )
(*IRQ_HandlerTable[16])();
// if (ISNR == IPER)
// if((IPER >=13) && (IPER <=16) )
// (*IRQ_HandlerTable[ISNR])();
// AIC_EOSCR = 0;
}
void Mac_EnableInt()
{
if (MAC_NUM == 0)
{
Enable_Int(EMCTXINT0);
Enable_Int(EMCRXINT0);
}
else if (MAC_NUM == 1)
{
Enable_Int(EMCTXINT1);
Enable_Int(EMCRXINT1);
}
}
void Mac_DisableInt()
{
if (MAC_NUM == 0)
{
Disable_Int(EMCTXINT0);
Disable_Int(EMCRXINT0);
}
else if (MAC_NUM == 1)
{
Disable_Int(EMCTXINT1);
Disable_Int(EMCRXINT1);
}
}
void Mac_EnableBroadcast()
{
if (MAC_NUM == 0)
CAMCMR_0 |= CAM_ABP ;
else
if (MAC_NUM == 1)
CAMCMR_1 |= CAM_ABP ;
}
void Mac_DisableBroadcast()
{
if (MAC_NUM == 0)
CAMCMR_0 &= ~CAM_ABP ;
else
if (MAC_NUM == 1)
CAMCMR_1 &= ~CAM_ABP ;
}
// MII Interface Station Management Register Write
void MiiStationWrite(INT num, UINT32 PhyInAddr, UINT32 PhyAddr, UINT32 PhyWrData)
{
volatile INT i = 1000;
/*
#ifdef MARVELL_6052
num = 0;
#endif
#ifdef IC_PLUS
num = 0;
#endif
*/
//if( _phy != NET_PHY )num=0; //CWS 5/20
if (num == 0)
{
MIID_0 = PhyWrData ;
MIIDA_0 = PhyInAddr | PhyAddr | PHYBUSY | PHYWR | MDCCR;
while (i--) ;
while ( (MIIDA_0 & PHYBUSY) ) ;
}
else
if (num == 1)
{
MIID_1 = PhyWrData ;
MIIDA_1 = PhyInAddr | PhyAddr | PHYBUSY | PHYWR | MDCCR;
while (i--) ;
while ( (MIIDA_1 & PHYBUSY) ) ;
}
}
// MII Interface Station Management Register Read
UINT32 MiiStationRead(INT num, UINT32 PhyInAddr, UINT32 PhyAddr)
{
UINT32 PhyRdData ;
/*
#ifdef MARVELL_6052
num = 0;
#endif
#ifdef IC_PLUS
num = 0;
#endif
*/
// if( _phy!=NET_PHY )num=0; //CWS 5/20
if (num == 0)
{
MIIDA_0 = PhyInAddr | PhyAddr | PHYBUSY | MDCCR;
while( (MIIDA_0 & PHYBUSY) ) ;
PhyRdData = MIID_0 ;
}
else if (num == 1)
{
MIIDA_1 = PhyInAddr | PhyAddr | PHYBUSY | MDCCR;
while( (MIIDA_1 & PHYBUSY) ) ;
PhyRdData = MIID_1 ;
}
return PhyRdData ;
}
// Reset PHY, Auto-Negotiation Enable
void ResetPhyChip(INT num)
{
UINT32 RdValue;
INT t0;
UINT32 i;
//#ifdef MARVELL_6052
switch(_phy)
{
case NET_MARVELL6052:
if (num == 0)
{
uprintf("setting lan side vlan table\r\n");
for (i = 8; i < 0xf; i ++)
{
RdValue = MiiStationRead(0, 0x04, (0x1000 |(i << 8)) );
MiiStationWrite(0, 0x04, (0x1000 | (i << 8)), RdValue | 0x3); // enable all ports
}
MiiStationWrite(0, 0x00, 0x1100, ENABLE_AN | RESTART_AN);
MiiStationWrite(0, 0x00, 0x1200, ENABLE_AN | RESTART_AN);
MiiStationWrite(0, 0x00, 0x1300, ENABLE_AN | RESTART_AN);
MiiStationWrite(0, 0x00, 0x1400, ENABLE_AN | RESTART_AN);
MiiStationWrite(0, 0x06, 0x1900, 0x003c); // port 1 for LAN
MiiStationWrite(0, 0x06, 0x1a00, 0x003a); // port 2
MiiStationWrite(0, 0x06, 0x1b00, 0x0036); // port 3
MiiStationWrite(0, 0x06, 0x1c00, 0x002e); // port 4
MiiStationWrite(0, 0x06, 0x1d00, 0x001e); // port 5 connect to CPU MAC 0
/* set MAC 0 to 100 full */
MCMDR_0 |= MCMDR_OPMOD;
MCMDR_0 |= MCMDR_FDUP;
}
else
{
uprintf("setting wan side vlan table\r\n");
for (i = 8; i < 0xf; i ++)
{
RdValue = MiiStationRead(0, 0x04, (0x1000 |(i << 8)) );
MiiStationWrite(0, 0x04, (0x1000 | (i << 8)), RdValue | 0x3); // enable all ports
}
MiiStationWrite(0, 0x00, 0x1000, ENABLE_AN | RESTART_AN);
MiiStationWrite(0, 0x06, 0x1800, 0x1040); // port 0 for WAN
MiiStationWrite(0, 0x06, 0x1e00, 0x1001); // port 6 connect to CPU port 1
/* set MAC 1 to 100 full */
MCMDR_1 |= MCMDR_OPMOD;
MCMDR_1 |= MCMDR_FDUP;
}
return;
//#endif
case NET_IC_PLUS:
//#ifdef IC_PLUS
#define IEEE_802_3_CSMA_CD 1
t0 = 1000000;
if (1)
{
if( num == 0 ) // CWS 6/10
{
MiiStationWrite(0, 0x16, PHYAD, 0x8420);
RdValue = MiiStationRead(0, 0x12, PHYAD);
MiiStationWrite(0, 0x12, PHYAD, RdValue | 0x80); // enable MII registers
}
if (num == 1)
{
MiiStationWrite(num, PHY_ANA_REG, PHYAD, DR100_TX_FULL|DR100_TX_HALF|\
DR10_TX_FULL|DR10_TX_HALF|IEEE_802_3_CSMA_CD); //CWS 6/10
MiiStationWrite(num, PHY_CNTL_REG, PHYAD, ENABLE_AN | RESET_PHY|RESTART_AN);
uprintf("Wait for auto-negotiation complete...");
while (1) /* wait for auto-negotiation complete */
{
RdValue = MiiStationRead(num, PHY_STATUS_REG, PHYAD) ;
if ((RdValue & AN_COMPLETE) != 0)
{
uprintf("OK\n");
break;
}
//if (NU_Retrieve_Clock() - t0 > 3 * NU_PLUS_Ticks_Per_Second)
if ( !(t0--) )
{
uprintf("FAILED!!\n");
/* By default, we set the MAC to work under 100M/Full-duplex */
MCMDR_1 |= MCMDR_OPMOD;
MCMDR_1 |= MCMDR_FDUP;
return;
}
} /* end of while */
}
}
if (num == 1)
{
/* read the result of auto-negotiation */
RdValue = MiiStationRead(num, PHY_CNTL_REG, PHYAD) ;
if (RdValue & DR_100MB)
{
uprintf("100MB - ");
MCMDR_1 |= MCMDR_OPMOD;
}
else
{
uprintf("10MB - ");
MCMDR_1 &= ~MCMDR_OPMOD;
}
if (RdValue & PHY_FULLDUPLEX)
{
uprintf("Full Duplex\n");
MCMDR_1 |= MCMDR_FDUP;
}
else
{
uprintf("Half Duplex\n");
MCMDR_1 &= ~MCMDR_FDUP;
}
/* Fix IC PLUS 10half collision bug */
RdValue = MiiStationRead(num, 0x1d, PHYAD);
RdValue |= 0x0100;
MiiStationWrite(num, 0x1d, PHYAD, RdValue);
}
else
{
/* MAC0 fixed to 100/Full */
MCMDR_0 |= MCMDR_OPMOD;
MCMDR_0 |= MCMDR_FDUP;
}
return;
//#endif
default:
case NET_PHY:
//#ifdef PHY
t0 = 1000000;
if (1)
{
MiiStationWrite(num, PHY_CNTL_REG, PHYAD, ENABLE_AN | RESTART_AN);
uprintf("Wait for auto-negotiation complete...");
while (1) /* wait for auto-negotiation complete */
{
RdValue = MiiStationRead(num, PHY_STATUS_REG, PHYAD) ;
if ((RdValue & AN_COMPLETE) != 0)
{
uprintf("OK\n");
break;
}
if (!(t0--))
{
uprintf("FAILED!!\n");
/* By default, we set the MAC to work under 100M/Full-duplex */
if (num == 0)
{
MCMDR_0 |= MCMDR_OPMOD;
MCMDR_0 |= MCMDR_FDUP;
}
else
{
MCMDR_1 |= MCMDR_OPMOD;
MCMDR_1 |= MCMDR_FDUP;
}
return;
}
}
}
/* read the result of auto-negotiation */
RdValue = MiiStationRead(num, PHY_CNTL_REG, PHYAD) ;
if (RdValue & DR_100MB) /* 100MB */
{
uprintf("100MB - ");
if (num == 1)
MCMDR_1 |= MCMDR_OPMOD;
else
MCMDR_0 |= MCMDR_OPMOD;
}
else
{
uprintf("10MB - ");
if (num == 1)
MCMDR_1 &= ~MCMDR_OPMOD;
else
MCMDR_0 &= ~MCMDR_OPMOD;
}
if (RdValue & PHY_FULLDUPLEX) /* Full Duplex */
{
uprintf("Full Duplex\n");
if (num == 1)
MCMDR_1 |= MCMDR_FDUP;
else
MCMDR_0 |= MCMDR_FDUP;
}
else
{
uprintf("Half Duplex\n");
if (num == 1)
MCMDR_1 &= ~MCMDR_FDUP;
else
MCMDR_0 &= ~MCMDR_FDUP;
}
return;
//#endif
}
}
void EnableCamEntry(INT num, INT entry)
{
if (num == 0)
CAMEN_0 |= 0x00000001 << entry ;
else
if (num == 1)
CAMEN_1 |= 0x00000001 << entry ;
}
void DisableCamEntry(INT num, INT entry)
{
if (num == 0)
CAMEN_0 &= ~(0x00000001 << entry) ;
else
if (num == 1)
CAMEN_1 &= ~(0x00000001 << entry) ;
}
void FillCamEntry(INT num, INT entry, UINT32 msw, UINT32 lsw)
{
if (num==0)
{
CAMxM_Reg_0(entry) = msw;
CAMxL_Reg_0(entry) = lsw;
}
else if (num==1)
{
CAMxM_Reg_1(entry) = msw;
CAMxL_Reg_1(entry) = lsw;
}
EnableCamEntry(num,entry);
}
// Set MAC Address to CAM
void SetMacAddr(INT num)
{
INT i;
UCHAR mac[6];
GetMacAddress((CHAR *)mac);
if (num == 0)
{
/* Copy MAC Address to global variable */
for (i = 0; i < (INT)MAC_ADDR_SIZE-2; i++)
gCam0M_0 = (gCam0M_0 << 8) | mac[i] ;
for (i = (INT)(MAC_ADDR_SIZE-2); i < (INT)MAC_ADDR_SIZE; i++)
gCam0L_0 = (gCam0L_0 << 8) | mac[i] ;
gCam0L_0 = (gCam0L_0 << 16) ;
FillCamEntry(0, 0, gCam0M_0, gCam0L_0);
}
else
if (num == 1)
{
/* Copy MAC Address to global variable */
for (i = 0; i < (INT)MAC_ADDR_SIZE-2; i++)
gCam0M_1 = (gCam0M_1 << 8) | mac[i] ;
for (i = (INT)(MAC_ADDR_SIZE-2); i < (INT)MAC_ADDR_SIZE; i++)
gCam0L_1 = (gCam0L_1 << 8) | mac[i] ;
gCam0L_1 = (gCam0L_1 << 16) ;
FillCamEntry(1, 0, gCam0M_1, gCam0L_1);
}
}
// Initialize Tx frame descriptor area-buffers.
void TxFDInitialize(INT num)
{
sFrameDescriptor *pFrameDescriptor;
sFrameDescriptor *pStartFrameDescriptor;
sFrameDescriptor *pLastFrameDescriptor = NULL;
UINT32 i;
if (num == 0)
{
// Get Frame descriptor's base address.
TXDLSA_0 = (UINT32)TxFDBaseAddr0 | 0x80000000;
gWTxFDPtr[0] = gCTxFDPtr[0] = TXDLSA_0;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[0];
pStartFrameDescriptor = pFrameDescriptor;
for(i = 0; i < MaxTxFrameDescriptors; i++)
{
if (pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else
pLastFrameDescriptor->NextFrameDescriptor = (UINT32)pFrameDescriptor;
pFrameDescriptor->Status1 = (PaddingMode | CRCMode | MACTxIntEn);
pFrameDescriptor->FrameDataPtr = (UINT32)0x0;
pFrameDescriptor->Status2 = (UINT32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
pLastFrameDescriptor = pFrameDescriptor;
pFrameDescriptor++;
}
// Make Frame descriptor to ring buffer type.
pFrameDescriptor--;
pFrameDescriptor->NextFrameDescriptor = (UINT32)pStartFrameDescriptor;
}
else
if (num == 1)
{
// Get Frame descriptor's base address.
TXDLSA_1 = (UINT32)TxFDBaseAddr1 | 0x80000000;
gWTxFDPtr[1] = gCTxFDPtr[1] = TXDLSA_1;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[1];
pStartFrameDescriptor = pFrameDescriptor;
for (i = 0; i < MaxTxFrameDescriptors; i++)
{
if (pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else
pLastFrameDescriptor->NextFrameDescriptor = (UINT32)pFrameDescriptor;
pFrameDescriptor->Status1 = (PaddingMode | CRCMode | MACTxIntEn);
pFrameDescriptor->FrameDataPtr = (UINT32)0x0;
pFrameDescriptor->Status2 = (UINT32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -