?? ne64driver.c
字號:
tU08 * pOut;
tU08 * pIn;
tU16 ctr;
/* check FIFO buffer A flag */
if (IEVENT_RXACIF)
{ /* frame in buffer A */
_DEBUGT("-RXA-");
pOut=(tU08 *)buffer;
pIn=emacFIFOa;
/* copy data from FIFO to output buffer */
for (ctr=0; ctr <= RXAEFP; ctr++)
{
*pOut=*pIn;
pOut++;
pIn++;
}
IEVENT = IEVENT_RXACIF_MASK;
return ctr; /* return number of bytes copied */
}
/* check FIFO buffer B flag */
if (IEVENT_RXBCIF)
{ /* frame in buffer B */
_DEBUGT("-RXB-");
pOut=(tU08 *)buffer;
pIn=emacFIFOb;
/* copy data from FIFO to output buffer */
for (ctr=0; ctr <= RXBEFP; ctr++)
{
*pOut=*pIn;
pOut++;
pIn++;
}
IEVENT = IEVENT_RXBCIF_MASK;
return ctr; /* return number of bytes copied */
}
return 0; /* neither A or B buffer filled */
}
//===============================================
tU16 EtherReceiveZeroCopy(tU08 * whichbuffer)
{
/* check FIFO buffer A flag */
if (IEVENT_RXACIF)
{ /* frame in buffer A */
_DEBUGT("-RXA-");
*whichbuffer = BUFA_FULL;
return (RXAEFP); /* return number of bytes copied */
}
/* check FIFO buffer B flag */
if (IEVENT_RXBCIF)
{ /* frame in buffer B */
_DEBUGT("-RXB-");
*whichbuffer = BUFB_FULL;
return (RXBEFP); /* return number of bytes copied
*/
}
return 0; /* neither A or B buffer filled */
}
//===============================================
#else //RX_POLL_MODE
#endif // RX_POLL_MODE
//===============================================
void EtherSend(void * databuf, tU16 datalen)
{
tU16 ctr;
#if WORD_ACCESS
tREG16 * pIn;
tREG16 * pOut;
#else
tU08 * pIn;
tU08 * pOut;
#endif
_DEBUGT("-TXSTART-");
/* check & fix the length if incorrect
*/
#if EMAC_TX_SZ > 1514
/* truncate if longer than Ethernet limit */
if (datalen > 1514) datalen=1514;
#else
/* truncate if longer than TX FIFO buffer limit */
if (datalen > EMAC_TX_SZ) datalen=EMAC_TX_SZ;
#endif
/* extend if shorter -> however this might be security flaw
as we do not know what data are stored beyond our frame */
if (datalen < 60) datalen=60;
#if WORD_ACCESS
pIn=(tREG16 *) databuf;
#else
pIn=(tU08 *) databuf;
#endif
pOut=emacFIFOtx;
/* copy input buffer to TX FIFO */
#if WORD_ACCESS
if ((datalen % 2) == 0) {
for (ctr=datalen/2; ctr >0; ctr--)
{
*pOut=*pIn;
pOut++;
pIn++;
}
} else {
for (ctr=(datalen+1)/2; ctr >0; ctr--)
{
*pOut=*pIn;
pOut++;
pIn++;
}
}
#else
for (ctr=datalen; ctr >0; ctr--)
{
*pOut=*pIn;
pOut++;
pIn++;
}
#endif
/* set the offset where the last frame byte resides in FIFO */
TXEFP=datalen-1;
//Wait for TX idle
while (TXCTS_TXACT == 1);
/* issue a transmit command */
TXCTS_TCMD=TCMD_START;
_DEBUGT( "-TXEND-");
}
//===============================================
void EtherOpen(tU08 miisetup, /* mii preamble & clock setup */
tU08 bufmap, /* buffer configuration) */
tU16 maxfl, /* initial max.frame length for receive */
void * pmacad, /* pointer to MAC address definition */
tU08 control, /* the acceptance mask*/
tU16 etype, /* programmable ethertype (16bit value)*/
tU08 rxmode, /* reception mode settings */
tU08 netctl /* network control setup (see NETCT_X)*/
) {
tU08 ctr;
tU16 * pIn;
tMACADStr * pInMAC = (tMACADStr *)&MACAD2;
_DEBUGT("EtherOpen(start)\n\r");
/* do EMAC software reset */
SWRST = SWRST_MACRST_MASK;
/* wait a while */
for (ctr=16; ctr >0; ctr--);
/* setup MDC clock */
MCMST_MDCSEL=miisetup;
_DEBUGT("mdcsel=");_DEBUGC(miisetup);
/* setup FIFO memory configuration */
BUFCFG_BUFMAP=bufmap;
_DEBUGT("; bufmap=");_DEBUGC(bufmap);
/* setup max. reception frame length */
BUFCFG_MAXFL=maxfl;
_DEBUGT("; maxfl=");_DEBUGI(maxfl);
/* set hardware address */
_DEBUGT("\n\rMAC ADDR");
pIn=(tU16 *)pmacad;
for (ctr=0; ctr < sizeof(tMACADStr)/2; ctr++)
{
pInMAC->Word[ctr] = *pIn;
_DEBUGI(*pIn);
pIn++;
}
_DEBUGNL;
EtherType(control, etype);
/* setup the reception mode */
RXCTS=rxmode;
_DEBUGT("rxmode=");_DEBUGC(rxmode);
#ifdef ETH_DEBUG
#if ETH_DEBUG
if (rxmode & RXCT_RFCE) _DEBUGT("=RFCE |");
if (rxmode & RXCT_PROM) _DEBUGT(" PROM |");
if (rxmode & RXCT_CONMC) _DEBUGT(" CONMC |");
if (rxmode & RXCT_BCREJ) _DEBUGT(" BCREJ");
#endif
#endif
/* and finally network control */
EmacControl(netctl);
/* after that the EMAC can be enabled */
EmacEnable();
_DEBUGT("\n\rEtherOpen(end)\n\r");
}
//===============================================
void EtherClose(void)
{
_DEBUGT("EtherClose\n\r");
/* disable EMAC */
EmacDisable();
/* mask all EMAC interrupts */
IMASK=0;
}
//===============================================
void EmacDisable(void)
{
/* disable EMAC */
NETCTL_EMACE = 0;
}
//===============================================
void EmacEnable(void)
{
/* Enable EMAC */
NETCTL_EMACE = 1;
}
//===============================================
void EmacControl(tU08 netctl)
{
/* Enable EMAC */
NETCTL=netctl;
_DEBUGT("\n\rnetctl"); _DEBUGC(netctl);
#ifdef ETH_DEBUG
#if ETH_DEBUG
if (netctl & NETCT_ESWAI) _DEBUGT("= ESWAI |");
if (netctl & NETCT_EXTPHY) _DEBUGT(" EXTPHY |");
if (netctl & NETCT_MLB) _DEBUGT(" MLB |");
if (netctl & NETCT_FDX) _DEBUGT(" FDX");
#endif
#endif
}
//===============================================
#define CRC32_POLY 0x04c11db7UL
#define SET_MCAST_LIST 0x01
#define SET_ALL_MCAST 0x02
void EtherIoctl(tU08 flag, void * optionPtr, tU08 optionLen)
{
tU32 calcCRC;
tU08 currByte;
tU08 Byte, bit;
tU32 hashEntry;
tU08 * multiAddr;
tU16 logicalAddrFilter[4];
tMCHASHStr * pHASH = (tMCHASHStr*)&MCHASH3;
_DEBUGT("EtherIoctl(start)\n\r");
/* Setup our list of multicast addresses to receive. */
if (flag & SET_MCAST_LIST)
{
_DEBUGT("SET_MCAST_LIST\n\r");
/* Clear the address filter (since this IOCTL call will add all the
* entries we need. */
logicalAddrFilter[0] = 0;
logicalAddrFilter[1] = 0;
logicalAddrFilter[2] = 0;
logicalAddrFilter[3] = 0;
/* Get the first address */
multiAddr = (tU08 *) optionPtr;
while (optionLen-- > 0)
{
/* Initialize the calculated CRC (with all ones) */
calcCRC = 0xffffffffUL;
/* For all the bytes in the (6 byte) address */
for (Byte=0;Byte<6;Byte++)
{
currByte = multiAddr[Byte];
/* For each bit in the current byte */
for (bit=0;bit<8;bit++)
{
/* Shift the calculated CRC left by one */
calcCRC <<= 1;
/* If the current bit is one... */
if ((currByte >> bit) & 0x01)
{
/* ... XOR the calculated CRC with the CRC-32 polynomial */
calcCRC ^= CRC32_POLY;
}
}
}
/* Get the most significant 6 bits from the calculated CRC */
hashEntry = (calcCRC & 0xfc000000UL) >> 26;
/* Decode the above number and set the appropriate bit in the EMAC logical
* address filter */
logicalAddrFilter[(tU08) (hashEntry >> 4)] |=
1 << ((tU08) (hashEntry % 16));
multiAddr += 6;
}
for (currByte=3; currByte > 0; currByte--)
{
pHASH->Word[currByte]=logicalAddrFilter[currByte];
}
}
/* Set the EMAC to receive all multicast packets. */
if (flag & SET_ALL_MCAST)
{
_DEBUGT("SET_ALL_MCAST\n\r");
MCHASH0=0xffff;
MCHASH1=0xffff;
MCHASH2=0xffff;
MCHASH3=0xffff;
}
_DEBUGT("EtherIoctl(end)\n\r");
}
//===============================================
void EtherGetPhysAddr(void * ethaddr) {
tU08 ctr;
tU16 * peth;
tMACADStr * pethReg = (tMACADStr *)&MACAD2;
_DEBUGT("EtherGetPhysAddr");
peth=ethaddr;
for (ctr=0; ctr < sizeof(tMACADStr)/2; ctr++)
{
*peth=pethReg->Word[ctr]; /* copy MAC address, word after word */
_DEBUGI(*peth);
peth++;
}
_DEBUGNL;
}
//===============================================
void EtherType(tU08 control, tU16 etype)
{
_DEBUGT("EtherType = ");
/* setup the ethertype control register */
ETCTL=control;
_DEBUGC(control);
#ifdef ETH_DEBUG
#if ETH_DEBUG
if (control & T_PET) _DEBUGT("= PET |");
if (control & T_EMW) _DEBUGT("EMW |");
if (control & T_IPV6) _DEBUGT("IPV6 |");
if (control & T_ARP) _DEBUGT("ARP |");
if (control & T_IPV4) _DEBUGT("IPV4 |");
if (control & T_IEEE) _DEBUGT("IEEE ");
#endif
#endif
/* setup the programmable ethertype */
_DEBUGT("; Programmable etype = ");_DEBUGI(etype);_DEBUGNL;
ETYPE=etype;
}
//===============================================
void EtherAbortTx(void)
{
_DEBUGT("EtherAbortTX\n\r");
TXCTS_TCMD=TCMD_ABORT;
}
//===============================================
tU16 EtherPause(tU08 ptrc, tU16 ptime)
{
_DEBUGT("EtherPause(start)\n\r");
TXCTS_PTRC = ptrc;
if (ptrc)
{
_DEBUGT("ptrc=1 (send pause)");
PTIME=ptime;
while (TXCTS_TXACT == 1);
TXCTS_TCMD=TCMD_PAUSE; //send pause
}
else
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -