📄 etherdev.c
字号:
/* 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 + -