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

📄 etherdev.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This source code has been made available to you by IBM on an AS-IS * basis.  Anyone receiving this source is licensed under IBM * copyrights to use it in any way he or she deems fit, including * copying it, modifying it, compiling it, and redistributing it either * with or without modifications.  No license under IBM patents or * patent applications is to be implied by the copyright license. * * Any user of this software should understand that IBM cannot provide * technical support for this software and will not be responsible for * any consequences resulting from the use of this software. * * Any person who transfers this source code or any derivative work * must include the IBM copyright notice, this paragraph, and the * preceding two paragraphs in the transferred software. * * COPYRIGHT   I B M   CORPORATION 1995 * LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M * *  File Name:  etherdev.c (originally enetemac.c) * *  Function:   Device driver for the ethernet EMAC3 macro on the 405GP. * *  Author:     Mark Wisner * *  Change Activity- * *  Date        Description of Change                                      BY *  ---------   --------------------- *  05-May-99   Created                                                    MKW *  27-Jun-99   Clean up                                                   JWB *  16-Jul-99   Added MAL error recovery and better IP packet              MKW                handling. *  29-Jul-99   Added Full duplex support                                  MKW *  06-Aug-99   Changed names for Mal CR reg                               MKW *  23-Aug-99   Turned off SYE when running at 10Mbs                       MKW *  24-Aug-99   Marked descriptor empty after call_xlc                     MKW *  07-Sep-99   Set MAL RX buffer size reg to ENET_MAX_MTU_ALIGNED / 16    MCG *              to avoid chaining maximum sized packets. Push starting *              RX descriptor address up to the next cache line boundary. *  19-Apr-00   Integrated enetemac.c (now etherdev.c) into MicroMonitor   ELS *              platform. Changed some register names to match the names *              used in the manual. *  26-Sep-00   Added PHY interface, auto-negotiation, and selftest.       ELS *              Also fixed a bug where the descriptor tables must start *              on an 8-byte boundary. * * 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"#include "genlib.h"#include "stddefs.h"#include "enetemac.h"#include "cpuio.h"#include "phy.h"#include "ppcmal.h"#include "ppcuic.h"#include "ether.h"#if INCLUDE_ETHERNET/* defines for EtherSpeed status */#define Is10BaseT       0x1#define Is100BaseT      0x2#define IsFullDuplex    0x4#define AutoNeg         0x8#define AutoNegFailed   0x10/* Defines for number of buffers.  */#define NUM_TX_BUFF 1#define NUM_RX_BUFF 10/* define the number of channels implemented */#define EMAC_RXCHL      1#define EMAC_TXCHL      1/* definitions used to check link status */#define LINK_NULL       0#define LINK_UP         1#define LINK_DOWN       2/* Global variables. TX and RX descriptors and buffers.  */static mal_desc_t *tx;static mal_desc_t *rx;static mal_desc_t tx_desctbl[NUM_TX_BUFF+2];static mal_desc_t rx_desctbl[NUM_RX_BUFF+2];static struct memblock *tx_buff;static struct memblock *rx_buff;static ulong xmit_buffer[(400*NUM_TX_BUFF)];static ulong recv_buffer[(400*NUM_RX_BUFF)];static int rx_slot;                 /* MAL Receive Slot */static int rx_ready[NUM_RX_BUFF];   /* Receive Ready Queue */static int tx_slot;                 /* MAL Transmit Slot */static int tx_run[NUM_TX_BUFF];     /* Transmit Running Queue */static ulong EtherSpeed;/* * enreset(): *  Reset the ethernet-related hardware. */voidenreset(void){    volatile int delay;    /* PHY reset */    phy_reset();    /* MAL reset */    ppcMtmalcr(MAL_CR_MMSR);    /* Disable MAL interrupts: */    ppcMtmalier(0);    /* EMAC reset */    *(ulong *)(EM0MR0) = EM0MR0_SRST;    for (delay=0;delay<1000;delay++);    *(ulong *)(EM0MR0) = *(ulong *)(EM0MR0) & ~EM0MR0_SRST;    /* Disable EMAC interrupts: */    *(ulong *)(EMAC_IER) = 0;}/* * eninit() - Initialize the Mal and the Emac macros. */inteninit(void){    int     i;    char    *p;    ulong   reg, emac_ier;    unsigned mode_reg;    rx_slot = 0;                /* MAL Receive Slot */    tx_slot = 0;                /* MAL Transmit Slot */    /* The descriptor tables must be aligned on an 8-byte boundary     * (least significant 3 bits must be 0).     */    tx = (mal_desc_t *)((ulong)(&tx_desctbl[1]) & 0xfffffff8);    rx = (mal_desc_t *)((ulong)(&rx_desctbl[1]) & 0xfffffff8);    /* Set MAL configuration reg:     *  - Burst transactions enabled;     *  - Lock OPB during xfers to/from the EMAC;     *  - Handle errors in locked mode;     */    ppcMtmalcr(MAL_CR_PLBB|MAL_CR_OPBBL|MAL_CR_LEA|MAL_CR_PLBLT_DEFAULT);    /* Set up the TX and RX descriptors */    tx_buff = (struct memblock *)xmit_buffer;    rx_buff = (struct memblock *)recv_buffer;    for (i=0;i<NUM_TX_BUFF;i++) {        tx[i].ctrl = 0;        tx[i].data_len = 0;        tx[i].data_ptr = (char *) &tx_buff[i];        if ((NUM_TX_BUFF - 1) == i)            tx[i].ctrl |= MAL_TX_CTRL_WRAP;        tx_run[i] = -1;    }    for (i=0;i<NUM_RX_BUFF;i++) {        rx[i].ctrl = 0;        rx[i].data_len = 0;        rx[i].data_ptr = (char *) &rx_buff[i];        if ((NUM_RX_BUFF - 1) == i)            rx[i].ctrl |= MAL_RX_CTRL_WRAP;        rx[i].ctrl |=   MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;        rx_ready[i] = -1;    }    /* Write the ethernet address (6 bytes) into the EMAC Individual      * Address High and Low registers:     */    reg = 0;    reg |= BinEnetAddr[0];    reg = reg << 8;    reg |= BinEnetAddr[1];    *(ulong *)(EM0IAH) = reg;    reg = 0;    reg |= BinEnetAddr[2];    reg = reg << 8;    reg |= BinEnetAddr[3];    reg = reg << 8;    reg |= BinEnetAddr[4];    reg = reg << 8;    reg |= BinEnetAddr[5];    *(ulong *)(EM0IAL) = reg;    /* Setup MAL tx & rx channel pointers */    ppcMtmaltxctp0r((int)tx);    ppcMtmalrxctp0r((int)rx);    /* Reset transmit and receive channels */    ppcMtmalrxcarr(0x80000000);     /* 2 channels */    ppcMtmaltxcarr(0x80000000);     /* 2 channels */    /* Enable MAL transmit and receive channels */    ppcMtmaltxcasr(0x80000000);     /* 1 channel */    ppcMtmalrxcasr(0x80000000);     /* 1 channel */    /* Set RX buffer size */    ppcMtmalrcbs0(ENET_MAX_MTU_ALIGNED / 16);    /* Set transmit enable & receive enable */    *(ulong *)(EM0MR0) = (EM0MR0_TXE | EM0MR0_RXE);    /* Set receive fifo to 4k and tx fifo to 2k */    mode_reg = EM0MR1_RFS_4K | EM0MR1_TX_FIFO_2K;    /* Set speed based on content of ETHERSPEED shell variable... */    if ((p = getenv("ETHERSPEED")) == 0) {        EtherSpeed = Is10BaseT;        phy_write(PHY_BMCR,PHY_BMCR_10MB);    } else {        if(!strcmp(p, "10")) {            EtherSpeed = Is10BaseT;            phy_write(PHY_BMCR,PHY_BMCR_10MB);        } else if(!strcmp(p, "100")) {            EtherSpeed = Is100BaseT;            phy_write(PHY_BMCR,PHY_BMCR_100MB);        } else if(!strcmp(p, "10FULL")) {            EtherSpeed = Is10BaseT | IsFullDuplex;            phy_write(PHY_BMCR,PHY_BMCR_10MB | PHY_BMCR_FDPLX);        } else if(!strcmp(p, "100FULL")) {            EtherSpeed = Is100BaseT | IsFullDuplex;            phy_write(PHY_BMCR,PHY_BMCR_100MB | PHY_BMCR_FDPLX);        } else if (!strcmp(p, "AUTO")) {            int is100BaseT, isFullDuplex;            EtherSpeed = AutoNeg;            isFullDuplex = is100BaseT = 1;            if (phy_autoneg(0, &is100BaseT, &isFullDuplex)) {                printf("Ethernet auto negotiate failed, ");                printf("defaulting to 10BaseT half duplex.\n");                EtherSpeed = AutoNegFailed | Is10BaseT;                phy_write(PHY_BMCR,PHY_BMCR_10MB);            } else {                if(isFullDuplex && is100BaseT) {                    EtherSpeed = Is100BaseT | IsFullDuplex;                }                else if(!isFullDuplex && is100BaseT) {                    EtherSpeed = Is100BaseT;                }                else if(!isFullDuplex && !is100BaseT) {                    EtherSpeed = Is10BaseT;                }                else if(isFullDuplex && is100BaseT) {                    EtherSpeed = Is10BaseT | IsFullDuplex;                }            }        } else {            printf("ETHERSPEED not valid, defaulting to 10BaseT half duplex\n");            EtherSpeed |= Is10BaseT;            phy_write(PHY_BMCR,PHY_BMCR_10MB);        }    }    if (EtherSpeed & Is100BaseT)        mode_reg |= EM0MR1_MF_100MBPS;    else        mode_reg &= ~EM0MR1_MF_SPEED;   /* 10 MBPS */    if(EtherSpeed & IsFullDuplex)        mode_reg |= EM0MR1_FDE;    /* Load EM0MR1: */    *(ulong *)(EM0MR1) = mode_reg;    /* Configure receive mode:     *  - Accept broadcast addresses;     *  - Accept individual address;     *  - Allow runt packets (< 64 bytes);     *  - Strip Frame Check Sequence and padding;     */    *(ulong *)(EM0RMR) =         (EMAC_RMR_BAE|EMAC_RMR_IAE|EMAC_RMR_ARRP|EMAC_RMR_SFCS|EMAC_RMR_SP);    /* we probably need to set the tx mode1 reg? maybe at tx time */    /* set transmit request threshold register */    *(ulong *)(EMAC_TRTR) = 0x18000000; /* 256 byte threshold */    /* set recieve  low/high water mark register */    *(ulong *)(EMAC_RX_HI_LO_WMARK) = 0x0f002000;

⌨️ 快捷键说明

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