len = MHLEN - pad;
len -= pad;
struct mbuf *	be_get __P((struct besoftc *, int, int));void	be_tcvr_idle __P((struct besoftc *));void	be_tcvr_init __P((struct besoftc *));void	be_tcvr_write __P((struct besoftc *, u_int8_t, u_int16_t));void	be_tcvr_write_bit __P((struct besoftc *, int));int	be_tcvr_read_bit1 __P((struct besoftc *));int	be_tcvr_read_bit2 __P((struct besoftc *));int	be_tcvr_read __P((struct besoftc *, u_int8_t));void	be_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));int	be_ifmedia_upd __P((struct ifnet *));void	be_mcreset __P((struct besoftc *));struct cfdriver be_cd = {	NULL, "be", DV_IFNET};struct cfattach be_ca = {	sizeof(struct besoftc), bematch, beattach};intbematch(parent, vcf, aux)	struct device *parent;	void *vcf, *aux;{	struct cfdata *cf = vcf;	struct confargs *ca = aux;	register struct romaux *ra = &ca->ca_ra;	if (strcmp(cf->cf_driver->cd_name, ra->ra_name))		return (0);	return (1);}voidbeattach(parent, self, aux)	struct device *parent, *self;	void *aux;{	struct qec_softc *qec = (struct qec_softc *)parent;	struct besoftc *sc = (struct besoftc *)self;	struct ifnet *ifp = &sc->sc_arpcom.ac_if;	struct confargs *ca = aux;	struct bootpath *bp;	extern void myetheraddr __P((u_char *));	int pri, bmsr;	if (ca->ca_ra.ra_nintr != 1) {		printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);		return;	}	pri = ca->ca_ra.ra_intr[0].int_pri;	sc->sc_rev = getpropint(ca->ca_ra.ra_node, "board-version", -1);	sc->sc_cr = mapiodev(&ca->ca_ra.ra_reg[0], 0, sizeof(struct be_cregs));	sc->sc_br = mapiodev(&ca->ca_ra.ra_reg[1], 0, sizeof(struct be_bregs));	sc->sc_tr = mapiodev(&ca->ca_ra.ra_reg[2], 0, sizeof(struct be_tregs));	sc->sc_qec = qec;	sc->sc_qr = qec->sc_regs;	bestop(sc);	sc->sc_channel = getpropint(ca->ca_ra.ra_node, "channel#", -1);	if (sc->sc_channel == -1)		sc->sc_channel = 0;	sc->sc_burst = getpropint(ca->ca_ra.ra_node, "burst-sizes", -1);	if (sc->sc_burst == -1)		sc->sc_burst = qec->sc_burst;	/* Clamp at parent's burst sizes */	sc->sc_burst &= qec->sc_burst;	sc->sc_ih.ih_fun = beintr;	sc->sc_ih.ih_arg = sc;	intr_establish(pri, &sc->sc_ih);	myetheraddr(sc->sc_arpcom.ac_enaddr);	be_tcvr_init(sc);	ifmedia_init(&sc->sc_ifmedia, 0, be_ifmedia_upd, be_ifmedia_sts);	bmsr = be_tcvr_read(sc, PHY_BMSR);	if (bmsr == BE_TCVR_READ_INVALID)		return;	if (bmsr & PHY_BMSR_10BASET_HALF) {		ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);		ifmedia_add(&sc->sc_ifmedia,		    IFM_ETHER | IFM_10_T | IFM_HDX, 0, NULL);		sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX;	}	if (bmsr & PHY_BMSR_10BASET_FULL) {		ifmedia_add(&sc->sc_ifmedia,		    IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);		sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_FDX;	}	if (bmsr & PHY_BMSR_100BASETX_HALF) {		ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL);		ifmedia_add(&sc->sc_ifmedia,		    IFM_ETHER | IFM_100_TX | IFM_HDX, 0, NULL);		sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_HDX;	}	if (bmsr & PHY_BMSR_100BASETX_FULL) {		ifmedia_add(&sc->sc_ifmedia,		    IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);		sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_FDX;	}	if (bmsr & PHY_BMSR_100BASET4) {		ifmedia_add(&sc->sc_ifmedia,		    IFM_ETHER | IFM_100_T4, 0, NULL);		sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_100_T4;	}	if (bmsr & PHY_BMSR_ANC) {		ifmedia_add(&sc->sc_ifmedia,		    IFM_ETHER | IFM_AUTO, 0, NULL);		sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_AUTO;	}	ifmedia_set(&sc->sc_ifmedia, sc->sc_ifmedia.ifm_media);	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);	ifp->if_softc = sc;	ifp->if_start = bestart;	ifp->if_ioctl = beioctl;	ifp->if_watchdog = bewatchdog;	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |	    IFF_MULTICAST;	/* Attach the interface. */	if_attach(ifp);	ether_ifattach(ifp);	printf(" pri %d: rev %x address %s\n", pri, sc->sc_rev,	    ether_sprintf(sc->sc_arpcom.ac_enaddr));#if NBPFILTER > 0	bpfattach(&sc->sc_arpcom.ac_if.if_bpf, ifp, DLT_EN10MB,	    sizeof(struct ether_header));#endif	bp = ca->ca_ra.ra_bp;	if (bp != NULL && strcmp(bp->name, "be") == 0 &&	    sc->sc_dev.dv_unit == bp->val[1])		bp->dev = &sc->sc_dev;}/* * Start output on interface. * We make two assumptions here: *  1) that the current priority is set to splnet _before_ this code *     is called *and* is returned to the appropriate priority after *     return *  2) that the IFF_OACTIVE flag is checked before this code is called *     (i.e. that the output part of the interface is idle) */voidbestart(ifp)	struct ifnet *ifp;{	struct besoftc *sc = (struct besoftc *)ifp->if_softc;	struct mbuf *m;	int bix, len;	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)		return;	bix = sc->sc_last_td;	for (;;) {		IF_DEQUEUE(&ifp->if_snd, m);		if (m == 0)			break;#if NBPFILTER > 0		/*		 * If BPF is listening on this interface, let it see the		 * packet before we commit it to the wire.		 */		if (ifp->if_bpf)			bpf_mtap(ifp->if_bpf, m);#endif		/*		 * Copy the mbuf chain into the transmit buffer.		 */		len = be_put(sc, bix, m);		/*		 * Initialize transmit registers and start transmission		 */		sc->sc_desc->be_txd[bix].tx_flags =			BE_TXD_OWN | BE_TXD_SOP | BE_TXD_EOP |			(len & BE_TXD_LENGTH);		sc->sc_cr->ctrl = BE_CR_CTRL_TWAKEUP;		if (++bix == BE_TX_RING_MAXSIZE)			bix = 0;		if (++sc->sc_no_td == BE_TX_RING_SIZE) {			ifp->if_flags |= IFF_OACTIVE;			break;		}	}	sc->sc_last_td = bix;}voidbestop(sc)	struct besoftc *sc;{	int tries;	tries = 32;	sc->sc_br->tx_cfg = 0;	while (sc->sc_br->tx_cfg != 0 && --tries)		DELAY(20);	tries = 32;	sc->sc_br->rx_cfg = 0;	while (sc->sc_br->rx_cfg != 0 && --tries)		DELAY(20);}/* * Reset interface. */voidbereset(sc)	struct besoftc *sc;{	int s;	s = splnet();	bestop(sc);	beinit(sc);	splx(s);}voidbewatchdog(ifp)	struct ifnet *ifp;{	struct besoftc *sc = ifp->if_softc;	log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);	++sc->sc_arpcom.ac_if.if_oerrors;	bereset(sc);}intbeintr(v)	void *v;{	struct besoftc *sc = (struct besoftc *)v;	u_int32_t whyq, whyb, whyc;	int r = 0;	whyq = sc->sc_qr->stat;		/* qec status */	whyc = sc->sc_cr->stat;		/* be channel status */	whyb = sc->sc_br->stat;		/* be status */	if (whyq & QEC_STAT_BM)		r |= beeint(sc, whyb);	if (whyq & QEC_STAT_ER)		r |= beqint(sc, whyc);	if (whyq & QEC_STAT_TX && whyc & BE_CR_STAT_TXIRQ)		r |= betint(sc);	if (whyq & QEC_STAT_RX && whyc & BE_CR_STAT_RXIRQ)		r |= berint(sc);	return (r);}/* * QEC Interrupt. */intbeqint(sc, why)	struct besoftc *sc;	u_int32_t why;{	int r = 0, rst = 0;	if (why & BE_CR_STAT_TXIRQ)		r |= 1;	if (why & BE_CR_STAT_RXIRQ)		r |= 1;	if (why & BE_CR_STAT_ERRORS) {		r |= 1;		rst = 1;	}	if (rst || r == 0) {		printf("%s:%s qstat=%b\n", sc->sc_dev.dv_xname,		    (r) ? "" : " unexpected",		    why, BE_CR_STAT_BITS);		printf("%s: resetting\n", sc->sc_dev.dv_xname);		bereset(sc);	}	return r;}/* * Error interrupt. */intbeeint(sc, why)	struct besoftc *sc;	u_int32_t why;{	int r = 0;	if (why & (BE_BR_STAT_RFIFOVF | BE_BR_STAT_TFIFO_UND |		   BE_BR_STAT_MAXPKTERR)) {		r |= 1;	}	printf("%s:%s stat=%b\n", sc->sc_dev.dv_xname,	    (r) ? "" : " unexpected", why, BE_BR_STAT_BITS);	printf("%s: resetting\n", sc->sc_dev.dv_xname);	bereset(sc);	return r;}/* * Transmit interrupt. */intbetint(sc)	struct besoftc *sc;{	struct ifnet *ifp = &sc->sc_arpcom.ac_if;	struct be_bregs *br = sc->sc_br;	int bix;	struct be_txd txd;	/*	 * Get collision counters	 */	ifp->if_collisions += br->nc_ctr + br->fc_ctr + br->ex_ctr + br->lt_ctr;	br->nc_ctr = 0;	br->fc_ctr = 0;	br->ex_ctr = 0;	br->lt_ctr = 0;	bix = sc->sc_first_td;	for (;;) {		if (sc->sc_no_td <= 0)			break;		txd.tx_flags = sc->sc_desc->be_txd[bix].tx_flags;		if (txd.tx_flags & BE_TXD_OWN)			break;		ifp->if_flags &= ~IFF_OACTIVE;		ifp->if_opackets++;		if (++bix == BE_TX_RING_MAXSIZE)			bix = 0;		--sc->sc_no_td;	}	sc->sc_first_td = bix;	bestart(ifp);	if (sc->sc_no_td == 0)		ifp->if_timer = 0;	return 1;}/* * Receive interrupt. */intberint(sc)	struct besoftc *sc;{	int bix, len;	bix = sc->sc_last_rd;	/*	 * Process all buffers with valid data.	 */	for (;;) {		if (sc->sc_desc->be_rxd[bix].rx_flags & BE_RXD_OWN)			break;		len = sc->sc_desc->be_rxd[bix].rx_flags & BE_RXD_LENGTH;		be_read(sc, bix, len);		sc->sc_desc->be_rxd[(bix + BE_RX_RING_SIZE)%BE_RX_RING_MAXSIZE].rx_flags =		    BE_RXD_OWN | (BE_PKT_BUF_SZ & BE_RXD_LENGTH);		if (++bix == BE_RX_RING_MAXSIZE)			bix = 0;	}	sc->sc_last_rd = bix;	return 1;}intbeioctl(ifp, cmd, data)	struct ifnet *ifp;	u_long cmd;	caddr_t data;{	struct besoftc *sc = ifp->if_softc;	struct ifaddr *ifa = (struct ifaddr *)data;	struct ifreq *ifr = (struct ifreq *)data;	int s, error = 0;	s = splnet();	switch (cmd) {	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		switch (ifa->ifa_addr->sa_family) {#ifdef INET		case AF_INET:			beinit(sc);			arp_ifinit(&sc->sc_arpcom, ifa);			break;#endif /* INET */#ifdef NS		/* XXX - This code is probably wrong. */		case AF_NS:		    {			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;			if (ns_nullhost(*ina))				ina->x_host = *(union ns_host *)				    (sc->sc_arpcom.ac_enaddr);			else				bcopy(ina->x_host.c_host,				    sc->sc_arpcom.ac_enaddr,				    sizeof(sc->sc_arpcom.ac_enaddr));			/* Set new address. */			beinit(sc);			break;		    }#endif /* NS */		default:			beinit(sc);			break;		}		break;	case SIOCSIFFLAGS:		if ((ifp->if_flags & IFF_UP) == 0 &&		    (ifp->if_flags & IFF_RUNNING) != 0) {			/*			 * If interface is marked down and it is running, then			 * stop it.			 */			bestop(sc);			ifp->if_flags &= ~IFF_RUNNING;		} else if ((ifp->if_flags & IFF_UP) != 0 &&		    (ifp->if_flags & IFF_RUNNING) == 0) {			/*			 * If interface is marked up and it is stopped, then			 * start it.			 */			beinit(sc);		} else {			/*			 * Reset the interface to pick up changes in any other			 * flags that affect hardware registers.			 */			bestop(sc);			beinit(sc);		}#ifdef IEDEBUG   		if (ifp->if_flags & IFF_DEBUG)			sc->sc_debug = IED_ALL;		else			sc->sc_debug = 0;#endif		break;	case SIOCADDMULTI:	case SIOCDELMULTI:		error = (cmd == SIOCADDMULTI) ?		    ether_addmulti(ifr, &sc->sc_arpcom):		    ether_delmulti(ifr, &sc->sc_arpcom);		if (error == ENETRESET) {			/*			 * Multicast list has changed; set the hardware filter			 * accordingly.			 */			be_mcreset(sc);			error = 0;		}		break;	case SIOCGIFMEDIA:	case SIOCSIFMEDIA:		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);		break;	default:		if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {			splx(s);			return error;		}		error = EINVAL;		break;	}	splx(s);	return error;}voidbeinit(sc)	struct besoftc *sc;{	struct be_bregs *br = sc->sc_br;	struct be_cregs *cr = sc->sc_cr;	struct qec_softc *qec = sc->sc_qec;	struct ifnet *ifp = &sc->sc_arpcom.ac_if;	int s = splimp();	int i;	sc->sc_nticks = 0;	/*	 * Allocate descriptor ring and buffers, if not already done	 */	if (sc->sc_desc == NULL)		sc->sc_desc_dva = (struct be_desc *) dvma_malloc(			sizeof(struct be_desc), &sc->sc_desc, M_NOWAIT);	if (sc->sc_bufs == NULL)		sc->sc_bufs_dva = (struct be_bufs *) dvma_malloc(			sizeof(struct be_bufs), &sc->sc_bufs, M_NOWAIT);		for (i = 0; i < BE_TX_RING_MAXSIZE; i++) {		sc->sc_desc->be_txd[i].tx_addr =			(u_int32_t) &sc->sc_bufs_dva->tx_buf[i % BE_TX_RING_SIZE][0];		sc->sc_desc->be_txd[i].tx_flags = 0;	}	for (i = 0; i < BE_RX_RING_MAXSIZE; i++) {		sc->sc_desc->be_rxd[i].rx_addr =			(u_int32_t) &sc->sc_bufs_dva->rx_buf[i % BE_RX_RING_SIZE][0];		if ((i / BE_RX_RING_SIZE) == 0)			sc->sc_desc->be_rxd[i].rx_flags =				BE_RXD_OWN |				(BE_PKT_BUF_SZ & BE_RXD_LENGTH);		else			sc->sc_desc->be_rxd[i].rx_flags = 0;	}	sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;	sc->sc_last_rd = 0;	be_tcvr_init(sc);	be_ifmedia_upd(ifp);	bestop(sc);	br->mac_addr2 = (sc->sc_arpcom.ac_enaddr[4] << 8) |	    sc->sc_arpcom.ac_enaddr[5];	br->mac_addr1 = (sc->sc_arpcom.ac_enaddr[2] << 8) |	    sc->sc_arpcom.ac_enaddr[3];	br->mac_addr0 = (sc->sc_arpcom.ac_enaddr[0] << 8) |	    sc->sc_arpcom.ac_enaddr[1];	br->rx_cfg = BE_BR_RXCFG_HENABLE | BE_BR_RXCFG_FIFO;	be_mcreset(sc);	DELAY(20);	br->tx_cfg = BE_BR_TXCFG_FIFO;	br->rand_seed = 0xbd;	br->xif_cfg = BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV;	cr->rxds = (u_int32_t) &sc->sc_desc_dva->be_rxd[0];	cr->txds = (u_int32_t) &sc->sc_desc_dva->be_txd[0];	cr->rxwbufptr = cr->rxrbufptr = sc->sc_channel * qec->sc_msize;	cr->txwbufptr = cr->txrbufptr = cr->rxrbufptr + qec->sc_rsize;	/*	 * Turn off counter expiration interrupts as well as	 * 'gotframe' and 'sentframe'	 */	br->imask = BE_BR_IMASK_GOTFRAME	|		    BE_BR_IMASK_RCNTEXP		|		    BE_BR_IMASK_ACNTEXP		|		    BE_BR_IMASK_CCNTEXP		|		    BE_BR_IMASK_LCNTEXP		|		    BE_BR_IMASK_CVCNTEXP	|		    BE_BR_IMASK_SENTFRAME	|		    BE_BR_IMASK_NCNTEXP		|		    BE_BR_IMASK_ECNTEXP		|		    BE_BR_IMASK_LCCNTEXP	|		    BE_BR_IMASK_FCNTEXP		|		    BE_BR_IMASK_DTIMEXP;	cr->rimask = 0;	cr->timask = 0;	cr->qmask = 0;	cr->bmask = 0;	br->jsize = 4;	cr->ccnt = 0;	br->tx_cfg |= BE_BR_TXCFG_ENABLE;	br->rx_cfg |= BE_BR_RXCFG_ENABLE;	ifp->if_flags |= IFF_RUNNING;	ifp->if_flags &= ~IFF_OACTIVE;	splx(s);}/* * Set the tcvr to an idle state */voidbe_tcvr_idle(sc)	struct besoftc *sc;{	struct be_tregs *tr = sc->sc_tr;	volatile u_int32_t x;	int i = 20;	while (i--) {		tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |			       MGMT_PAL_OENAB;		x = tr->mgmt_pal;		tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |			       MGMT_PAL_OENAB | MGMT_PAL_DCLOCK;		x = tr->mgmt_pal;	}}/* * Initialize the transceiver and figure out whether we're using the * external or internal one. */voidbe_tcvr_init(sc)	struct besoftc *sc;{	volatile u_int32_t x;	struct be_tregs *tr = sc->sc_tr;	be_tcvr_idle(sc);	if (sc->sc_rev != 1) {		printf("%s: rev %d PAL not supported.\n",			sc->sc_dev.dv_xname,			sc->sc_rev);		return;	}	tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;	x = tr->mgmt_pal;	tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO;	x = tr->mgmt_pal;	DELAY(200);	if (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) {		sc->sc_tcvr_type = BE_TCVR_EXTERNAL;		tr->tcvr_pal = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE |				 TCVR_PAL_LTENABLE);		x = tr->tcvr_pal;	}	else if (tr->mgmt_pal & MGMT_PAL_INT_MDIO) {		sc->sc_tcvr_type = BE_TCVR_INTERNAL;		tr->tcvr_pal = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE |				 TCVR_PAL_LTENABLE | TCVR_PAL_SERIAL);		x = tr->tcvr_pal;	}	else {		printf("%s: no internal or external transceiver found.\n",			sc->sc_dev.dv_xname);	}}intbe_tcvr_read(sc, reg)	struct besoftc *sc;	u_int8_t reg;{	int phy, i;	u_int32_t ret = 0;	if (sc->sc_tcvr_type == BE_TCVR_INTERNAL)		phy = BE_PHY_INTERNAL;	else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL)		phy = BE_PHY_EXTERNAL;	else {		printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);		return BE_TCVR_READ_INVALID;	}	be_tcvr_idle(sc);	be_tcvr_write_bit(sc, 0);	be_tcvr_write_bit(sc, 1);	be_tcvr_write_bit(sc, 1);	be_tcvr_write_bit(sc, 0);	for (i = 4; i >= 0; i--)		be_tcvr_write_bit(sc, (phy >> i) & 1);	for (i = 4; i >= 0; i--)		be_tcvr_write_bit(sc, (reg >> i) & 1);	if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {		(void) be_tcvr_read_bit2(sc);		(void) be_tcvr_read_bit2(sc);		for (i = 15; i >= 0; i--) {			int b;			b = be_tcvr_read_bit2(sc);			ret |= (b & 1) << i;		}		(void) be_tcvr_read_bit2(sc);		(void) be_tcvr_read_bit2(sc);		(void) be_tcvr_read_bit2(sc);	}	else {		(void) be_tcvr_read_bit1(sc);		(void) be_tcvr_read_bit1(sc);		for (i = 15; i >= 0; i--) {			int b;			b = be_tcvr_read_bit1(sc);			ret |= (b & 1) << i;		}		(void) be_tcvr_read_bit1(sc);		(void) be_tcvr_read_bit1(sc);		(void) be_tcvr_read_bit1(sc);	}	return ret;}intbe_tcvr_read_bit1(sc)	struct besoftc *sc;{	volatile u_int32_t x;	struct be_tregs *tr = sc->sc_tr;	int ret = 0;	if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {		tr->mgmt_pal = MGMT_PAL_EXT_MDIO;		x = tr->mgmt_pal;		tr->mgmt_pal = MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;		x = tr->mgmt_pal;		DELAY(20);		ret = (tr->mgmt_pal & MGMT_PAL_INT_MDIO) >> 3;	} else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {		tr->mgmt_pal = MGMT_PAL_INT_MDIO;		x = tr->mgmt_pal;		tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK;		x = tr->mgmt_pal;		DELAY(20);		ret = (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) >> 2;	} else {		printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);	}	return (ret & 1);}intbe_tcvr_read_bit2(sc)	struct besoftc *sc;{	volatile u_int32_t x;	struct be_tregs *tr = sc->sc_tr;	int ret = 0;	if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {		tr->mgmt_pal = MGMT_PAL_EXT_MDIO;		x = tr->mgmt_pal;		DELAY(20);		ret = (tr->mgmt_pal & MGMT_PAL_INT_MDIO) >> 3;		tr->mgmt_pal = MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;		x = tr->mgmt_pal;	} else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {		tr->mgmt_pal = MGMT_PAL_INT_MDIO;		x = tr->mgmt_pal;		DELAY(20);		ret = (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) >> 2;		tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK;		x = tr->mgmt_pal;	} else {		printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);	}	return ret;}voidbe_tcvr_write(sc, reg, val)	struct besoftc *sc;	u_int8_t reg;	u_int16_t val;{	int phy, i;	if (sc->sc_tcvr_type == BE_TCVR_INTERNAL)		phy = BE_PHY_INTERNAL;	else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL)		phy = BE_PHY_EXTERNAL;	else {		printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);		return;	}	be_tcvr_idle(sc);	be_tcvr_write_bit(sc, 0);	be_tcvr_write_bit(sc, 1);	be_tcvr_write_bit(sc, 0);	be_tcvr_write_bit(sc, 1);	for (i = 4; i >= 0; i--)		be_tcvr_write_bit(sc, (phy >> i) & 1);	for (i = 4; i >= 0; i--)		be_tcvr_write_bit(sc, (reg >> i) & 1);	be_tcvr_write_bit(sc, 1);	be_tcvr_write_bit(sc, 0);	for (i = 15; i >= 0; i--)		be_tcvr_write_bit(sc, (val >> i) & 1);}voidbe_tcvr_write_bit(sc, bit)	struct besoftc *sc;	int bit;{	volatile u_int32_t x;	if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {		bit = ((bit & 1) << 3) | MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO;		sc->sc_tr->mgmt_pal = bit;		x = sc->sc_tr->mgmt_pal;		sc->sc_tr->mgmt_pal = bit | MGMT_PAL_DCLOCK;		x = sc->sc_tr->mgmt_pal;	} else {		bit = ((bit & 1) << 2) | MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO;		sc->sc_tr->mgmt_pal = bit;		x = sc->sc_tr->mgmt_pal;		sc->sc_tr->mgmt_pal = bit | MGMT_PAL_DCLOCK;		x = sc->sc_tr->mgmt_pal;	}}/* * Routine to copy from mbuf chain to transmit buffer in * network buffer memory. */intbe_put(sc, idx, m)	struct besoftc *sc;	int idx;	struct mbuf *m;{	struct mbuf *n;	int len, tlen = 0, boff = 0;	for (; m; m = n) {		len = m->m_len;		if (len == 0) {			MFREE(m, n);			continue;		}		bcopy(mtod(m, caddr_t),		      &sc->sc_bufs->tx_buf[idx % BE_TX_RING_SIZE][boff], len);		boff += len;		tlen += len;		MFREE(m, n);	}	return tlen;}/* * Pass a packet to the higher levels. */voidbe_read(sc, idx, len)	struct besoftc *sc;	int idx, len;{	struct ifnet *ifp = &sc->sc_arpcom.ac_if;	struct ether_header *eh;	struct mbuf *m;	if (len <= sizeof(struct ether_header) ||	    len > ETHERMTU + sizeof(struct ether_header)) {		printf("%s: invalid packet size %d; dropping\n",			ifp->if_xname, len);		ifp->if_ierrors++;		return;	}	/*	 * Pull packet off interface.	 */	m = be_get(sc, idx, len);	if (m == NULL) {		ifp->if_ierrors++;		return;	}	ifp->if_ipackets++;	/* We assume that the header fit entirely in one mbuf. */	eh = mtod(m, struct ether_header *);#if NBPFILTER > 0	/*	 * Check if there's a BPF listener on this interface.	 * If so, hand off the raw packet to BPF.	 */	if (ifp->if_bpf)		bpf_mtap(ifp->if_bpf, m);#endif	/* Pass the packet up, with the ether header sort-of removed. */	m_adj(m, sizeof(struct ether_header));	ether_input(ifp, eh, m);}/* * Pull data off an interface. * Len is the length of data, with local net header stripped. * We copy the data into mbufs.  When full cluster sized units are present, * we copy into clusters. */struct mbuf *be_get(sc, idx, totlen)	struct besoftc *sc;	int idx, totlen;{	struct ifnet *ifp = &sc->sc_arpcom.ac_if;	struct mbuf *m;	struct mbuf *top, **mp;	int len, pad, boff = 0;	MGETHDR(m, M_DONTWAIT, MT_DATA);	if (m == NULL)		return (NULL);	m->m_pkthdr.rcvif = ifp;	m->m_pkthdr.len = totlen;	pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);	m->m_data += pad;	len = MHLEN - pad;	top = NULL;	mp = &top;	while (totlen > 0) {		if (top) {			MGET(m, M_DONTWAIT, MT_DATA);			if (m == NULL) {				m_freem(top);				return NULL;			}			len = MLEN;		}		if (top && totlen >= MINCLSIZE) {			MCLGET(m, M_DONTWAIT);			if (m->m_flags & M_EXT)				len = MCLBYTES;		}		m->m_len = len = min(totlen, len);		bcopy(&sc->sc_bufs->rx_buf[idx % BE_RX_RING_SIZE][boff],		      mtod(m, caddr_t), len);		boff += len;		totlen -= len;		*mp = m;		mp = &m->m_next;	}	return (top);}