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

📄 etherdev.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* 34. Enable RTS1.  Note that RTS1 can be brought out to one of two     * different pio pins (PC15 or PB19).     */#if RTS1_PB19    IMMRBase->pip_pbpar |= 0x1000;          /* Enable RTS1 on PB19 */    IMMRBase->pip_pbdir |= 0x1000;#else    IMMRBase->pio_pcpar |= 0x0001;          /* Enable RTS1 on PC15 */    IMMRBase->pio_pcdir &= ~0x0001;#endif    /* 35. Enable transmit/receive: */    IMMRBase->scc_regs[SCC1_REG].scc_gsmr_l = 0x1088003c;    return(0);}/* enselftest():    1. Enable ethernet interface.    2. Put the PHY in loopback.    3. Send a packet, and see if that packet is received.    4. Disable the ethernet interface.    Return 1 if passed, else -1.*/intenselftest(int verbose){#define TESTSIZE    50    int     i, timeout, passed;    uchar   *bp;    ulong   bcsr4;    vushort event;    struct ether_header *te;        enreset();    eninit();    passed = 1;    bcsr4 = *(ulong *)BCSR4_BASE;    bcsr4 |= ETHLOOP;                       /* Enable loopback */    bcsr4 &= ~TFPLDL;                       /* Enable full duplex */    *(ulong *)BCSR4_BASE = bcsr4;    IMMRBase->scc_regs[SCC1_REG].scc_psmr |= (ENET_PSMR_LPB|ENET_PSMR_FDE);    enableBroadcastReception();    te = (struct ether_header *) getXmitBuffer();    memcpy((char *)&(te->ether_shost),BroadcastAddr,6);    memcpy((char *)&(te->ether_dhost),BroadcastAddr,6);    te->ether_type = ETHERTYPE_IP;    bp = (uchar *)(te+1);    for(i=0;i<TESTSIZE;i++)        *bp++ = (uchar )i;    sendBuffer(sizeof(struct ether_header)+TESTSIZE);    for(timeout=1000000;timeout>0;timeout--) {        event = IMMRBase->scc_regs[SCC1_REG].scc_scce;        IMMRBase->scc_regs[SCC1_REG].scc_scce = event;        if (!(event & ENET_SCCE_RXF))       /* Received frame interrupt */            continue;        if(!(rbptr->status & BD_READY)) {            bp = rbptr->baddr;            bp+=sizeof(struct ether_header);            for(i=0;i<TESTSIZE;i++,bp++) {                if (*bp != i) {                    if (verbose)                        printf("Data valid failure %02x != %02x\n",*bp,i);                    passed = -1;                    break;                }            }            /* Make the buffer ready. */            rbptr->status |= BD_READY;            break;        }    }    if (timeout == 0) {        passed = -1;        if (verbose)            printf("Timed out waiting for data.\n");    }    bcsr4 = *(ulong *)BCSR4_BASE;    bcsr4 &= ~ETHLOOP;                      /* Disable loopback */    bcsr4 |= TFPLDL;                        /* Disable full duplex */    *(ulong *)BCSR4_BASE = bcsr4;    IMMRBase->scc_regs[SCC1_REG].scc_psmr &= ~(ENET_PSMR_LPB|ENET_PSMR_FDE);    disableBroadcastReception();    if ((verbose) && (passed > 0))        printf("Passed\n");    DisableEthernet();    return(passed);}/* geteinbuf():    Get ethernet input buffer...    Do whatever is necessary to pull the packet out of the ethernet device    and pass that packet (along with the size of the packet) to the    processPACKET() function.*/static intgeteinbuf(){    int cnt;    struct  enet_bd *rp;    cnt = 0;    /* Stay in this loop while there is an active receive buffer. */    /* If receive buffer is empty, just return. */    while(!(rbptr->status & BD_READY)) {        EtherRFRAMECnt++;        processPACKET((struct ether_header *)rbptr->baddr,rbptr->length);        /* Make the buffer ready. */        rbptr->status |= BD_READY;        /* If WRAP, then back to top; else, increment to next BD. */        if (rbptr->status & BD_WRAP)            rbptr = &IMMRBase->qcp_or_ud.umd.e_bdtbl[XBUFCNT];        else            rbptr++;        cnt++;    }#if 1    /* Make sure no other receive buffers are ready... */    rp = rbptr;    while(1) {        if (rp->status & BD_WRAP)            rp = &IMMRBase->qcp_or_ud.umd.e_bdtbl[XBUFCNT];        else            rp++;        if (rp == rbptr)            break;        if (!(rp->status & BD_READY))            printf("rbptr buffer ready out of order!\n");    }#endif    return(cnt);}/* polletherdev():    Called by pollethernet() to do the device-specific portion of the    ethernet polling.  This code is the first step in processing incoming    ethernet packets.  If a packet is available, the functino geteinbuf()    (get ethernet input buffer) is called to pass the packet to the higher    level processPACKET() function.    IMPORTANT NOTE:    This function MUST be re-entrant.  There is a possibility that the    processPACKET() function will ultimately call polletherdev() again.    This means that once the packet has been detected in the device, it     is important that this code do whatever is necessary to assure that    the same packet will not be seen as available to the nested caller.    In other words...    clear the packet from the device prior to calling processPACKET().*/intpolletherdev(){    vushort event;    int     pcnt;    pcnt = 0;    event = IMMRBase->scc_regs[SCC1_REG].scc_scce;    IMMRBase->scc_regs[SCC1_REG].scc_scce = event;    if (event & ENET_SCCE_RXF) {    /* Received frame interrupt */        geteinbuf();        pcnt++;    }    return(pcnt);}/* getXmitBuffer():    Called by various points in the IP/UDP/ICMP code for a buffer that    will ultimately be the next output packet.*/uchar *getXmitBuffer(){    /* Wait for the next buffer descriptor to become available... */    while(tbptr->status & BD_READY);    return(tbptr->baddr);}/* 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)        printPkt((struct ether_header *)tbptr->baddr,length,ETHER_OUTGOING);    /* Keep stats: */    if (EtherXFRAMECnt) {        if (prevtbptr->status & BD_DEF)            EtherDEFCnt++;        if (prevtbptr->status & BD_LC)            EtherLCCnt++;        if (prevtbptr->status & BD_RL)            EtherRLCnt++;    }    EtherXFRAMECnt++;    /* Make the current transmit buffer ready and populate the length. */    tbptr->length = (ushort)length;#if 1    tbptr->status |= (BD_PAD | BD_READY | BD_LAST | BD_TC);#else    tbptr->status |= (BD_READY | BD_LAST | BD_TC);#endif    /* Keep track of this BD so that the status can be looked at when the */    /* next transmission is done. */    prevtbptr = tbptr;    /* If WRAP, then back to top; else, just increment to next BD. */    if (tbptr->status & BD_WRAP)        tbptr = IMMRBase->qcp_or_ud.umd.e_bdtbl;    else        tbptr++;    return(0);}/* Disable/Enable either broadcast or promiscuous mode... */voiddisableBroadcastReception(){    IMMRBase->scc_regs[SCC1_REG].scc_psmr |= ENET_PSMR_BRO;}voidenableBroadcastReception(){    IMMRBase->scc_regs[SCC1_REG].scc_psmr &= ~ENET_PSMR_BRO;}voidenablePromiscuousReception(){    IMMRBase->scc_regs[SCC1_REG].scc_psmr |= ENET_PSMR_PRO;}voiddisablePromiscuousReception(){    IMMRBase->scc_regs[SCC1_REG].scc_psmr &= ~ENET_PSMR_PRO;}voidenresetmmu(){}/* 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 + -