⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 etherdev.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
字号:
/* etherdev.c: *  This code supports some basic ethernet device-specific stuff for the *  68EN302 processor. * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Author: Ed Sutter *  email:  esutter@lucent.com      (home: lesutter@worldnet.att.net) *  phone:  908-582-2351            (home: 908-889-5161) */#include "config.h"#if INCLUDE_ETHERNET#include "cpuio.h"#include "ether.h"#include "genlib.h"#include "stddefs.h"int     EtherRLCnt, EtherDEFCnt, EtherLCCnt;int     EtherXFRAMECnt, EtherRFRAMECnt, EtherDRVRETRYCnt;struct  snoopinfo snoopInfo;ushort  ArCtrl;                     /* Address recognition reg */static  ulong xbuf[XBUFCNT][400];   /* Transmit & receive buffers pointed */static  ulong rbuf[RBUFCNT][400];   /* to by the buffer descriptors. */int geteinbuf(void);/* struct ebd: *  Structure used to overlay onto the ethernet buffer descriptors: */struct  ebd {    ushort  flags;    ushort  length;    ushort  ptrhi;    ushort  ptrlo;} *rbptr, *xbptr;/* ShowEtherdevStats(): *  Called by the command "ether stat" on the monitor's command line. *  This function and a common ShowEthernetStats() are used to dump *  generic as well as device-specific ethernet driver statistics. */voidShowEtherdevStats(){    printf("Driver retry count:      %d\n",EtherDRVRETRYCnt);    printf("Retry_count_exceeded:    %d times\n",EtherRLCnt);    printf("Late-collision count:    %d\n",EtherLCCnt);    printf("Defer-indication count:  %d\n",EtherDEFCnt);    printf("Transmitted frames:      %d\n",EtherXFRAMECnt);    printf("Received frames:         %d\n",EtherRFRAMECnt);    printf("IP hdr cksum errors:     %d\n",EtherIPERRCnt);    printf("UDP pkt cksum errors:    %d\n",EtherUDPERRCnt);    if (snoopInfo.on) {        char smac[32];        EtherToString(snoopInfo.mac,smac);        printf("Snoop MAC:               %s\n",smac);    }}intEtherdevStartup(int verbose){    int eninit();    EtherRLCnt = 0;    EtherLCCnt = 0;    EtherDEFCnt = 0;    EtherXFRAMECnt = 0;    EtherRFRAMECnt = 0;    EtherDRVRETRYCnt = 0;    snoopInfo.on = 0;    /* Put ethernet controller in reset: */    enreset();    /* Initialize controller: */    eninit();    /* Enable all ethernet ctrlr interrupts: */    *(ushort *)INTR_MASK = 0x07ff;    /* Enable the controller: */    *(ushort *)ECNTRL = 3;    return(0);}voidDisableEtherdev(void){    enreset();}/* pollethernet(): *  If the interface is active, poll for incoming packets.  Return *  the number of packets processed. */intpolletherdev(void){    ushort  event;    int     pcnt=0;    event = *(ushort *)INTR_EVENT;    *(ushort *)INTR_EVENT = event;    if (event & RFINT) {    /* Received frame interrupt */        pcnt++;        geteinbuf();    }    return(pcnt);}voidenreset(void){    /* Reset the controller, but leave it disabled: */    *(ushort *)ECNTRL = 0;    *(ushort *)ECNTRL = 1;#if SYSTEM_PPAFAXROUTER    /* Reset the transceiver also: */    pioset('b',11);    pioclr('b',11);#endif}inteninit(void){    uchar   *cam;    struct  ebd *bdp;    int i;    /* Ethernet DMA config: */    /* BDSIZE=01 (16x & 112r) */    *(ushort *)EDMA = 0x000b | (BDSIZE);    /* Maximum receive buffer length is 1518. */    *(ushort *)EMRBLR = 0x05ee;    /* Use interrupt vector 224. */    *(ushort *)INTR_VECT = 0x00e0;    *(ushort *)ECNFIG = 0x0000;    /* Self test using ETHER_TEST... */    *(ushort *)ETHER_TEST = 0x0080;    for(i=0;i<50000;i++)        if ((*(ushort *)ETHER_TEST & 0x0080) == 0)            break;    if (i == 50000) {        printf("Ethernet random number test failed\n");        return(-1);    }    /* Set address recognition control based on command line input. */    *(ushort *)AR_CNTRL = ArCtrl;    /* Initialize Buffer Descriptors: */    bdp =  (struct ebd *)EBD;    xbptr = (struct ebd *)XBDBASE;    rbptr = (struct ebd *)RBDBASE;    /* Of the total 128 buffer descriptors available, only */    /* XBUFCNT + RBUFCNT are used here... */    for (bdp = xbptr,i=0;i<XBUFCNT;i++,bdp++) {        bdp->flags = 0;        bdp->length = 0;        bdp->ptrhi = ((ushort)((ulong)(xbuf[i]) >> 16) & 0x00ff);        bdp->ptrlo = (ushort)((ulong)xbuf[i] & 0xffff);        if (i == (XBUFCNT-1))            bdp->flags |= WRAPBIT;  /* Set WRAP bit on final BD */    }    for(bdp = rbptr,i=0;i<RBUFCNT;i++,bdp++) {        bdp->flags = 0x8000;        bdp->length = 0;        bdp->ptrhi = ((ushort)((ulong)(rbuf[i]) >> 16) & 0x00ff);        bdp->ptrlo = (ushort)((ulong)rbuf[i] & 0xffff);        if (i == (RBUFCNT-1))            bdp->flags |= WRAPBIT;  /* Set WRAP bit on final BD */    }    /* Load the CAM with this board's ethernet address. */    cam = (uchar *)CET;    *cam++ = BinEnetAddr[0];    *cam++ = BinEnetAddr[1];    *cam++ = BinEnetAddr[2];    *cam++ = BinEnetAddr[3];    *cam++ = BinEnetAddr[4];    *cam++ = BinEnetAddr[5];    return(0);}intgeteinbuf(void){    int cnt, timeout;    uchar   *dp;    struct  ebd *rp;    cnt = 0;    /* Stay in this loop while there is an active receive buffer. */    /* If receive buffer is empty, just return. */    timeout = 100000;    while(!(rbptr->flags & 0x8000)) {        EtherRFRAMECnt++;        /* Extract data ptr from buffer descriptor: */        dp = (uchar *)(((ulong)(rbptr->ptrhi)<<16) & (ulong)0xff0000);        dp += (int)(rbptr->ptrlo);        processPACKET((struct ether_header *)dp,rbptr->length);        /* Make the buffer ready. */        rbptr->flags |= 0x8000;        /* If WRAP, then back to top; else, increment to next BD. */        if (rbptr->flags & WRAPBIT)            rbptr = (struct ebd *)RBDBASE;        else            rbptr++;        cnt++;    }#if 1    /* Make sure no other receive buffers are ready... */    rp = rbptr;    timeout=100000;    while(timeout > 0) {        if (rp->flags & WRAPBIT)            rp = (struct ebd *)RBDBASE;        else            rp++;        if (rp == rbptr)            break;        if (!(rp->flags & 0x8000))            printf("rbptr buffer ready out of order!\n");        timeout--;    }    if (timeout <= 0) {        printf("geteinbuf timeout2\n");        enreset();        EtherIsActive = 0;    }#endif    return(cnt);}uchar *getXmitBuffer(){    int     timeout;    uchar   *dp;    /* Wait for the next buffer descriptor to become available... */    timeout = 100000;    while(xbptr->flags & 0x8000) {        timeout--;        if (timeout <= 0) {            printf("getXmitBuffer timeout\n");            enreset();            EtherIsActive = 0;        }    }    /* Extract the data pointer from the buffer descriptor: */    dp = (uchar *)(((ulong)(xbptr->ptrhi) << 16) & (ulong)0x00ff0000);    dp += (int)(xbptr->ptrlo);    return(dp);}/* sendBuffer():   Set the flag within the current transmit buffer descriptor indicating   that it is ready to be transmitted.  Then increment the BD pointer to    the next buffer descriptor.*/intsendBuffer(int length){    if (EtherVerbose &  SHOW_OUTGOING) {        uchar   *dp;        dp = (uchar *)(((ulong)(xbptr->ptrhi) << 16) & (ulong)0xff0000);        dp += (int)(xbptr->ptrlo);        printPkt((struct ether_header *)dp,length,ETHER_OUTGOING);    }    /* Make the current transmit buffer ready and populate the length. */    xbptr->length = (ushort)length;    xbptr->flags |= 0x8c00;    /* If WRAP, then back to top; else, just increment to next BD. */    if (xbptr->flags & WRAPBIT)        xbptr = (struct ebd *)XBDBASE;    else        xbptr++;    return(0);}#if 0int_sendBuffer(int length){    int err;    ushort  flags;    if (EtherVerbose &  SHOW_OUTGOING) {        uchar   *dp;        dp = (uchar *)(((ulong)(xbptr->ptrhi) << 16) & (ulong)0xff0000);        dp += (int)(xbptr->ptrlo);        printPkt((struct ether_header *)dp,length,ETHER_OUTGOING);    }    /* Make the current transmit buffer ready and populate the length. */    xbptr->length = (ushort)length;    xbptr->flags |= 0x8c00;    /* Wait for packet to be sent, if error, return -1. */    timeout = 100000;    while(timeout > 0) {        flags = xbptr->flags;        if (!(flags & READY))            break;    }    it (timeout <= 0) {        printf("_sendBuffer timeout\n");        enreset();        EtherIsActive = 0;        return(-1);    }    err = 0;    /* Keep stats: */    EtherXFRAMECnt++;    if (flags & DEF) {        EtherDEFCnt++;        err = -1;    }    if (flags & LC) {        EtherLCCnt++;        err = -1;    }    if (flags & RL) {        EtherRLCnt++;        err = -1;    }    /* If WRAP, then back to top; else, just increment to next BD. */    if (xbptr->flags & WRAPBIT)        xbptr = (struct ebd *)XBDBASE;        else        xbptr++;    return(err);}voidsendBufferRetry(int length){    struct  ebd *xptr;    uchar   *dp, *dp1;    xptr = xbptr;    while(_sendBuffer(length) == -1) {        EtherDRVRETRYCnt++;        dp = getXmitBuffer();        dp1 = (uchar *)(((ulong)(xptr->ptrhi) << 16) & (ulong)0xff0000);        dp1 += (int)(xptr->ptrlo);        memcpy(dp,dp1,length);    }}#endif/* enselftest(): *  Return 1 if passed, else -1. */intenselftest(int verbose){    if (verbose)        printf("Self test not available\n");    return(1);}voidenresetmmu(void){}voiddisablePromiscuousReception(){}voidenablePromiscuousReception(){}voiddisableBroadcastReception(){    *(ushort *)AR_CNTRL = ArCtrl | 0x3000;  /* Disable bcast rcv. */}voidenableBroadcastReception(){    *(ushort *)AR_CNTRL = ArCtrl;           /* Re-enable bcast rcv. */}/* extGetEtherAdd() & extGetIpAdd():    These two functions return a char * to a string that represents an    IP or MAC address.  If they return NULL, then it is assumed by the    calling function that there is no target specific hardware that    contains the IP and/or MAC address.*/char *extGetEtherAdd(){    return((char *)0);}char *extGetIpAdd(){    return((char *)0);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -