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

📄 dev_sb1250_ethernet.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
	pkt->next = NULL;	pkt->length = pktsize;	if (s->sbe_rxqueue == NULL) {	    s->sbe_rxqueue = pkt;	    }	else {	    listptr = s->sbe_rxqueue;	    while (listptr->next) listptr = listptr->next;	    listptr->next = pkt;	    }	}    else {	sbeth_free_pkt(s,pkt);	}    sbeth_fillrxring(s,chan);}/*  *********************************************************************    *  SBETH_INITCHAN(s)    *      *  Initialize the Ethernet channel (program the CSRs to    *  get the channel set up)    *      *  Input parameters:     *  	   s - sbeth structure    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sbeth_initchan(sbeth_t *s){    sbeth_port_t port;    int idx;    uint64_t cfg,fifo,framecfg;    /*     * Bring the controller out of reset, and set the "must be one"     * bits.     */    SBETH_WRITECSR(s->sbe_macenable,0);    /*      * Set up some stuff in the control registers, but do not     * enable the channel     */    cfg = M_MAC_RETRY_EN |	M_MAC_TX_HOLD_SOP_EN | 	V_MAC_TX_PAUSE_CNT_16K |	V_MAC_SPEED_SEL_100MBPS |	M_MAC_AP_STAT_EN |	M_MAC_FAST_SYNC |	M_MAC_SS_EN |	0;    fifo = V_MAC_TX_WR_THRSH(4) |	/* Must be '4' or '8' */	   V_MAC_TX_RD_THRSH(8) |	   V_MAC_TX_RL_THRSH(4) |	   V_MAC_RX_PL_THRSH(4) |	   V_MAC_RX_RD_THRSH(4) |	/* Must be '4' */	   V_MAC_RX_PL_THRSH(4) |    	   V_MAC_RX_RL_THRSH(8) |	   0;    framecfg = V_MAC_MIN_FRAMESZ_DEFAULT |	V_MAC_MAX_FRAMESZ_DEFAULT |	V_MAC_BACKOFF_SEL(1);    /*     * Clear out the hash address map      */        port = SBETH_PORT(s->sbe_baseaddr + R_MAC_HASH_BASE);        for (idx = 0; idx < MAC_HASH_COUNT; idx++) {	SBETH_WRITECSR(port,0);	port += sizeof(uint64_t);	}    /*     * Clear out the exact-match table     */    port = SBETH_PORT(s->sbe_baseaddr + R_MAC_ADDR_BASE);    for (idx = 0; idx < MAC_ADDR_COUNT; idx++) {	SBETH_WRITECSR(port,0);	port += sizeof(uint64_t);	}    /*     * Clear out the DMA Channel mapping table registers     */    port = SBETH_PORT(s->sbe_baseaddr + R_MAC_CHUP0_BASE);    for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {	SBETH_WRITECSR(port,0);	port += sizeof(uint64_t);	}    port = SBETH_PORT(s->sbe_baseaddr + R_MAC_CHLO0_BASE);    for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {	SBETH_WRITECSR(port,0);	port += sizeof(uint64_t);	}    if (!s->sbe_zerormon) {	s->sbe_zerormon =1;	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_TX_BYTES),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_COLLISIONS),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_LATE_COL),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_EX_COL),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_FCS_ERROR),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_TX_ABORT),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_TX_BAD),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_TX_GOOD),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_TX_RUNT),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_TX_OVERSIZE),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_BYTES),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_MCAST),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_BCAST),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_BAD),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_GOOD),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_RUNT),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_OVERSIZE),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_FCS_ERROR),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_LENGTH_ERROR),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_CODE_ERROR),0);	SBETH_WRITECSR(SBETH_PORT(s->sbe_baseaddr+R_MAC_RMON_RX_ALIGN_ERROR),0);	}    /*     * Configure the receive filter for no packets     */    SBETH_WRITECSR(s->sbe_rxfilter,0);    SBETH_WRITECSR(s->sbe_imr,0);    SBETH_WRITECSR(s->sbe_framecfg,framecfg);    SBETH_WRITECSR(s->sbe_fifocfg,fifo);    SBETH_WRITECSR(s->sbe_maccfg,cfg);}/*  *********************************************************************    *  SBETH_INITCTX(s,mac)    *      *  Initialize an Ethernet context structure - this is called    *  once per MAC on the 1250.    *      *  Input parameters:     *  	   s - sbeth context structure    *  	   mac - number of this MAC (0,1,2)    *      ifctx - interface context (reference saved by driver)    *  	       *  Return value:    *  	   0    ********************************************************************* */static int sbeth_initctx(sbeth_t *s,unsigned long baseaddr,void *ifctx){    /*      * Start with all zeroes      */    memset(s,0,sizeof(sbeth_t));    /*      * Identify ourselves      */    s->sbe_baseaddr = baseaddr;    s->sbe_ifctx   = ifctx;    s->sbe_minrxring = 8;    /*     * Set default hardware address.  This is in case there is *no* environment.     */    s->sbe_hwaddr[0] = 0x02;    s->sbe_hwaddr[1] = 0x10;    s->sbe_hwaddr[2] = 0x18;    s->sbe_hwaddr[3] = (s->sbe_baseaddr >> 24) & 0xFF;    s->sbe_hwaddr[4] = (s->sbe_baseaddr >> 16) & 0xFF;    s->sbe_hwaddr[5] = (s->sbe_baseaddr >>  8) & 0xFF;    /*      * figure out the addresses of some ports      */    s->sbe_macenable = SBETH_PORT(s->sbe_baseaddr + R_MAC_ENABLE);    s->sbe_maccfg    = SBETH_PORT(s->sbe_baseaddr + R_MAC_CFG);    s->sbe_fifocfg   = SBETH_PORT(s->sbe_baseaddr + R_MAC_THRSH_CFG);    s->sbe_framecfg  = SBETH_PORT(s->sbe_baseaddr + R_MAC_FRAMECFG);    s->sbe_rxfilter  = SBETH_PORT(s->sbe_baseaddr + R_MAC_ADFILTER_CFG);    s->sbe_isr = SBETH_PORT(s->sbe_baseaddr + R_MAC_STATUS);    s->sbe_imr = SBETH_PORT(s->sbe_baseaddr + R_MAC_INT_MASK);    s->sbe_mdio = SBETH_PORT(s->sbe_baseaddr + R_MAC_MDIO);    /*     * Initialize the DMA channels.       */    sbdma_initctx(s,&(s->sbe_txdma[0]),0,DMA_TX,SBETH_MAX_TXDESCR,sbeth_tx_callback);    sbdma_initctx(s,&(s->sbe_rxdma[0]),0,DMA_RX,SBETH_MAX_RXDESCR,sbeth_rx_callback);#if (SBETH_DMA_CHANNELS == 2)    sbdma_initctx(s,&(s->sbe_txdma[1]),1,DMA_TX,SBETH_MAX_TXDESCR,sbeth_tx_callback);    sbdma_initctx(s,&(s->sbe_rxdma[1]),1,DMA_RX,SBETH_MAX_RXDESCR,sbeth_rx_callback);#endif    /*     * initialize free list     */    s->sbe_freelist = NULL;    s->sbe_rxqueue = NULL;    s->sbe_pktpool = KMALLOC(SBETH_PKTBUF_SIZE*SBETH_PKTPOOL_SIZE,			     SBDMA_CACHESIZE);    /*     * Set values for the PHY so that when we poll the phy status     * we'll notice that it has changed.     */    s->sbe_phy_oldbmsr   = 0xFFFFFFFF;    s->sbe_phy_oldbmcr   = 0xFFFFFFFF;    s->sbe_phy_oldanlpar = 0xFFFFFFFF;    s->sbe_phy_oldk1stsr = 0xFFFFFFFF;    /*     * initial state is OFF     */    s->sbe_state = sbeth_state_off;    return 0;}/*  *********************************************************************    *  SBETH_START(s)    *      *  Start packet processing on this MAC.    *      *  Input parameters:     *  	   s - sbeth structure    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sbeth_start(sbeth_t *s){    uint64_t ctl;	    sbdma_initchan(s,&(s->sbe_txdma[0]));    sbdma_initchan(s,&(s->sbe_rxdma[0]));#if (SBETH_DMA_CHANNELS == 2)    sbdma_initchan(s,&(s->sbe_txdma[1]));    sbdma_initchan(s,&(s->sbe_rxdma[1]));#endif    sbeth_initchan(s);    sbeth_setspeed(s,s->sbe_speed);    sbeth_set_duplex(s,s->sbe_duplex,s->sbe_fc);    SBETH_WRITECSR(s->sbe_rxfilter,0);    ctl = SBETH_READCSR(s->sbe_macenable);    ctl |= M_MAC_RXDMA_EN0 |   	   M_MAC_TXDMA_EN0 |#if (SBETH_DMA_CHANNELS == 2)	   M_MAC_TXDMA_EN1 |	   M_MAC_RXDMA_EN1 |#endif	   M_MAC_RX_ENABLE |	   M_MAC_TX_ENABLE |	0;    sbeth_initfreelist(s);    SBETH_WRITECSR(s->sbe_macenable,ctl);    sbeth_setaddr(s,s->sbe_hwaddr);#ifdef _SB1250_PASS1_WORKAROUNDS_    /* Must set the Ethernet address to zero in pass1 */    do {	sbeth_port_t port;	port = SBETH_PORT(s->sbe_baseaddr + R_MAC_ETHERNET_ADDR);	SBETH_WRITECSR(port,0);	} while (0);#endif    sbeth_fillrxring(s,0);    SBETH_WRITECSR(s->sbe_rxfilter,M_MAC_UCAST_EN | M_MAC_BCAST_EN |	V_MAC_IPHDR_OFFSET(15) |		   /* M_MAC_ALLPKT_EN |*/  /* uncomment for promisc mode */	0	);    s->sbe_state = sbeth_state_on;}/*  *********************************************************************    *  SBETH_STOP(s)    *      *  Stop packet processing on this MAC.    *      *  Input parameters:     *  	   s - sbeth structure    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sbeth_stop(sbeth_t *s){    uint64_t ctl;    int mac_mdio_genc;    SBETH_WRITECSR(s->sbe_rxfilter,0);    ctl = SBETH_READCSR(s->sbe_macenable);    ctl &= ~(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0 | M_MAC_RXDMA_EN1 | M_MAC_TXDMA_EN1 |	M_MAC_RX_ENABLE | M_MAC_TX_ENABLE);    SBETH_WRITECSR(s->sbe_macenable,ctl);    /*     * The genc bit on the MAC MDIO register needs to be preserved through reset.     * Read the MAC MDIO register and mask out genc bit.     */    mac_mdio_genc = SBETH_READCSR(s->sbe_mdio) & M_MAC_GENC;        ctl |= M_MAC_PORT_RESET;    SBETH_WRITECSR(s->sbe_macenable,ctl);    /* Write back value of genc bit */    SBETH_WRITECSR(s->sbe_mdio,mac_mdio_genc);    s->sbe_state = sbeth_state_off;    sbdma_reset(&(s->sbe_txdma[0]));    sbdma_reset(&(s->sbe_rxdma[0]));}/*  *********************************************************************    *  SBETH_SETADDR(s,addr)    *      *  Set the ethernet address for the specified MAC    *      *  Input parameters:     *  	   s - sbeth structure    *  	   addr - Ethernet address    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sbeth_setaddr(sbeth_t *s,uint8_t *addr){    sbeth_port_t port;    uint64_t regval = 0;    int idx;    /*     * Pack the bytes into the register, with the first byte transmitted     * in the lowest-order 8 bits of the register.     */    for (idx = 0; idx < 6; idx++) {	regval |= (((uint64_t) (*addr)) << (idx*8));	addr++;	}    /*     * Write to the port.     */    port = SBETH_PORT(s->sbe_baseaddr + R_MAC_ETHERNET_ADDR);    SBETH_WRITECSR(port,regval);    port = SBETH_PORT(s->sbe_baseaddr + R_MAC_ADDR_BASE);    SBETH_WRITECSR(port,regval);}/*  *********************************************************************    *  SBETH_SETSPEED(s,speed)    *      *  Configure LAN speed for the specified MAC    *      *  Input parameters:     *  	   s - sbeth structure    *  	   speed - speed to set MAC to (see sbeth_speed_t enum)    *  	       *  Return value:    *  	   1 if successful    *      0 indicates invalid parameters    ********************************************************************* */static int sbeth_setspeed(sbeth_t *s,sbeth_speed_t speed){    uint64_t cfg;    uint64_t framecfg;    /*     * Read current register values      */    cfg = SBETH_READCSR(s->sbe_maccfg);    framecfg = SBETH_READCSR(s->sbe_framecfg);    /*     * Mask out the stuff we want to change     */    cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL);    framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH |		  M_MAC_SLOT_SIZE);    /*     * Now add in the new bits     */    switch (speed) {	case sbeth_speed_10:	    framecfg |= V_MAC_IFG_RX_10 |		V_MAC_IFG_TX_10 |		K_MAC_IFG_THRSH_10 |		V_MAC_SLOT_SIZE_10;	    cfg |= V_MAC_SPEED_SEL_10MBPS;	    break;	case sbeth_speed_100:	    framecfg |= V_MAC_IFG_RX_100 |		V_MAC_IFG_TX_100 |		V_MAC_IFG_THRSH_100 |		V_MAC_SLOT_SIZE_100;	    cfg |= V_MAC_SPEED_SEL_100MBPS ;	    break;	case sbeth_speed_1000:

⌨️ 快捷键说明

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