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

📄 dev_sb1250_ethernet.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
		    uint16_t anar, k1ctl, bmcr;		    uint16_t led_sel1;		    /* Undo autodetect. */		    auto_det = (0x1E << 10);		    sbeth_mii_write(s, phy_addr, 0x1C, auto_det);		    auto_det = sbeth_mii_read(s, phy_addr, 0x1C);		    auto_det |= (0x1 << 15);		    sbeth_mii_write(s, phy_addr, 0x1C, auto_det);		    cfe_usleep(100);		    auto_det &= ~(0x1 << 0);		    sbeth_mii_write(s, phy_addr, 0x1C, auto_det);		    cfe_usleep(100);		    auto_det &= ~(0x1 << 15);		    sbeth_mii_write(s, phy_addr, 0x1C, auto_det);		    /* Force copper. */		    mode_ctrl = (0x1F << 10);		    sbeth_mii_write(s, phy_addr, 0x1C, mode_ctrl);		    mode_ctrl = sbeth_mii_read(s, phy_addr, 0x1C);		    mode_ctrl |= (1 << 15);		    sbeth_mii_write(s, phy_addr, 0x1C, mode_ctrl);		    cfe_usleep(100);		    mode_ctrl &= ~((0x3 << 1) | (0x1 << 0));		    sbeth_mii_write(s, phy_addr, 0x1C, mode_ctrl);		    cfe_usleep(100);		    mode_ctrl &= ~(1 << 15);		    sbeth_mii_write(s, phy_addr, 0x1C, mode_ctrl);		    cfe_usleep(100);		    /* Restart autonegotiation. */		    anar = sbeth_mii_read(s, phy_addr, MII_ANAR);		    anar |= (ANAR_TXFD | ANAR_TXHD | ANAR_10FD | ANAR_10HD);		    sbeth_mii_write(s, phy_addr, MII_ANAR, anar);		    k1ctl = sbeth_mii_read(s, phy_addr, MII_K1CTL);		    k1ctl |= (K1TCR_1000BT_FDX | K1TCR_1000BT_HDX);		    sbeth_mii_write(s, phy_addr, MII_K1CTL, k1ctl);		    bmcr = sbeth_mii_read(s, phy_addr, MII_BMCR);		    bmcr |= (BMCR_ANENABLE | BMCR_RESTARTAN);		    sbeth_mii_write(s, phy_addr, MII_BMCR, bmcr);		    /* Remap LINKSPD[1] selector to Link Quality. */		    led_sel1 = (0x0D << 10);		    sbeth_mii_write(s, phy_addr, 0x1C, led_sel1);		    led_sel1 = sbeth_mii_read(s, phy_addr, 0x1C);		    led_sel1 |= (1 << 15);		    sbeth_mii_write(s, phy_addr, 0x1C, mode_ctrl);		    cfe_usleep(100);		    led_sel1 &= ~(0xF << 0);		    led_sel1 |= 0x7;		    sbeth_mii_write(s, phy_addr, 0x1C, led_sel1);		    cfe_usleep(100);		    led_sel1 &= ~(1 << 15);		    sbeth_mii_write(s, phy_addr, 0x1C, led_sel1);		    }#endif		break;	    }	}    return 0;}/*  *********************************************************************    *  Declarations for CFE Device Driver Interface routines    ********************************************************************* */static int sb1250_ether_open(cfe_devctx_t *ctx);static int sb1250_ether_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);static int sb1250_ether_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);static int sb1250_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);static int sb1250_ether_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);static int sb1250_ether_close(cfe_devctx_t *ctx);static void sb1250_ether_poll(cfe_devctx_t *ctx,int64_t ticks);static void sb1250_ether_reset(void *softc);/*  *********************************************************************    *  CFE Device Driver dispatch structure    ********************************************************************* */const static cfe_devdisp_t sb1250_ether_dispatch = {    sb1250_ether_open,    sb1250_ether_read,    sb1250_ether_inpstat,    sb1250_ether_write,    sb1250_ether_ioctl,    sb1250_ether_close,    sb1250_ether_poll,    sb1250_ether_reset};/*  *********************************************************************    *  CFE Device Driver descriptor    ********************************************************************* */const cfe_driver_t sb1250_ether = {    "SiByte Ethernet",    "eth",    CFE_DEV_NETWORK,    &sb1250_ether_dispatch,    sb1250_ether_probe};/*  *********************************************************************    *  SB1250_ETHER_PROBE(drv,probe_a,probe_b,probe_ptr)    *      *  Probe and install an Ethernet device driver.  This routine    *  creates a context structure and attaches to the specified    *  MAC device.    *      *  Input parameters:     *  	   drv - driver descriptor    *  	   probe_a - base address of MAC to probe    *  	   probe_b - not used    *  	   probe_ptr - string pointer to hardware address for this    *  	               MAC, in the form xx:xx:xx:xx:xx:xx    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sb1250_ether_probe(cfe_driver_t *drv,			       unsigned long probe_a, unsigned long probe_b, 			       void *probe_ptr){    sbeth_t *softc;    char descr[100];    softc = (sbeth_t *) KMALLOC(sizeof(sbeth_t),0);    if (softc) {	sbeth_initctx(softc,probe_a,softc);	if (probe_ptr) {	    enet_parse_hwaddr((char *) probe_ptr,softc->sbe_hwaddr);	    }	xsprintf(descr,"%s at 0x%X (%a)",drv->drv_description,probe_a,		 softc->sbe_hwaddr);	sbeth_mii_findphy(softc);	sbeth_mii_setup(softc);	cfe_attach(drv,softc,NULL,descr);	sbeth_setaddr(softc,softc->sbe_hwaddr);	}}/*  *********************************************************************    *  SB1250_ETHER_READENV(ctx)    *      *  Read the environment variable that corresponds to this    *  interface to pick up the hardware address.  Note that the way    *  we do this is somewhat slimey.    *      *  Input parameters:     *  	   ctx - device context    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sb1250_ether_readenv(cfe_devctx_t *ctx){    sbeth_t *softc = ctx->dev_softc;    char envbuf[100];    char *hwaddr;    /*     * Gross - we should *not* be reaching into these data     * structures like this!     */    xsprintf(envbuf,"%s_HWADDR",cfe_device_name(ctx));    strupr(envbuf);        hwaddr = env_getenv(envbuf);    if (hwaddr) {	enet_parse_hwaddr(hwaddr,softc->sbe_hwaddr);	}   }/*  *********************************************************************    *  SBETH_MII_DUMP(s)    *      *  Dump out the MII registers    *      *  Input parameters:     *  	   s - sbeth structure    *  	       *  Return value:    *  	   nothing    ********************************************************************* */#if 0static void sbeth_mii_dump(sbeth_t *s){    int idx;    printf("---Phy registers---\n");        for (idx = 0; idx < 31; idx++) {	printf("Reg %2d = %04X\n",	       idx,	       sbeth_mii_read(s,1,idx));	}    printf ("\n\n");}#endif/*  *********************************************************************    *  SB1250_ETHER_OPEN(ctx)    *      *  Open the Ethernet device.  The MAC is reset, initialized, and    *  prepared to receive and send packets.    *      *  Input parameters:     *  	   ctx - device context (includes ptr to our softc)    *  	       *  Return value:    *  	   status, 0 = ok    ********************************************************************* */static int sb1250_ether_open(cfe_devctx_t *ctx){    sbeth_t *softc = ctx->dev_softc;    softc->sbe_devctx = ctx;    sbeth_stop(softc);    /*     * Note: The Phy can take several seconds to become ready!     * This gross code pounds on the phy until  it says it is     * ready, but it still takes 2 more seconds after this     * before the link is usable.  We're better off letting the     * dhcp/arp retries do the right thing here.     */#if 0    do {	int64_t timer;	TIMER_SET(timer,2*CFE_HZ);	while (!TIMER_EXPIRED(timer)) {	    sbeth_mii_poll(softc,FALSE);	    if (softc->sbe_linkstat != ETHER_SPEED_UNKNOWN) break;	    }	} while (0);#else    sbeth_mii_poll(softc,TRUE);#endif    sb1250_ether_readenv(ctx);    TIMER_SET(softc->sbe_linkstat_timer,SBETH_MIIPOLL_TIMER);    softc->sbe_autospeed = TRUE;    softc->fifo_mode = FALSE;    /* Make sure we see a change with autospeed set */    softc->sbe_phy_oldbmsr &= ~BMSR_ANCOMPLETE;    sbeth_start(softc);    return 0;}/*  *********************************************************************    *  SB1250_ETHER_READ(ctx,buffer)    *      *  Read a packet from the Ethernet device.  If no packets are    *  available, the read will succeed but return 0 bytes.    *      *  Input parameters:     *  	   ctx - device context (includes ptr to our softc)    *      buffer - pointer to buffer descriptor.      *  	       *  Return value:    *  	   status, 0 = ok    ********************************************************************* */static int sb1250_ether_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer){    sbeth_t *softc = ctx->dev_softc;    sbeth_pkt_t *pkt;    int blen;    if (softc->sbe_state != sbeth_state_on) return -1;    sbeth_isr(softc);    if (softc->sbe_rxqueue == NULL) {	buffer->buf_retlen = 0;	return 0;	}    pkt = softc->sbe_rxqueue;    softc->sbe_rxqueue = pkt->next;    pkt->next = NULL;    blen = buffer->buf_length;    if (blen > pkt->length) blen = pkt->length;    memcpy(buffer->buf_ptr,pkt->buffer,blen);    buffer->buf_retlen = blen;    sbeth_free_pkt(softc,pkt);    sbeth_fillrxring(softc,0);    sbeth_isr(softc);    return 0;}/*  *********************************************************************    *  SB1250_ETHER_INPSTAT(ctx,inpstat)    *      *  Check for received packets on the Ethernet device    *      *  Input parameters:     *  	   ctx - device context (includes ptr to our softc)    *      inpstat - pointer to input status structure    *  	       *  Return value:    *  	   status, 0 = ok    ********************************************************************* */static int sb1250_ether_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat){    sbeth_t *softc = ctx->dev_softc;    if (softc->sbe_state != sbeth_state_on) return -1;    sbeth_isr(softc);    inpstat->inp_status = (softc->sbe_rxqueue == NULL) ? 0 : 1;    return 0;}/*  *********************************************************************    *  SB1250_ETHER_WRITE(ctx,buffer)    *      *  Write a packet to the Ethernet device.    *      *  Input parameters:     *  	   ctx - device context (includes ptr to our softc)    *      buffer - pointer to buffer descriptor.      *  	       *  Return value:    *  	   status, 0 = ok    ********************************************************************* */static int sb1250_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer){    sbeth_t *softc = ctx->dev_softc;    sbeth_pkt_t *pkt;    int blen;    if (softc->sbe_state != sbeth_state_on) return -1;    if (!softc->fifo_mode) {	/* Only do a speed check if not packet fifo mode*/	if (softc->sbe_linkstat == ETHER_SPEED_UNKNOWN) {	    sbeth_mii_poll(softc,1);	    if (softc->sbe_linkstat == ETHER_SPEED_UNKNOWN) return -1;	    }	}    pkt = sbeth_alloc_pkt(softc);    if (!pkt) return CFE_ERR_NOMEM;    blen = buffer->buf_length;    if (blen > pkt->length) blen = pkt->length;    memcpy(pkt->buffer,buffer->buf_ptr,blen);    pkt->length = blen;    sbeth_isr(softc);    if (sbeth_transmit(softc,0,pkt->buffer,pkt->length,pkt) != 1) {	sbeth_free_pkt(softc,pkt);	return CFE_ERR_IOERR;	}    sbeth_isr(softc);    buffer->buf_retlen = blen;    return 0;}/*  *********************************************************************    *  SB1250_ETHER_IOCTL_LOOPBACK(s,loopback)    *      *  Set loopback modes    *      *  Input parameters:     *  	   s - sbeth structure    *  	   loopback - loopback modes    *  	       *  Return value:    *  	   0 if ok, else error    ********************************************************************* */static int sb1250_ether_ioctl_loopback(sbeth_t *s,int loopback){    unsigned int miireg;    uint64_t regval;    switch (loopback) {	case ETHER_LOOPBACK_OFF:	    miireg = sbeth_mii_read(s,s->sbe_phyaddr,MII_BMCR);	    if (miireg & BMCR_LOOPBACK) {		miireg &= ~BMCR_LOOPBACK;		miireg |= BMCR_RESTARTAN;		sbeth_mii_write(s,s->sbe_phyaddr,MII_BMCR,miireg);		}	    regval = SBETH_READCSR(s->sbe_maccfg);	    if (regval & M_MAC_LOOPBACK_SEL) {		regval &= ~M_MAC_LOOPBACK_SEL;		SBETH_WRITECSR(s->sbe_maccfg,regval);		}	    break;	case ETHER_LOOPBACK_INT:	    regval = SBETH_READCSR(s->sbe_maccfg);	    regval |= M_MAC_LOOPBACK_SEL;	    SBETH_WRITECSR(s->sbe_maccfg,regval);	    break;	case ETHER_LOOPBACK_EXT:	    regval = SBETH_READCSR(s->sbe_maccfg);	    if (regval & M_MAC_LOOPBACK_SEL) {		regval &= ~M_MAC_LOOPBACK_SEL;		SBETH_WRITECSR(s->sbe_maccfg,regval);		}	    miireg = sbeth_mii_read(s,s->sbe_phyaddr,MII_BMCR);	    miireg |= BMCR_LOOPBACK;	    sbeth_mii_write(s,s->sbe_phyaddr,MII_BMCR,miireg);	    break;	}    s->sbe_loopback = loopback;    return 0;}/*  *********************************************************************    *  SB1250_ETHER_IOCTL_SPEED(s,speed)    *      *  Set speed forcibly via the IOCTL command    *      *  Input parameters:     *  	   s - sbeth structure    *  	   speed - speed IOCTL setting    *  	       *  Return value:    *  	   0 if ok, else error    ********************************************************************* */static int sb1250_ether_ioctl_speed(sbeth_t *s,int speed)

⌨️ 快捷键说明

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