📄 etherne.c
字号:
if (lolen > 0xfc)
hilen++;
len = (hilen<<8) + lolen;
if (len != nichdr.len) /* ..and compare with actual value */
{
if (netdebug)
Uart_Printf(" NIC length mismatch %Xh - %Xh\n", len, nichdr.len);
}
#else
len = nichdr.len; /* Take length from stored header */
#endif
if ((nichdr.stat&1) && len>=MINFRAMEC && len<=MAXFRAMEC)
{ /* If hdr is OK, get packet */
len -= CRCLEN; /* ..without CRC! */
if (pkt)
getnic((WORD)((cp->next_pkt<<8)+sizeof(nichdr)), pkt, len);
}
else /* If not, no packet data */
{
Uart_Printf(" NIC packet error\n");
} /* Update next packet ptr */
if (nichdr.next>=RXSTART && nichdr.next<RXSTOP)
cp->next_pkt = nichdr.next;
else /* If invalid, use prev+1 */
{
Uart_Printf(" NIC pointer error\n");
cp->next_pkt = nicwrap(cp->next_pkt + 1);
} /* Update boundary register */
bnry = nicwrap(cp->next_pkt - 1);
//outnic(BNRY, bnry);
BNRY=bnry;
}
return(len); /* Return length excl. CRC */
}
/* Send Ethernet packet given len excl. CRC, return 0 if NIC is busy */
WORD put_etherne(WORD dtype, void *pkt, WORD len)
{
CONFIGNE *cp;
cp = &configs[dtype & NETNUM_MASK];
ebase = cp->ebase;
//if (!ebase || innic(CMDR) & 4) /* If still Txing, return 0 */
if(!ebase || CMDR & 4)
len = 0;
else if (pkt)
{ /* If last Tx is complete.. */
len = minw(MAXFRAME, maxw(MINFRAME, len)); /* Constrain length */
memcpy((BYTE *)pkt+MACLEN, cp->myeth, MACLEN); /* Set source addr */
//outnic(ISR, 0x0a);
ISR=0x0a; /* Clear interrupt flags */
//outnic(TBCR0, len & 0xff);
TBCR0=len&0xff; /* Set Tx length regs */
//outnic(TBCR1, len >> 8);
TBCR1=len>>8;
putnic(TXSTART<<8, pkt, len);
//outnic(CMDR, 0x24);
CMDR=0x24; /* Transmit the packet */
}
return(len);
}
/* Reset the Ethernet card, if 'cold' start, get my 6-byte address */
void resetnic(CONFIGNE *cp, char cold)
{
int i;
// BYTE temp[MACLEN*2];
//outnic(CMDR, 0x21);
CMDR=0x21; /* Stop, DMA abort, page 0 */
SoftDelay(10); /* ..wait to take effect */
//outnic(DCR, DCRVAL);
DCR=DCRVAL;
//outnic(RBCR0, 0);
RBCR0=0; /* Clear remote byte count */
//outnic(RBCR1, 0);
RBCR1=0;
//outnic(RCR, 0x20);
RCR=0x20; /* Rx monitor mode */
//outnic(TCR, 0x02);
TCR=0x02; /* Tx internal loopback */
//outnic(TPSR, TXSTART);
TPSR=TXSTART; /* Set Tx start page 0x40*/
//outnic(PSTART, RXSTART);
PSTART=RXSTART; /* Set Rx start 0x46, stop, boundary */
//outnic(PSTOP, RXSTOP); //0x7e
PSTOP=RXSTOP;
//outnic(BNRY, (BYTE)(RXSTOP-1));
BNRY=(BYTE)(RXSTOP-1); //0x7d?
//outnic(ISR, 0xff);
ISR=0xff; /* Clear interrupt flags */
//outnic(IMR, 0);
IMR=0; /* Mask all interrupts */
if (cold)
{
//outnic(CMDR, 0x22);
// CMDR=0x22; /* Start NIC, DMA abort */
// SoftDelay(10);
// getnic(0, temp, 16); /* Get 6-byte addr */
for (i=0; i<MACLEN; i++) /* Convert addr words to bytes */
cp->myeth[i] = MYMAC[i];//temp[WORDMODE ? i+i : i];
}
//outnic(CMDR, 0x61);
CMDR=0x61; /* Stop, DMA abort, page 1 */
SoftDelay(10);
//for (i=0; i<6; i++) /* Set Phys addr */
//outnic(PAR0+i, cp->myeth[i]);
PAR0=cp->myeth[0];
PAR1=cp->myeth[1];
PAR2=cp->myeth[2];
PAR3=cp->myeth[3];
PAR4=cp->myeth[4];
PAR5=cp->myeth[5];
//for (i=0; i<8; i++) /* Multicast accept-all */
//outnic(MAR0+i, 0xff);
MAR0=0xff;
MAR1=0xff;
MAR2=0xff;
MAR3=0xff;
MAR4=0xff;
MAR5=0xff;
MAR6=0xff;
MAR7=0xff;
//outnic(CURR, RXSTART+1);
CURR=RXSTART+1; /* Set current Rx page */
cp->next_pkt = RXSTART + 1;
//outnic(CMDR, 0x20);
CMDR=0x20; /* DMA abort, page 0 */
//outnic(RCR, promisc ? 0x14 : 0x04);
RCR=promisc ? 0x14 : 0x04; /* Allow broadcasts, maybe all pkts */
//outnic(TCR, 0);
TCR=0; /* Normal Tx operation */
//outnic(ISR, 0xff);
ISR=0xff; /* Clear interrupt flags */
//outnic(CMDR, 0x22);
CMDR=0x22; /* Start NIC */
}
/* Get a packet from a given address in the NIC's RAM */
void getnic(WORD addr, BYTE data[], WORD len)
{
register int count;
register WORD *dataw;
int temp;
count = WORDMODE ? len>>1 : len; // Halve byte count if word I/P
//dataport = ebase + DATAPORT<<8; // Address of NIC data port
//outnic(ISR, 0x40);
ISR=0x40; // Clear remote DMA interrupt flag
//outnic(RBCR0, len&0xff);
temp=len&0xff;
RBCR0=len&0xff; // Byte count
//outnic(RBCR1, len>>8);
temp=len>>8;
RBCR1=len>>8;
//outnic(RSAR0, addr&0xff);
temp=addr&0xff;
RSAR0=addr&0xff; // Data addr
//outnic(RSAR1, addr>>8);
temp=addr>>8;
RSAR1=addr>>8;
//outnic(CMDR, 0x0a);
CMDR=0x0a; // Start, DMA remote read
Delay(1);
#if WORDMODE
// if(WORDMODE==1)
dataw = (WORD *)data; // Use pointer for speed
while(count--) // Get words
*dataw++ =DATAPORT;//*(WORD*)(dataport);
if (len & 1) // If odd length, do last byte
*(BYTE*)dataw =DATAPORT;//*(BYTE*)(dataport);
#else
// else
while(count--)
*data++= DATAPORT;//*(BYTE*)(dataport);
#endif
}
/* Put a packet into a given address in the NIC's RAM */
void putnic(WORD addr, BYTE data[], WORD len)
{
register int count;
register WORD *dataw;//, dataport;
len += len & 1; /* Round length up to an even value */
count = WORDMODE ? len>>1 : len; /* Halve byte count if word O/P */
//dataport = ebase + DATAPORT<<8; /* Address of NIC data port */
//outnic(ISR, 0x40);
ISR=0x40; /* Clear remote DMA interrupt flag */
//outnic(RBCR0, len&0xff);
RBCR0=len&0xff; /* Byte count */
//outnic(RBCR1, len>>8);
RBCR1=len>>8;
//outnic(RSAR0, addr&0xff);
RSAR0=addr&0xff; /* Data addr */
//outnic(RSAR1, addr>>8);
RSAR1=addr>>8;
//outnic(CMDR, 0x12);
CMDR=0x12; /* Start, DMA remote write */
#if WORDMODE /* Word transfer? */
dataw = (WORD *)data;
while(count--)
//*(WORD*)(dataport)=*dataw++; //outpw(dataport, *dataw++); /* O/P words */
DATAPORT=*dataw++;
#else
while(count--) /* O/P bytes */
//*(BYTE*)(dataport)=*data++; //outp(dataport, *data++);
DATAPORT=*data++;
#endif
count = 10000; /* Done: must ensure DMA complete */
//isrtemp=ISR;
while(count && (ISR&0x40)==0)
count--;
}
/* Wrap an NIC Rx page number */
BYTE nicwrap(int page)
{
if (page >= RXSTOP)
page += RXSTART - RXSTOP;
else if (page < RXSTART)
page += RXSTOP - RXSTART;
return(page);
}
/* Input a byte from a NIC register
BYTE innic(int reg)
{
//return(inp((WORD)(ebase+reg)));
//return(*((volatile BYTE*)(ebase+(((LWORD)(reg))<<8))));
}
//Output a byte to a NIC register
void outnic(int reg, int b)
{
//outp((WORD)(ebase+reg), b);
//Uart_Printf("\nOUTNIC");
*((volatile WORD*)(ebase+(((LWORD)(reg))<<8)))=b;
}*/
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -