📄 etherdev.c
字号:
/* Frame gap set */ *(ulong *)(EMAC_I_FRAME_GAP_REG) = 0x00000008; ppcMtmalier(MAL_IER_DE | MAL_IER_NE | MAL_IER_TE | MAL_IER_OPBE | MAL_IER_PLBE); emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE; if (EtherSpeed & Is100BaseT) emac_ier |= EMAC_ISR_SYE; *(ulong *)(EMAC_IER) = emac_ier; return (0);}intEtherdevStartup(int verbose){ /* Initialize local device error counts here. */ /* Put ethernet controller in reset: */ enreset(); /* Initialize controller: */ eninit(); return(0);}voiddisablePromiscuousReception(void){ *(ulong *)(EM0RMR) = *(ulong *)(EM0RMR) & ~EMAC_RMR_PME;}voidenablePromiscuousReception(void){ *(ulong *)(EM0RMR) = *(ulong *)(EM0RMR) | EMAC_RMR_PME;}voiddisableBroadcastReception(void){ *(ulong *)(EM0RMR) = *(ulong *)(EM0RMR) & ~EMAC_RMR_BAE;}voidenableBroadcastReception(void){ *(ulong *)(EM0RMR) = *(ulong *)(EM0RMR) | EMAC_RMR_BAE;}/* * enselftest(): * Do a simple read of the PHY ID register and verify that it is * as expected. Then put the PHY in loopback and verify that what * is transmitted is what is received. * Return 1 if passed, else -1. */intenselftest(int verbose){ int retval, timeout; uchar *msg; ushort id1, id2; ulong mal_rx_eob, len; static uchar testmsg[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 't', 'e', 's', 't' }; retval = 1; if (verbose) printf("Self test "); /* First read the PHY ID registers and verify valid device ID. */ phy_read(PHY_ID1,&id1); phy_read(PHY_ID2,&id2); if ((((ulong)id1 << 16) | (ulong)id2) != 0x20005c10) { if (verbose) printf("phy-id failed (%04x%04x)\n",id1,id2); retval = -1; goto done; } /* Next, put the PHY in loopback and send a packet to see if we receive * what we transmit... */ phy_write(PHY_BMCR,PHY_BMCR_LOOP); msg = getXmitBuffer(); memcpy(msg,testmsg,sizeof(testmsg)); sendBuffer(sizeof(testmsg)); /* Wait for the looped back message... */ for(timeout=20000000;timeout > 0;timeout--) { mal_rx_eob = ppcMfmalrxeobisr(); if ((mal_rx_eob & 0x80000000) == 0x80000000) break; } if (timeout == 0) goto failed; len = (ulong) rx[rx_slot].data_len; /* Get len */ ppcMtmalrxeobisr(mal_rx_eob); rx[rx_slot].ctrl |= MAL_RX_CTRL_EMPTY; ppcMtmalrxeobisr(mal_rx_eob); if (!memcmp(rx[rx_slot].data_ptr,testmsg,len)) {failed: if (verbose) printf("lbk failed\n"); retval = -1; goto done; } if (verbose) printf("passed\n"); /* Put things back to normal... */done: enreset(); eninit(); return(retval);}voidShowEtherdevStats(void){ printf("Interface speed is %d Mbs, %s duplex.\n", EtherSpeed & Is100BaseT ? 100 : 10, EtherSpeed & IsFullDuplex ? "full" : "half");#if 0 printf(" EMAC DEBUG...\n"); printf(" EM0MR0: %lx \n", *(ulong *)(EM0MR0)); printf(" EM0MR1: %lx \n", *(ulong *)(EM0MR1)); printf(" EMAC_TXM0: %lx \n", *(ulong *)(EMAC_TXM0)); printf(" EMAC_TXM1: %lx \n", *(ulong *)(EMAC_TXM1)); printf(" EM0RMR: %lx \n", *(ulong *)(EM0RMR)); printf(" EMAC_ISR: %lx \n", *(ulong *)(EMAC_ISR)); printf(" EMAC_IER: %lx \n", *(ulong *)(EMAC_IER)); printf(" EM0IAH: %lx \n", *(ulong *)(EM0IAH)); printf(" EM0IAL: %lx \n", *(ulong *)(EM0IAL)); printf(" EMAC_VLAN_TPID_REG: %lx \n", *(ulong *)(EMAC_VLAN_TPID_REG)); printf(" MAL DEBUG...\n"); printf(" MCR: %lx\n", ppcMfmalcr()); printf(" ESR: %lx\n", ppcMfmalesr()); printf(" IER: %lx\n", ppcMfmalier()); printf(" DBR: %lx\n", ppcMfmaldbr()); printf(" TXCASR: %lx\n", ppcMfmaltxcasr()); printf(" TXCARR: %lx\n", ppcMfmaltxcarr()); printf(" TXEOBISR: %lx\n", ppcMfmaltxeobisr()); printf(" TXDEIR: %lx\n", ppcMfmaltxdeir()); printf(" RXCASR: %lx\n", ppcMfmalrxcasr()); printf(" RXCARR: %lx\n", ppcMfmalrxcarr()); printf(" RXEOBISR: %lx\n", ppcMfmalrxeobisr()); printf(" RXDEIR: %lx\n", ppcMfmalrxdeir()); printf(" TXCTP0R: %lx\n", ppcMfmaltxctp0r()); printf(" TXCTP1R: %lx\n", ppcMfmaltxctp1r()); printf(" RXCTP0R: %lx\n", ppcMfmalrxctp0r()); printf(" RCBS0: %lx\n", ppcMfmalrcbs0());#endif}uchar *getXmitBuffer(void){ return((uchar *)tx_buff);}intsendBuffer(int length){ int timeout; if (EtherVerbose & SHOW_OUTGOING) printPkt((struct ether_header *)tx_buff,length,ETHER_OUTGOING); if (length > ENET_MAX_MTU) length = ENET_MAX_MTU; if (length < ETHER_MINPKT) length = ETHER_MINPKT; /* set TX Buffer busy, and send it */ tx[0].ctrl = (MAL_TX_CTRL_LAST | EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP) & ~(EMAC_TX_CTRL_ISA | EMAC_TX_CTRL_RSA); if ((NUM_TX_BUFF - 1) == tx_slot) tx[0].ctrl |= MAL_TX_CTRL_WRAP; tx[0].data_len = (short)length; tx[0].ctrl |= MAL_TX_CTRL_READY; *(ulong *)(EMAC_TXM0) = *(ulong *)(EMAC_TXM0) | EMAC_TXM0_GNP0; /* Poll unitl the packet is sent */ timeout = 0; while (*(ulong *)(EMAC_TXM0) & EMAC_TXM0_GNP0) { if (++timeout == LoopsPerSecond) { printf("sendBuffer(): poll giving up\n"); break; } } EtherXFRAMECnt++; return(0);}voidenresetmmu(void){}voidDisableEtherdev(void){ enreset();}char *extGetIpAdd(void){ return((char *)0);}char *extGetEtherAdd(void){ return((char *)0);}/* * polletherdev(): * Called continuously by the monitor to determine if there is any incoming * ethernet packets. */intpolletherdev(void){ int pktcnt, i; ulong mal_rx_eob, mal_esr, len;#if MONITOR_LINK static int linkstate; if (!phy_linkup()) { if (linkstate == LINK_UP) { printf("Ethernet link down\n"); linkstate = LINK_DOWN; } } else { if (linkstate == LINK_DOWN) printf("Ethernet link up\n"); linkstate = LINK_UP; }#endif /* If ANY error status is set, just reset here... */ mal_esr = ppcMfmalesr(); if (mal_esr & MAL_ESR_ANY) { enreset(); eninit(); return(0); } pktcnt = 0; mal_rx_eob = ppcMfmalrxeobisr(); if (mal_rx_eob & 0x80000000) { while(1) { i = rx_slot; if (rx[i].ctrl & MAL_RX_CTRL_EMPTY) break; rx_slot++; if (rx_slot == NUM_RX_BUFF) rx_slot = 0; len = (ulong) rx[i].data_len; /* Get len */ if (len) { if ((len > ENET_MAX_MTU) || (EMAC_RX_ERRORS & rx[i].ctrl)) len = 0; else { pktcnt++; EtherRFRAMECnt++; processPACKET((struct ether_header *)rx[i].data_ptr, len); } } /* Free the receive buffer. */ rx[i].ctrl |= MAL_RX_CTRL_EMPTY; } /* clear EOB */ ppcMtmalrxeobisr(mal_rx_eob); } return(pktcnt);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -