📄 packetdriver.c
字号:
/******************************************************************************
*
* Copyright (c) 2008 Nuvoton Tech. Corp.
* All rights reserved.
*
* Module Name: PACKETDRIVER.C
*
* Created by :
******************************************************************************/
#include <string.h>
#include "netbuf.h"
#include "w90p910.h"
#include "net.h"
#include "uprintf.h"
__align(16) static sFrameDescriptor RxFDBaseAddr[MaxRxFrameDescriptors];
__align(16) static sFrameDescriptor TxFDBaseAddr[MaxRxFrameDescriptors];
INT _phy=NET_PHY;
INT _rmii=1;
// Global variables used for MAC driver
volatile UINT32 gMCMDR = MCMDR_FDUP | MCMDR_SPCRC | MCMDR_RXON |
MCMDR_EnMDC | MCMDR_AEP | MCMDR_ACP;
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, gWTxFDPtr, gCRxFDPtr;
volatile UINT32 gCam0M = 0 , gCam0L = 0;
volatile INT TDU_Flag;
volatile char TxReady=1;
NETBUF *_TxQueue = NULL;
// Interrupt Handler Table
typedef void (*fptr)(); // function pointer
extern fptr IRQ_HandlerTable[31];
extern void MAC_Tx_isr(void) ;
extern void MAC_Rx_isr(void) ;
extern UCHAR _HostMAC[];
extern UCHAR _HostIP[];
volatile unsigned int PHYAD; //cmn, [2007/03/08]
void GetMacAddress(unsigned 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);
}
#if 0
void SetMacNumber(INT num)
{
return;
}
#endif
// Setup Interrupt Handler Vector Table
void SysSetInterrupt(volatile UINT32 vector, void (*handler)())
{
IRQ_HandlerTable[vector] = handler;
}
#if 0
// 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<<16) )
(*IRQ_HandlerTable[16])();
if( irq & (0x1<<17) )
(*IRQ_HandlerTable[17])();
}
#endif
void Mac_EnableInt()
{
Enable_Int(EMCTXINT);
Enable_Int(EMCRXINT);
}
void Mac_DisableInt()
{
Disable_Int(EMCTXINT);
Disable_Int(EMCRXINT);
}
void Mac_EnableBroadcast()
{
CAMCMR |= CAM_ABP ;
}
void Mac_DisableBroadcast()
{
CAMCMR &= ~CAM_ABP ;
}
// MII Interface Station Management Register Write
void MiiStationWrite(UINT32 PhyInAddr, UINT32 PhyAddr, UINT32 PhyWrData)
{
INT volatile i = 1000;
MIID = PhyWrData ;
MIIDA = PhyInAddr | PhyAddr | PHYBUSY | PHYWR | MDCCR;
while (i--) ;
while ( (MIIDA & PHYBUSY) ) ;
}
// MII Interface Station Management Register Read
UINT32 MiiStationRead(UINT32 PhyInAddr, UINT32 PhyAddr)
{
UINT32 volatile PhyRdData ;
MIIDA = PhyInAddr | PhyAddr | PHYBUSY | MDCCR;
while( (MIIDA & PHYBUSY) ) ;
PhyRdData = MIID ;
return PhyRdData ;
}
void AutoDetectPhyAddr()
{
int i;
int flag;
unsigned int temp;
flag = 0;
PHYAD = 0;
for (i=0; i<32; i++)
{
temp = MiiStationRead(0, (i << 8));
if ((temp & 0xFFFF) != 0xFFFF)
{
PHYAD = i << 8;
flag = 1;
break;
}
//UART_printf("PHY ADDR %d = %x\n", i, MiiStationRead(num, 0, (i << 8)));
}
#ifdef _DEBUG
if (flag == 1)
uprintf("AutoDetectPhyAddr() : PHY ADDR = %d\n", i);
else
uprintf("AutoDetectPhyAddr() : Don't find PHY Addr!\n");
#endif
} /* end AutoDetectPhyAddr */
// Reset PHY, Auto-Negotiation Enable
void ResetPhyChip(void)
{
UINT32 volatile RdValue;
UINT32 volatile regANA, regANLPA;
INT t0;
// Check the RMII bit is enabled or not
RdValue = MiiStationRead(16, PHYAD) ;
if (!(RdValue & 0x0100))
{
//uprintf("WARNING, RMII is not enabled, set it by software !\n");
RdValue |= 0x0100;
MiiStationWrite(16, PHYAD, RdValue);
}
//Reset PHY
t0 = 1000000;
MiiStationWrite(PHY_CNTL_REG, PHYAD, RESET_PHY);
while (1)
{
RdValue = MiiStationRead(PHY_CNTL_REG, PHYAD) ;
if ((RdValue&RESET_PHY)==0)
break;
if (!(t0--))
{
uprintf("Reset PHY FAILED!!\n");
break;
}
}
//Start auto-negotiation
MiiStationWrite(PHY_ANA_REG, PHYAD, DR100_TX_FULL|DR100_TX_HALF|DR10_TX_FULL|DR10_TX_HALF|IEEE_802_3_CSMA_CD);
RdValue = MiiStationRead(PHY_CNTL_REG, PHYAD) ;
//RdValue = (RdValue | RESTART_AN | ENABLE_AN);
RdValue |= RESTART_AN;
MiiStationWrite(PHY_CNTL_REG, PHYAD, RdValue);
//uprintf("Wait for auto-negotiation complete...");
t0 = 1000000;
while (1) /* wait for auto-negotiation complete */
{
RdValue = MiiStationRead(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 */
MCMDR |= MCMDR_OPMOD;
MCMDR |= MCMDR_FDUP;
return;
}
}
/* wait for link valid [2006/06/20], cmn */
t0 = 1000000;
while ( !(MiiStationRead(PHY_STATUS_REG, PHYAD) & 0x04) )
{
if (!(t0--))
{
uprintf("FAILED!!\n");
return;
}
}
/* read the result of auto-negotiation */
regANA = MiiStationRead(PHY_ANA_REG, PHYAD);
regANLPA = MiiStationRead(PHY_ANLPA_REG, PHYAD);
if ((regANA & 0x100) && (regANLPA & 0x100)) //100Mb, Full duplex
{
MCMDR = MCMDR | MCMDR_OPMOD | MCMDR_FDUP;
}
else if ((regANA & 0x80) && (regANLPA & 0x80)) //100Mb, Half duplex
{
MCMDR |= MCMDR_OPMOD;
MCMDR &= ~MCMDR_FDUP;
}
else if ((regANA & 0x40) && (regANLPA & 0x40)) //10Mb, Full duplex
{
MCMDR &= ~MCMDR_OPMOD;
MCMDR |= MCMDR_FDUP;
}
else //10Mb, half duplex
{
MCMDR &= ~MCMDR_OPMOD;
MCMDR &= ~MCMDR_FDUP;
}
return;
}
void EnableCamEntry(INT entry)
{
CAMEN |= 0x00000001 << entry ;
}
void DisableCamEntry(INT entry)
{
CAMEN &= ~(0x00000001 << entry) ;
}
void FillCamEntry(INT entry, UINT32 msw, UINT32 lsw)
{
CAMxM_Reg(entry) = msw;
CAMxL_Reg(entry) = lsw;
EnableCamEntry(entry);
}
// Set MAC Address to CAM
void SetMacAddr(void)
{
INT i;
UCHAR mac[6];
GetMacAddress((UCHAR *)mac);
/* Copy MAC Address to global variable */
for (i = 0; i < (INT)MAC_ADDR_SIZE-2; i++)
gCam0M = (gCam0M << 8) | mac[i] ;
for (i = (INT)(MAC_ADDR_SIZE-2); i < (INT)MAC_ADDR_SIZE; i++)
gCam0L = (gCam0L << 8) | mac[i] ;
gCam0L = (gCam0L << 16) ;
FillCamEntry(0, gCam0M, gCam0L);
}
// Initialize Tx frame descriptor area-buffers.
void TxFDInitialize(void)
{
sFrameDescriptor *pFrameDescriptor;
sFrameDescriptor *pStartFrameDescriptor;
sFrameDescriptor *pLastFrameDescriptor = NULL;
UINT32 i;
// Get Frame descriptor's base address.
TXDLSA = (UINT32)TxFDBaseAddr | 0x80000000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -