예제 #1
0
/* Initialize interface.  */
static void 
el_init(void *xsc)
{
	struct el_softc *sc = xsc;
	struct ifnet *ifp = &sc->arpcom.ac_if;
	u_short base = sc->el_base;


	/* First, reset the board. */
	dprintf(("Resetting board...\n"));
	el_hardreset(sc);

	/* Configure rx */
	dprintf(("Configuring rx...\n"));
	if(ifp->if_flags & IFF_PROMISC)
		outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
	else
		outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
	outb(base+EL_RBC,0);

	/* Configure TX */
	dprintf(("Configuring tx...\n"));
	outb(base+EL_TXC,0);

	/* Start reception */
	dprintf(("Starting reception...\n"));
	outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));

	/* Set flags appropriately */
	ifp->if_flags |= IFF_RUNNING;
	ifp->if_flags &= ~IFF_OACTIVE;

	/* And start output. */
	el_start(ifp);
}
예제 #2
0
파일: if_el.c 프로젝트: metacore/spin
/* Initialize interface.  */
void el_init(int unit)
{
	struct el_softc *sc;
	struct ifnet *ifp;
	int s;
	u_short base;

	/* Set up pointers */
	sc = &el_softc[unit];
	ifp = &sc->arpcom.ac_if;
	base = sc->el_base;

	/* If address not known, do nothing. */
	if(ifp->if_addrlist == (struct ifaddr *)0)
		return;

	s = splimp();

	/* First, reset the board. */
	dprintf(("Resetting board...\n"));
	el_hardreset(unit);

	/* Configure rx */
	dprintf(("Configuring rx...\n"));
	if(ifp->if_flags & IFF_PROMISC)
		outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
	else
		outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
	outb(base+EL_RBC,0);

	/* Configure TX */
	dprintf(("Configuring tx...\n"));
	outb(base+EL_TXC,0);

	/* Start reception */
	dprintf(("Starting reception...\n"));
	outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));

	/* Set flags appropriately */
	ifp->if_flags |= IFF_RUNNING;
	ifp->if_flags &= ~IFF_OACTIVE;

	/* And start output. */
	el_start(ifp);

	splx(s);
}
예제 #3
0
파일: if_el.c 프로젝트: ycui1984/netbsd-src
/*
 * Initialize interface.
 */
void
elinit(struct el_softc *sc)
{
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;

	/* First, reset the board. */
	el_hardreset(sc);

	/* Configure rx. */
	DPRINTF(("Configuring rx...\n"));
	if (ifp->if_flags & IFF_PROMISC)
		bus_space_write_1(iot, ioh, EL_RXC,
		    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
		    EL_RXC_DOFLOW | EL_RXC_PROMISC);
	else
		bus_space_write_1(iot, ioh, EL_RXC,
		    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
		    EL_RXC_DOFLOW | EL_RXC_ABROAD);
	bus_space_write_1(iot, ioh, EL_RBC, 0);

	/* Configure TX. */
	DPRINTF(("Configuring tx...\n"));
	bus_space_write_1(iot, ioh, EL_TXC, 0);

	/* Start reception. */
	DPRINTF(("Starting reception...\n"));
	bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);

	/* Set flags appropriately. */
	ifp->if_flags |= IFF_RUNNING;
	ifp->if_flags &= ~IFF_OACTIVE;

	/* And start output. */
	elstart(ifp);
}
예제 #4
0
/* Attach the interface to the kernel data structures.  By the time
 * this is called, we know that the card exists at the given I/O address.
 * We still assume that the IRQ given is correct.
 */
