#include "netcfg.h" #include "netdef.h" #include "netsys.h" #include "mem.h" #include "netif.h" #include "ne2kif.h"
static UINT8 StartPageOfPacket;
static UINT8 LastSendStartPage;
/*============================================================== Function: Description: Parameters: Returns: Notes: ==============================================================*/ void NE2KIfInit(PNETIF pNetIf, UINT32 NeBase) { int i; for(i=0; i < RTL_DELAY_AFTER_HARDWARE_RESET; i++); NE2K_OUT(0, NE_RESET); i = NE2K_IN(NE_RESET);
NE2K_OUT(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR); NE2K_OUT(RECV_START + 1, NE_CURR); NE2K_OUT(pNetIf->MAC[0], NE_PAR0); NE2K_OUT(pNetIf->MAC[1], NE_PAR1); NE2K_OUT(pNetIf->MAC[2], NE_PAR2); NE2K_OUT(pNetIf->MAC[3], NE_PAR3); NE2K_OUT(pNetIf->MAC[4], NE_PAR4); NE2K_OUT(pNetIf->MAC[5], NE_PAR5);
NE2K_OUT(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
NE2K_OUT(TCR_LOOP_INT, NE_TCR); NE2K_OUT(RECV_START, NE_PSTART); NE2K_OUT(RECV_STOP, NE_PSTOP); NE2K_OUT(RECV_START, NE_BNRY); NE2K_OUT(SEND_PAGE0, NE_TPSR); NE2K_OUT(RCR_AB, NE_RCR); NE2K_OUT(0, NE_RBCR0); NE2K_OUT(0, NE_RBCR1); NE2K_OUT(DCR_LS | DCR_FIFO8 | DCR_WTS_BOS, NE_DCR); NE2K_OUT(ISR_OVW | ISR_PRX | ISR_RXE, NE_IMR); NE2K_OUT(0xff, NE_ISR); NE2K_OUT(TCR_LOOP_NONE, NE_TCR); NE2K_OUT(CMD_PAGE0 |CMD_NODMA | CMD_RUN, NE_CR);
LastSendStartPage = SEND_PAGE0; StartPageOfPacket = RECV_START + 1; }
/*============================================================== Function: Description: Parameters: Returns: Notes: ==============================================================*/ void NE2KIfIsr(PNETIF pNetIf, UINT32 NeBase) { UINT8 isr,curr; isr = NE2K_IN(NE_ISR); if (isr & ISR_OVW){ NE2K_OUT(ISR_OVW,NE_ISR); }
if (isr & ISR_RXE){ NE2K_OUT(ISR_RXE,NE_ISR); NE2KPAGE(1); curr = NE2K_IN(NE_CURR); NE2KPAGE(0); NE2K_OUT(curr-1, NE_BNRY); }
if (isr & ISR_PRX){ NE2K_OUT(ISR_PRX, NE_ISR); pNetIf->lpInput(pNetIf); }
NE2K_OUT(0xff, NE_ISR); }
/*============================================================== Function: Description: Parameters: Returns: Notes: ==============================================================*/ static void NE2KIfDMAWrite(UINT16 Count, PUINT8 pBuf, UINT32 NeBase) { int i;
#if DMA_TYPE==16 Count = (Count + 1) >> 1; #endif for (i = 0; i < Count; i ++){ #if DMA_TYPE==16 NE2K_OUT(*(((PUINT16)pBuf)+i),NE_DMA); #else NE2K_OUT(pBuf,NE_DMA); #endif } }
/*============================================================== Function: Description: Parameters: Returns: Notes: ==============================================================*/ void NE2KIfSend(PNETBUF pBuf, UINT32 NeBase) { static BOOL InSend = FALSE; PNETBUF pt; UINT16 TotLen; if (InSend){ return; }else{ InSend = TRUE; } for (pt = pBuf, TotLen = 0; pt != NULL; pt = pt->pSub){ TotLen += pt->TotLen; } if (TotLen < MIN_PACKET_LEN){ TotLen = MIN_PACKET_LEN; }else if (TotLen > MAX_PACKET_LEN){ TotLen = MAX_PACKET_LEN; } if (LastSendStartPage == SEND_PAGE0){ LastSendStartPage = SEND_PAGE1; }else{ LastSendStartPage = SEND_PAGE0; } NE2K_OUT(TotLen & 0xff, NE_RBCR0); NE2K_OUT(TotLen >> 8, NE_RBCR1); NE2K_OUT(0, NE_RSAR0); NE2K_OUT(LastSendStartPage, NE_RSAR1); NE2K_OUT(CMD_PAGE0 | CMD_WRITE | CMD_RUN, NE_CR);
for (pt = pBuf; pt != NULL; pt = pt->pSub){ NE2KIfDMAWrite(pt->TotLen, pt->PayLoad, NeBase); }
NE2K_OUT(0, NE_RBCR0); NE2K_OUT(0, NE_RBCR1); NE2K_OUT(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR); while((NE2K_IN(NE_CR) & CR_TXP) == CR_TXP); NE2K_OUT(LastSendStartPage, NE_TPSR); NE2K_OUT(TotLen & 0xff, NE_TBCR0); NE2K_OUT(TotLen >> 8, NE_TBCR1); NE2K_OUT(CMD_PAGE0 | CMD_NODMA | CMD_XMIT | CMD_RUN, NE_CR); InSend = FALSE; }
/*============================================================== Function: Description: Parameters: Returns: Notes: ==============================================================*/ static void NE2KIfDMARead(UINT16 Count, PUINT8 pBuf, UINT16 Addr, UINT32 NeBase) { int i; NE2K_OUT((UINT8)(Addr>>8),NE_RSAR1); NE2K_OUT((UINT8)Addr,NE_RSAR0); NE2K_OUT((UINT8)(Count>>8),NE_RBCR1); NE2K_OUT((UINT8)Count,NE_RBCR0); NE2K_OUT(CMD_PAGE0 | CMD_READ | CMD_RUN, NE_CR); #if DMA_TYPE==16 Count = (Count + 1) >> 1; #endif for (i = 0; i < Count; i ++){ #if DMA_TYPE==16 *(((PUINT16)pBuf)+i) = NE2K_IN(NE_DMA); #else pBuf = NE2K_IN(NE_DMA); #endif }
NE2K_OUT(0, NE_RBCR0); NE2K_OUT(0, NE_RBCR1); NE2K_OUT(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR); }
/*============================================================== Function: Description: Parameters: Returns: Notes: ==============================================================*/ PNETBUF NE2KIfRecv(UINT32 NeBase) { PNETBUF pt; UINT16 TotLen; UINT8 PDHeader[4]; UINT8 curr,bnry;
pt = NULL;
NE2KPAGE(1); curr = NE2K_IN(NE_CURR); NE2KPAGE(0);
if (StartPageOfPacket >= RECV_STOP || StartPageOfPacket < RECV_START){ StartPageOfPacket = curr; return NULL; } if (StartPageOfPacket == curr){ return NULL; } NE2KIfDMARead(4, PDHeader, (StartPageOfPacket << 8), NeBase); TotLen = (PDHeader[2] | (PDHeader[3] << 8 ));
if (PDHeader[0] & RSR_PRX) if (TotLen <= NE2KIF_MAX_PACKET_LEN) if ((pt = RecvBufAlloc()) != NULL){ pt->PayLoad = pt->Data + (NETIF_HEAD_MAX_LEN - ETH_NETIF_HEAD_LEN); pt->TotLen = TotLen - 4; NE2KIfDMARead(pt->TotLen, pt->PayLoad, (StartPageOfPacket << 8) + 4, NeBase); } StartPageOfPacket = PDHeader[1]; bnry = StartPageOfPacket-1; if (bnry < RECV_START){ bnry = RECV_STOP - 1; } NE2K_OUT(bnry, NE_BNRY); return pt; } |