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

📄 if_xdssonic.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 4 页
字号:
	    /* update statistics for this packet */	    sn->sn_sum.ss_tpacks++;	    sn->sn_if.if_opackets++;	    if (status & TSR_DEF) {		sn->sn_sum.ss_tdef++;	    }	    if (status & TSR_OWC) {		sn->sn_sum.ss_tlcol++;		sn->sn_if.if_oerrors++;		log (LOG_NOTICE, "%s%d: late collision (noisy network?)\n", 		     sn->sn_if.if_name, sn->sn_if.if_unit);	    }	    if (status & (TSR_NCRS|TSR_CRSL)) {		sn->sn_sum.ss_tlcar++;		sn->sn_if.if_oerrors++;		log (LOG_NOTICE, "%s%d: no carrier (check cables?)\n", 		     sn->sn_if.if_name, sn->sn_if.if_unit);	    }	    if (ncol = (status & TSR_NC) >> TSR_NCSHFT) {		sn->sn_if.if_collisions += ncol;		if (ncol == 1)		  sn->sn_sum.ss_tone++;		else		  sn->sn_sum.ss_tmore++;	    }	}	else {	    /* tx failed: CTDA still points at failing packet */	    sn->sn_if.if_oerrors++;	    if (status & (TSR_EXD|TSR_EXC)) {		sn->sn_sum.ss_cerr++;		log (LOG_NOTICE, "%s%d: excessive %s (network jammed?)\n", 		     sn->sn_if.if_name, sn->sn_if.if_unit,		     (status & TSR_EXD) ? "deferrals" : "collisions");		status &= ~TSR_BCM; /* ignore bcm error */	    }	    if (status & TSR_FU) {		sn->sn_sum.ss_tuflo++;		log (LOG_INFO, "%s%d: tx fifo underflow\n",		     sn->sn_if.if_name, sn->sn_if.if_unit);		if (sn->sn_if.if_flags & IFF_DEBUG)		  sntxdump (txp);	    }	    if (status & TSR_BCM) {		int fr, frag_total;		sn->sn_sum.ss_tbuff++;		for (fr = 0, frag_total = 0; fr < txp->frag_count; fr++)		  frag_total += txp->frags[fr].frag_size;		if ((sn->sn_if.if_flags & IFF_DEBUG) ||		    frag_total != txp->pkt_size) {		    log (LOG_WARNING, "%s%d: tx byte count mismatch, psz=%d, %d in %d frags\n",			     sn->sn_if.if_name, sn->sn_if.if_unit,			     txp->pkt_size, frag_total, txp->frag_count);		    sntxdump (txp);		}		/* pointless attempt to fix error! */		txp->pkt_size = frag_total;	    }	    if (sn->sn_retries++ >= SNRETRIES) {		/* give up on this packet */		log (LOG_INFO, "%s%d: tx retry count exceeded\n",		     sn->sn_if.if_name, sn->sn_if.if_unit);		sntxdone (sn, mtd);		/* manually advance to next packet:		 * strictly we only need to set CTDA here, but we are		 * paranoid and reset it for all errors, below. */	    }	    if (mtdhead) {		/* restart transmission */		register volatile struct sn_reg *csr = sn->sn_csr;		csr->s_ctda = LOWER(mtdhead->mtd_txp); wbflush();		csr->s_cr = CR_TXP; wbflush();		break;	    }	}    }    /* dequeue some new packets, if possible */    if (!(sn->sn_if.if_flags & IFF_OACTIVE))      snifstart (&sn->sn_if);}static voidsntxdone (struct sn_softc *sn, struct mtd *mtd){    sn->sn_if.if_flags &= ~IFF_OACTIVE;    sn->sn_retries = 0;    if (mtd->mtd_mbuf) {	m_freem (mtd->mtd_mbuf);	mtd->mtd_mbuf = 0;    }    mtdhead = mtd->mtd_link;    if (mtdhead == mtdnext)      mtdhead = 0;    mtd_free (mtd);}static voidsntxdump (volatile struct TXpkt *txp){    int fr;    printf ("     frags:");    for (fr = 0; fr < MASK(txp->frag_count); fr++)      printf (" %d", MASK(txp->frags[fr].frag_size));    printf ("\n");}/* * Receive interrupt routine */static voidsnrxint (struct sn_softc *sn){    volatile struct sn_reg *csr = sn->sn_csr;    volatile struct RXpkt *rxp;    rxp = &rda[sn->sn_rxmark];    while (MASK(rxp->in_use) == 0) {	if ((MASK(rxp->status) & RCR_LPKT) == 0)	  log (LOG_WARNING, "%s%d: more than one packet in RBA\n",	       sn->sn_if.if_name, sn->sn_if.if_unit);	#ifdef DEBUG	if (SEQNO_PKT (MASK(rxp->seqno)) != 0)	  log (LOG_WARNING, "%s%d: bad psn sequence no. %d\n",	       sn->sn_if.if_name, sn->sn_if.if_unit, SEQNO_PKT (MASK(rxp->seqno)));#endif		if (MASK(rxp->status) & RCR_PRX) {	    if (snread (sn, rxp)) {		sn->sn_if.if_ipackets++;		sn->sn_sum.ss_rpacks++;	    }	} else {	    log (LOG_INFO, "%s%d: rx packet error 0x%x\n", MASK(rxp->status));	    sn->sn_if.if_ierrors++;	}	/* give receive buffer area back to chip 	 * XXX what buffer did the sonic use for this descriptor	 * answer look at the rba sequence number !!	 */	{	    int orra = SEQNO_RBA (MASK(rxp->seqno)) & RRAMASK;	    volatile struct RXrsrc *orr = &rra[orra];	    #ifdef DEBUG	    if (MASK(rxp->pkt_ptrhi) != MASK(orr->buff_ptrhi) ||		MASK(rxp->pkt_ptrlo) != MASK(orr->buff_ptrlo) ||		MASK(orr->buff_wclo) == 0)	      log (LOG_WARNING, "%s%d: bad rx pkt pointers\n",		   sn->sn_if.if_name, sn->sn_if.if_unit);#endif	    	    /* orra is now empty of packets and can be freed	     * (if snread didnt copy it out, but instead passed	     * pointers around then we would have to wait for	     * higher levels to free it up)	     *	     * (dont bother add it back in again straight away)	     */	    if (IS_K0SEG (rba))		/* hand data buffer over to Sonic */		clean_dcache (PHYS_TO_K0 ((MASK(orr->buff_ptrhi) << 16) |					  orr->buff_ptrlo), RBASIZE);	    rra[sn->sn_rramark] = *orr;	    /* zap old rra */	    orr->buff_wchi = orr->buff_wclo = 0;	    	    sn->sn_rramark = (sn->sn_rramark + 1) & RRAMASK;	    csr->s_rwp = LOWER(&rra[sn->sn_rramark]); wbflush ();	}	/*	 * give receive descriptor back to chip	 * simple list is circular 	 */	rxp->in_use = ~0;	rxp->rlink |= EOL;	sn->sn_lrxp->rlink &= ~EOL;	sn->sn_lrxp = rxp;		if (++sn->sn_rxmark >= NRDA)	  sn->sn_rxmark = 0;	rxp = &rda[sn->sn_rxmark];    }}/* * snread -- pull packet off interface and forward to appropriate * protocol handler */static intsnread (struct sn_softc *sn, volatile struct RXpkt *rxp){    struct ifqueue *inq;    extern char *ether_sprintf();    struct ether_header *eh;    caddr_t addr;    struct mbuf *m;    int len, i;     int toff, tlen;    /*     * Get input data length.     * Get pointer to ethernet header (in input buffer).     * Deal with trailer protocol: if type is PUP trailer     * get true type from first 16-bit word past data.     * Remember that type was trailer by setting off.     */    len = MASK(rxp->byte_count) - FCSSIZE;    addr = (caddr_t) ((MASK(rxp->pkt_ptrhi) << 16) | MASK(rxp->pkt_ptrlo));#ifdef XDSSONICBUG    addr = (caddr_t) ((unsigned int)addr << 1);#endif    if (IS_K0SEG (rba))	addr = (caddr_t) PHYS_TO_K0 (addr);    else	addr = (caddr_t) PHYS_TO_K1 (addr);#ifdef XDSSONICBUG    xds_compress_buffer (addr, len);#endif#ifdef MIPSEL    snswapb (addr, addr, len);#endif#ifdef XDS    {	static struct ether_header ehdr;	copy_data_to_host (addr, (caddr_t)&ehdr, sizeof (ehdr));	eh = &ehdr;	eh->ether_type = ntohs((u_short)eh->ether_type);    }#else    eh = (struct ether_header  *)addr;    eh->ether_type = ntohs((u_short)eh->ether_type);#endif    addr += sizeof (struct ether_header);    len -= sizeof (struct ether_header);    if (len < ETHERMIN || len > ETHERMTU) {	log (LOG_WARNING, "%s%d: bad packet length received: %d bytes\n",	     sn->sn_if.if_name, sn->sn_if.if_unit, len);	return 0;    }        if (eh->ether_type >= ETHERTYPE_TRAIL &&	eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {	toff = (eh->ether_type - ETHERTYPE_TRAIL) * 512;	if (toff >= ETHERMTU) {	    log (LOG_WARNING, "%s%d: trailer offset %d >= ETHERMTU\n",		 sn->sn_if.if_name, sn->sn_if.if_unit, toff);	    return 0;	}#ifdef XDS	{	    struct {		u_short ttype;		u_short tlen;	    } trailer;	    copy_data_to_host (addr + toff, (caddr_t)&trailer, sizeof (trailer));	    eh->ether_type = ntohs(trailer.ttype);	    tlen = ntohs(trailer.tlen);	}#else	eh->ether_type = ntohs(*(u_short *)(addr + toff));	tlen = ntohs(*(u_short *)(addr + toff + sizeof(u_short)));#endif	if (toff + tlen > len) {	    log (LOG_WARNING, "%s%d: bad trailer toff=%d tlen=%d plen=%d\n",		 sn->sn_if.if_name, sn->sn_if.if_unit, toff, tlen, len);	    return 0;	}	len = toff;		/* sizeof data only */	toff += 2*sizeof(u_short);	tlen -= 2*sizeof(u_short);    }    else {	toff = tlen = 0;    }        if (T_rxp) {	printf("rcvd 0x%x status=0x%x len=%d type=0x%x from %s",	       addr, MASK(rxp->status), len, eh->ether_type,	       ether_sprintf (eh->ether_shost));	printf(" (to %s)\n", ether_sprintf (eh->ether_dhost));    }    /*     * Pull packet off interface.  Off is nonzero if packet     * has trailing header; sonic_get will then force this header     * information to be at the front, but we still have to drop     * the type and length which are at the front of any trailer data.     */    m = snget (sn, addr, len, toff, tlen);    if (!m)      return 0;    ether_input (&sn->sn_if, eh, m);    return 1;}/* * munge the received packet into an mbuf chain * because we are using stupid buffer management this  * is slow. */static struct mbuf *snget (struct sn_softc *sn, caddr_t addr, int dlen, int toff, int tlen){    struct mbuf *top = 0;    struct mbuf **mp = &top;    register struct mbuf *m;    register int len;    caddr_t sp;    if (dlen + tlen == 0)      return 0;    MGETHDR (m, M_DONTWAIT, MT_DATA);    if (!m)      return 0;    m->m_pkthdr.rcvif = &sn->sn_if;    m->m_pkthdr.len = dlen + tlen;    m->m_len = MHLEN;    sp = addr + toff;    len = tlen;    while (1) {	if (len == 0) {	    if (dlen == 0)	      return top;	/* all done */	    sp = addr;	    len = dlen;	    dlen = 0;	}	if (top) {	    /* get next mbuf */	    MGET (m, M_DONTWAIT, MT_DATA);	    if (!m) {		m_freem (top);		return 0;	    }	    m->m_len = MLEN;	}	if (len >= MINCLSIZE) {	    MCLGET (m, M_DONTWAIT);	    if (m->m_flags & M_EXT)	      m->m_len = MCLBYTES;	} 	else if (top == 0 && len + max_linkhdr <= m->m_len) {	    /* place initial small packet/header at end of mbuf */	    m->m_data += max_linkhdr;	}			if (m->m_len > len)	  m->m_len = len;	copy_data_to_host (sp, mtod(m, caddr_t), m->m_len);	sp += m->m_len;	len -= m->m_len;	*mp = m;	mp = &m->m_next;    }}static voidmtd_free (struct mtd *mtd){  mtd->mtd_mbuf = (struct mbuf *)0;  mtd->mtd_link = mtdfree;  mtdfree = mtd;}static struct mtd *mtd_alloc (){  struct mtd *mtd;  mtd = mtdfree;  if (mtd) {    mtdfree = mtd->mtd_link;    mtd->mtd_link = 0;  }  return (mtd);}/* * CAM support */static voidcaminitialise (){  int i;  bzero ((char *)cda, CDASIZE);  for (i = 0; i < MAXCAM; i++) {    cda->desc[i].cam_ep = i;    cda->desc[i].cam_ap0 = 0xdead;    cda->desc[i].cam_ap1 = 0xdead;    cda->desc[i].cam_ap2 = 0xdead;  }  cda->enable = 0;}static voidcamentry (int entry, u_char *ea){  cda->desc[entry].cam_ep = entry;  cda->desc[entry].cam_ap2 = (ea[5]<<8) | ea[4];  cda->desc[entry].cam_ap1 = (ea[3]<<8) | ea[2];  cda->desc[entry].cam_ap0 = (ea[1]<<8) | ea[0];  cda->enable |= (1 << entry);}static voidsonictxdump (char *msg, struct TXpkt *txp){  int i;  printf ("%s:\n", msg);  printf ("txp:0x%08x status:0x%04x config:0x%04x pkt_size:0x%04x frag_count:%d\n",           txp, MASK(txp->status), txp->config, txp->pkt_size, txp->frag_count);  for (i = 0; i < txp->frag_count; i++) {    printf ("ptrlo=0x%04x ptrhi=0x%04x size=0x%04x\n",	    txp->frags[i].frag_ptrlo, txp->frags[i].frag_ptrhi, txp->frags[i].frag_size);  }  }static voidsonicdump (char *msg, volatile struct sn_reg *csr){    printf ("%s:\n", msg);    printf ("s_cr\t0x%04x ", csr->s_cr);    printf ("s_dcr\t0x%04x ", csr->s_dcr);    printf ("s_rcr\t0x%04x ", csr->s_rcr);    printf ("\n");    printf ("s_tcr\t0x%04x ", csr->s_tcr);    printf ("s_imr\t0x%04x ", csr->s_imr);    printf ("s_isr\t0x%04x ", csr->s_isr);    printf ("\n");    printf ("s_utda\t0x%04x ", csr->s_utda);    printf ("s_ctda\t0x%04x ", csr->s_ctda);    printf ("s_urda\t0x%04x ", csr->s_urda);    printf ("\n");    printf ("s_crda\t0x%04x ", csr->s_crda);    printf ("s_eobc\t0x%04x ", csr->s_eobc);    printf ("s_urra\t0x%04x ", csr->s_urra);    printf ("\n");    printf ("s_rsa\t0x%04x ", csr->s_rsa);    printf ("s_rea\t0x%04x ", csr->s_rea);    printf ("s_rrp\t0x%04x ", csr->s_rrp);    printf ("\n");    printf ("s_rwp\t0x%04x ", csr->s_rwp);    printf ("s_cep\t0x%04x ", csr->s_cep);    printf ("s_cap2\t0x%04x ", csr->s_cap2);    printf ("\n");    printf ("s_cap1\t0x%04x ", csr->s_cap1);    printf ("s_cap0\t0x%04x ", csr->s_cap0);    printf ("s_ce\t0x%04x ", csr->s_ce);    printf ("\n");    printf ("s_cdp\t0x%04x ", csr->s_cdp);    printf ("s_cdc\t0x%04x ", csr->s_cdc);    printf ("s_sr\t0x%04x ", csr->s_sr);    printf ("\n");    printf ("s_wt0\t0x%04x ", csr->s_wt0);    printf ("s_wt1\t0x%04x ", csr->s_wt1);    printf ("s_rsc\t0x%04x ", csr->s_rsc);    printf ("\n");    printf ("s_crct\t0x%04x ", csr->s_crct);    printf ("s_faet\t0x%04x ", csr->s_faet);    printf ("s_mpt\t0x%04x ", csr->s_mpt);    printf ("\n");    printf ("s_dcr2\t0x%04x ", csr->s_dcr2);    printf ("\n");    printf ("_s_crba0\t0x%04x ", csr->_s_crba0);    printf ("_s_crba1\t0x%04x ", csr->_s_crba1);    printf ("_s_rbwc0\t0x%04x ", csr->_s_rbwc0);    printf ("_s_rbwc1\t0x%04x ", csr->_s_rbwc1);    printf ("\n");}static voidcamdump(volatile struct sn_reg *csr){    int i;  printf ("CAM entries:\n");  csr->s_cr = CR_RST;  wbflush ();     for (i = 0; i < 16; i++) {    u_short ap2, ap1, ap0;    csr->s_cep = i;    wbflush ();    ap2 = csr->s_cap2;    ap1 = csr->s_cap1;    ap0 = csr->s_cap0;    printf ("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i, ap2, ap1, ap0);  }  printf ("CAM enable 0x%x\n", csr->s_ce);     csr->s_cr = 0;  wbflush ();}static intcamprogram(struct sn_softc *sn){  volatile struct sn_reg *csr;  int timeout;  int i;  csr = sn->sn_csr;  csr->s_cdp = LOWER(cda);  csr->s_cdc = MAXCAM; wbflush ();  csr->s_cr = CR_LCAM; wbflush ();  DELAY(1000)  timeout = 1000;  while ((csr->s_cr & CR_LCAM) && --timeout > 0)    DELAY (100);		/* let it get at the bus */  if (timeout <= 0) {      log (LOG_ERR, "sonic: CAM init failed\n");      return 0;  }  timeout = 1000;  while ((csr->s_isr & ISR_LCD) == 0 && --timeout > 0)    DELAY (100);  csr->s_isr = ISR_LCD; wbflush();  if (timeout <= 0) {      log (LOG_ERR, "sonic: CAM init didn't interrupt\n");      return 0;  }

⌨️ 快捷键说明

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