static int
el_attach(struct isa_device *idev)
{
	struct el_softc *sc;
	struct ifnet *ifp;

	dprintf(("Attaching el%d...\n",idev->id_unit));

	/* Get things pointing to the right places. */
	idev->id_intr = (inthand2_t *)elintr;
	sc = &el_softc[idev->id_unit];
	ifp = &sc->arpcom.ac_if;

	/* Now reset the board */
	dprintf(("Resetting board...\n"));
	el_hardreset(sc);

	/* Initialize ifnet structure */
	ifp->if_softc = sc;
	if_initname(ifp, "el", idev->id_unit);
	ifp->if_mtu = ETHERMTU;
	ifp->if_start = el_start;
	ifp->if_ioctl = el_ioctl;
	ifp->if_watchdog = el_watchdog;
	ifp->if_init = el_init;
	ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX);
	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
	ifq_set_ready(&ifp->if_snd);

	/* Now we can attach the interface */
	dprintf(("Attaching interface...\n"));
	ether_ifattach(ifp, sc->arpcom.ac_enaddr, &el_serializer);

	dprintf(("el_attach() finished.\n"));
	return(1);
}
예제 #5
0
파일: if_el.c 프로젝트: ycui1984/netbsd-src
/*
 * Controller interrupt.
 */
int
elintr(void *arg)
{
	struct el_softc *sc = arg;
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;
	u_int8_t rxstat;
	int len;

	DPRINTF(("elintr: "));

	/* Check board status. */
	if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0) {
		(void)bus_space_read_1(iot, ioh, EL_RXC);
		bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
		return 0;
	}

	for (;;) {
		rxstat = bus_space_read_1(iot, ioh, EL_RXS);
		if (rxstat & EL_RXS_STALE)
			break;

		/* If there's an overflow, reinit the board. */
		if ((rxstat & EL_RXS_NOFLOW) == 0) {
			DPRINTF(("overflow.\n"));
			el_hardreset(sc);
			/* Put board back into receive mode. */
			if (sc->sc_ethercom.ec_if.if_flags & IFF_PROMISC)
				bus_space_write_1(iot, ioh, EL_RXC,
				    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
				    EL_RXC_DOFLOW | EL_RXC_PROMISC);
			else
				bus_space_write_1(iot, ioh, EL_RXC,
				    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
				    EL_RXC_DOFLOW | EL_RXC_ABROAD);
			(void)bus_space_read_1(iot, ioh, EL_AS);
			bus_space_write_1(iot, ioh, EL_RBC, 0);
			break;
		}

		/* Incoming packet. */
		len = bus_space_read_1(iot, ioh, EL_RBL);
		len |= bus_space_read_1(iot, ioh, EL_RBH) << 8;
		DPRINTF(("receive len=%d rxstat=%x ", len, rxstat));
		bus_space_write_1(iot, ioh, EL_AC, EL_AC_HOST);

		/* Pass data up to upper levels. */
		elread(sc, len);

		/* Is there another packet? */
		if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0)
			break;

		rnd_add_uint32(&sc->rnd_source, rxstat);

		DPRINTF(("<rescan> "));
	}

	(void)bus_space_read_1(iot, ioh, EL_RXC);
	bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
	return 1;
}
예제 #6
0
/* controller interrupt */
static void
elintr(void *arg)
{
	int unit = (int)arg;
	struct el_softc *sc;
	int base;
	int stat, rxstat, len, done;

	lwkt_serialize_enter(&el_serializer);

	/* Get things pointing properly */
	sc = &el_softc[unit];
	base = sc->el_base;

	dprintf(("elintr: "));

	/* Check board status */
	stat = inb(base+EL_AS);
	if(stat & EL_AS_RXBUSY) {
		inb(base+EL_RXC);
		outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));
		lwkt_serialize_exit(&el_serializer);
		return;
	}

	done = 0;
	while(!done) {
		rxstat = inb(base+EL_RXS);
		if(rxstat & EL_RXS_STALE) {
			inb(base+EL_RXC);
			outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));
			lwkt_serialize_exit(&el_serializer);
			return;
		}

		/* If there's an overflow, reinit the board. */
		if(!(rxstat & EL_RXS_NOFLOW)) {
			dprintf(("overflow.\n"));
			el_hardreset(sc);
			/* Put board back into receive mode */
			if(sc->arpcom.ac_if.if_flags & IFF_PROMISC)
				outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
			else
				outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
			inb(base+EL_AS);
			outb(base+EL_RBC,0);
			inb(base+EL_RXC);
			outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));
			lwkt_serialize_exit(&el_serializer);
			return;
		}

		/* Incoming packet */
		len = inb(base+EL_RBL);
		len |= inb(base+EL_RBH) << 8;
		dprintf(("receive len=%d rxstat=%x ",len,rxstat));
		outb(base+EL_AC,EL_AC_HOST);

		/* If packet too short or too long, restore rx mode and return
		 */
		if((len <= sizeof(struct ether_header)) || (len > ETHER_MAX_LEN)) {
			if(sc->arpcom.ac_if.if_flags & IFF_PROMISC)
				outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
			else
				outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW));
			inb(base+EL_AS);
			outb(base+EL_RBC,0);
			inb(base+EL_RXC);
			outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));
			lwkt_serialize_exit(&el_serializer);
			return;
		}

		sc->arpcom.ac_if.if_ipackets++;

		/* Copy the data into our buffer */
		outb(base+EL_GPBL,0);
		outb(base+EL_GPBH,0);
		insb(base+EL_BUF,sc->el_pktbuf,len);
		outb(base+EL_RBC,0);
		outb(base+EL_AC,EL_AC_RX);
		dprintf(("%6D-->",sc->el_pktbuf+6,":"));
		dprintf(("%6D\n",sc->el_pktbuf,":"));

		/* Pass data up to upper levels */
		elread(sc,(caddr_t)(sc->el_pktbuf),len);

		/* Is there another packet? */
		stat = inb(base+EL_AS);

		/* If so, do it all again (i.e. don't set done to 1) */
		if(!(stat & EL_AS_RXBUSY))
			dprintf(("<rescan> "));
		else
			done = 1;
	}

	inb(base+EL_RXC);
	outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));
	lwkt_serialize_exit(&el_serializer);
}
예제 #7
0
파일: if_el.c 프로젝트: metacore/spin
/* Attach the interface to the kernel data structures.  By the time
 * this is called, we know that the card exists at the given I/O address.
 * We still assume that the IRQ given is correct.
 */
