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

📄 etherdev.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* etherdev.c:    This file, along with common/ethernet.c supports the ethernet interface.    It is the lowest layer of code supporting the monitor's IP, ICMP & UDP    services.  This file is specific to one particular ethernet device    and provides the hooks needed by common/ethernet.c to initialize,    and transmit/receive packets in a polled environment.    The common vs device-specific code is generally noted by a naming     convention where ...Ethernet... is common and ...Etherdev... is device-    specific.    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 "stddefs.h"#include "genlib.h"#include "bcsr.h"#include "arch_ppc.h"#include "mpc860.h"#include "masks860.h"extern  char *processARP();extern  EPPC *IMMRBase;#define RTS1_PB19   1#define RTS1_PC15   0int EtherRLCnt, EtherDEFCnt, EtherLCCnt, EtherDRVRETRYCnt;int eninit();static uchar xbuf[XBUFCNT][1600];   /* Transmit & receive buffers pointed */static uchar rbuf[RBUFCNT][1600];   /* to by the buffer descriptors. */struct  snoopinfo snoopInfo;struct  enet_bd *tbptr, *rbptr, *prevtbptr;/* 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);    if (snoopInfo.on) {        char smac[32];        EtherToString(snoopInfo.mac,smac);        printf("Snoop MAC:               %s\n",smac);    }}/* EtherdevStartup():    Called by EthernetStartup().  Initialize all device-specific     counters, reset and initialized the ethernet device.*/intEtherdevStartup(int verbose){    EtherRLCnt = 0;    EtherLCCnt = 0;    EtherDEFCnt = 0;    EtherDRVRETRYCnt = 0;    snoopInfo.on = 0;    /* Put ethernet controller in reset: */    enreset();    /* Initialize controller: */    eninit();    return(0);}/* DisableEtherdev():    Called by DisableEthernet() to do the device-specific portion of     the turn-down.*/voidDisableEtherdev(){    ulong   bcsr;    bcsr = *(ulong *)BCSR1_BASE;    bcsr |= ETHERDISABLE;               /* Disable ethernet */    *(ulong *)BCSR1_BASE = bcsr;    enreset();#if RTS1_PB19    IMMRBase->pip_pbpar &= ~(0x1000);    /* set port B -> RTS1 = *TENA */#elif RTS1_PC15    IMMRBase->pio_pcpar &= ~(0x0001);    /* set port C -> RTS1 = *TENA */#else#error#endif    IMMRBase->cpmi_cimr &= ~CIMR_SCC1;    EtherIsActive = 0;    IPMonCmdActive = 0;}voidenreset(){    int timeout;    /* Issue CPM Command to init RX/TX params for SCC1: */    /* (wait for completion) */    IMMRBase->cp_cr = 0x0001;    timeout = 500000;    while(IMMRBase->cp_cr & 0x0001) {        timeout--;        if (timeout <= 0) {            printf("enreset() timeout\n");            break;        }    }}/* eninit():    These steps are basically taken from the MPC860 User's Manual (rev1)    section 28.22 "SCC Ethernet Programming Example".*/inteninit(){    ushort  mac;    uchar   *cp;    ulong   bcsr;    int     i, timeout;    struct  enet_bd *tbd, *rbd;    /* Set IMMR pointing to the MPC860's internal register memory map. */    IMMRBase = (EPPC *)(ppcMfimmr() & 0xFFFF0000);    /* Configure ports for ethernet... */    IMMRBase->si_sicr  &= 0xFFFFFF00;   /* Clear SCC1 info */    IMMRBase->pio_papar |=  0x0303;     /* RXD1,TXD1, CLK1, CLK2 */    IMMRBase->pio_padir &= ~0x0303;     /* RXD1,TXD1, CLK1, CLK2*/    bcsr = *(ulong *)BCSR4_BASE;    bcsr &= ~ETHLOOP;                   /* Disable loopback */    bcsr |= (TFPLDL | TPSQEL);          /* Disable squelch & full duplex */    *(ulong *)BCSR4_BASE = bcsr;    bcsr = *(ulong *)BCSR1_BASE;    bcsr &= ~ETHERDISABLE;              /* Enable ethernet */    *(ulong *)BCSR1_BASE = bcsr;    IMMRBase->si_sicr  |= 0x0000002c;   /* NMSI, recv = CLK2, xmit = CLK1 */#if RTS1_PB19    IMMRBase->pip_pbpar |=  0x1000;     /* RTS1 */    IMMRBase->pip_pbdir |=  0x1000;     /* RTS1 */    IMMRBase->pip_pbdat &= ~0x1000;     /* Data=0 for when RTS1 is disabled */#else    IMMRBase->pio_pcpar |=  0x0001;     /* RTS1 */    IMMRBase->pio_pcdir &=  ~0x0001;    /* RTS1 */    IMMRBase->pio_pcdat &= ~0x0001;     /* Data=0 for when RTS1 is disabled */#endif    IMMRBase->pio_pcpar &= ~0x0030;         /* CD1, CTS1 */    IMMRBase->pio_pcdir &= ~0x0030;         /* CD1, CTS1 */    IMMRBase->pio_pcso  |=  0x0030;         /* CD1, CTS1 */    /* Configure General SCC Mode Register for ethernet: */    IMMRBase->scc_regs[SCC1_REG].scc_gsmr_h = 0;    IMMRBase->scc_regs[SCC1_REG].scc_gsmr_l = 0x1088000c;    /* Initialize Buffer Descriptors (located in DPRAM): */    /* Refer to mpc860.h for the layout of DPRAM as used by MicroMonitor. */    tbd = tbptr = IMMRBase->qcp_or_ud.umd.e_bdtbl;    rbd = rbptr = &IMMRBase->qcp_or_ud.umd.e_bdtbl[XBUFCNT];    /* Set parameter ram to point to buffer descriptors in DPRAM: */    /* Note that this will generate a compiler warning because we are */    /* casting a pointer to a short. This can be ignored because these */    /* two entries are offsets relative to the base of the IMMR, not the */    /* actual address. */    IMMRBase->PRAM[PAGE1].enet_scc.rbase = (ushort)rbd;    IMMRBase->PRAM[PAGE1].enet_scc.tbase = (ushort)tbd;    for (i=0;i<XBUFCNT;i++,tbd++) {        tbd->status = 0;        tbd->length = 0;        tbd->baddr = xbuf[i];        if (i == (XBUFCNT-1))            tbd->status |= BD_WRAP; /* Set WRAP bit on final BD */    }    for(i=0;i<RBUFCNT;i++,rbd++) {        rbd->status = BD_READY;        rbd->length = 0;        rbd->baddr = rbuf[i];        if (i == (RBUFCNT-1))            rbd->status |= BD_WRAP; /* Set WRAP bit on final BD */    }    /* Issue CPM Command to init RX/TX params for SCC1: */    /* (wait for completion) */    IMMRBase->cp_cr = 0x0001;    timeout = 500000;    while(IMMRBase->cp_cr & 0x0001) {        timeout--;        if (timeout <= 0)            break;    }    /* Set RFCR,TFCR -- Rx,Tx Function Code */    /* Normal Operation and Motorola byte ordering */    IMMRBase->PRAM[PAGE1].enet_scc.rfcr = 0x10;      IMMRBase->PRAM[PAGE1].enet_scc.tfcr = 0x10;      /* MRBLR = MAX buffer length (first value larger than 1518 evenly */    /* divisible by 4). */    IMMRBase->PRAM[PAGE1].enet_scc.mrblr = 1520;        /* Initialize based on example in mpc860 manual. */    IMMRBase->PRAM[PAGE1].enet_scc.c_pres = 0xffffffff;    IMMRBase->PRAM[PAGE1].enet_scc.c_mask = 0xdebb20e3;    IMMRBase->PRAM[PAGE1].enet_scc.crcec = 0;    IMMRBase->PRAM[PAGE1].enet_scc.alec = 0;    IMMRBase->PRAM[PAGE1].enet_scc.disfc = 0;    IMMRBase->PRAM[PAGE1].enet_scc.pads = 0x8888;    IMMRBase->PRAM[PAGE1].enet_scc.ret_lim = 15;    IMMRBase->PRAM[PAGE1].enet_scc.mflr = 1518;    IMMRBase->PRAM[PAGE1].enet_scc.minflr = 64;    IMMRBase->PRAM[PAGE1].enet_scc.maxd1 = 1520;    IMMRBase->PRAM[PAGE1].enet_scc.maxd2 = 1520;    IMMRBase->PRAM[PAGE1].enet_scc.gaddr1 = 0;    IMMRBase->PRAM[PAGE1].enet_scc.gaddr2 = 0;    IMMRBase->PRAM[PAGE1].enet_scc.gaddr3 = 0;    IMMRBase->PRAM[PAGE1].enet_scc.gaddr4 = 0;    /* Load the PADDR registers with this board's ethernet address. */    cp = (uchar *)&mac;    cp[0] = BinEnetAddr[5];    cp[1] = BinEnetAddr[4];    IMMRBase->PRAM[PAGE1].enet_scc.paddr_h = mac;    cp[0] = BinEnetAddr[3];    cp[1] = BinEnetAddr[2];    IMMRBase->PRAM[PAGE1].enet_scc.paddr_m = mac;    cp[0] = BinEnetAddr[1];    cp[1] = BinEnetAddr[0];    IMMRBase->PRAM[PAGE1].enet_scc.paddr_l = mac;    IMMRBase->PRAM[PAGE1].enet_scc.p_per = 0;    IMMRBase->PRAM[PAGE1].enet_scc.iaddr1 = 0;    IMMRBase->PRAM[PAGE1].enet_scc.iaddr2 = 0;    IMMRBase->PRAM[PAGE1].enet_scc.iaddr3 = 0;    IMMRBase->PRAM[PAGE1].enet_scc.iaddr4 = 0;    IMMRBase->PRAM[PAGE1].enet_scc.taddr_h = 0;    IMMRBase->PRAM[PAGE1].enet_scc.taddr_m = 0;    IMMRBase->PRAM[PAGE1].enet_scc.taddr_l = 0;    /* Clear any events: */    IMMRBase->scc_regs[SCC1_REG].scc_scce = 0xffff;    /* Enable RXF events: */    IMMRBase->scc_regs[SCC1_REG].scc_sccm = ENET_SCCM_RXF;    IMMRBase->cpmi_cimr |= CIPR_SCC1;    IMMRBase->scc_regs[SCC1_REG].scc_dsr = 0xd555;    IMMRBase->scc_regs[SCC1_REG].scc_psmr = 0x080a;

⌨️ 快捷键说明

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