int el_attach(struct isa_device *idev)
{
	struct el_softc *sc;
	struct ifnet *ifp;
	struct ifaddr *ifa;
	struct sockaddr_dl *sdl;
	u_short base;
	int t;

	dprintf(("Attaching el%d...\n",idev->id_unit));

	/* Get things pointing to the right places. */
	sc = &el_softc[idev->id_unit];
	ifp = &sc->arpcom.ac_if;
	base = sc->el_base;

	/* Now reset the board */
	dprintf(("Resetting board...\n"));
	el_hardreset(idev->id_unit);

	/* Initialize ifnet structure */
	ifp->if_unit = idev->id_unit;
	ifp->if_name = "el";
	ifp->if_mtu = ETHERMTU;
	ifp->if_init = el_init;
	ifp->if_output = ether_output;
	ifp->if_start = el_start;
	ifp->if_ioctl = el_ioctl;
	ifp->if_reset = el_reset;
	ifp->if_watchdog = el_watchdog;
	ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS);

	/* Now we can attach the interface */
	dprintf(("Attaching interface...\n"));
	if_attach(ifp);
	kdc_el[idev->id_unit].kdc_state = DC_BUSY;

	/* Put the station address in the ifa address list's AF_LINK
	 * entry, if any.
	 */
	ifa = ifp->if_addrlist;
	while ((ifa != NULL) && (ifa->ifa_addr != NULL) &&
	  (ifa->ifa_addr->sa_family != AF_LINK))
		ifa = ifa->ifa_next;
	if((ifa != NULL) && (ifa->ifa_addr != NULL)) {
		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
		sdl->sdl_type = IFT_ETHER;
		sdl->sdl_alen = ETHER_ADDR_LEN;
		sdl->sdl_slen = 0;
		bcopy(sc->arpcom.ac_enaddr,LLADDR(sdl),ETHER_ADDR_LEN);
	}

	/* Print out some information for the user */
	printf("el%d: 3c501 address %s\n",idev->id_unit,
	  ether_sprintf(sc->arpcom.ac_enaddr));

	/* Finally, attach to bpf filter if it is present. */
#if NBPFILTER > 0
	dprintf(("Attaching to BPF...\n"));
	bpfattach(&sc->bpf,ifp,DLT_EN10MB,sizeof(struct ether_header));
#endif

	dprintf(("el_attach() finished.\n"));
	return(1);
}