static void
initialise_rra(struct sn_softc *sc)
{
	int	i;
	u_int	v;
	int	bitmode = sc->bitmode;

	if (bitmode)
		NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 2);
	else
		NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 1);

	NIC_PUT(sc, SNR_URRA, UPPER(sc->v_rra[0]));
	NIC_PUT(sc, SNR_RSA, LOWER(sc->v_rra[0]));
	/* rea must point just past the end of the rra space */
	NIC_PUT(sc, SNR_REA, LOWER(sc->v_rea));
	NIC_PUT(sc, SNR_RRP, LOWER(sc->v_rra[0]));
	NIC_PUT(sc, SNR_RSC, 0);

	/* fill up SOME of the rra with buffers */
	for (i = 0; i < NRBA; i++) {
		v = SONIC_GETDMA(sc->rbuf[i]);
		SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v));
		SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v));
		SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(PAGE_SIZE/2));
		SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(PAGE_SIZE/2));
	}
	sc->sc_rramark = NRBA;
	NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[sc->sc_rramark]));
	wbflush();
}
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.
 */
int
snsetup(struct sn_softc	*sc, uint8_t *lladdr)
{
	struct ifnet *ifp = &sc->sc_if;
	uint8_t	*p;
	uint8_t	*pp;
	int	i;

	if (sc->space == NULL) {
		aprint_error_dev(sc->sc_dev,
		    "memory allocation for descriptors failed\n");
		return 1;
	}

	/*
	 * Put the pup in reset mode (sninit() will fix it later),
	 * stop the timer, disable all interrupts and clear any interrupts.
	 */
	NIC_PUT(sc, SNR_CR, CR_STP);
	wbflush();
	NIC_PUT(sc, SNR_CR, CR_RST);
	wbflush();
	NIC_PUT(sc, SNR_IMR, 0);
	wbflush();
	NIC_PUT(sc, SNR_ISR, ISR_ALL);
	wbflush();

	/*
	 * because the SONIC is basically 16bit device it 'concatenates'
	 * a higher buffer address to a 16 bit offset--this will cause wrap
	 * around problems near the end of 64k !!
	 */
	p = sc->space;
	pp = (uint8_t *)roundup((int)p, PAGE_SIZE);
	p = pp;

	for (i = 0; i < NRRA; i++) {
		sc->p_rra[i] = (void *)p;
		sc->v_rra[i] = SONIC_GETDMA(p);
		p += RXRSRC_SIZE(sc);
	}
	sc->v_rea = SONIC_GETDMA(p);

	p = (uint8_t *)SOALIGN(sc, p);

	sc->p_cda = (void *)(p);
	sc->v_cda = SONIC_GETDMA(p);
	p += CDA_SIZE(sc);

	p = (uint8_t *)SOALIGN(sc, p);

	for (i = 0; i < NTDA; i++) {
		struct mtd *mtdp = &sc->mtda[i];
		mtdp->mtd_txp = (void *)p;
		mtdp->mtd_vtxp = SONIC_GETDMA(p);
		p += TXP_SIZE(sc);
	}

	p = (uint8_t *)SOALIGN(sc, p);

	if ((p - pp) > PAGE_SIZE) {
		aprint_error_dev(sc->sc_dev, "sizeof RRA (%ld) + CDA (%ld) +"
		    "TDA (%ld) > PAGE_SIZE (%d). Punt!\n",
		    (ulong)sc->p_cda - (ulong)sc->p_rra[0],
		    (ulong)sc->mtda[0].mtd_txp - (ulong)sc->p_cda,
		    (ulong)p - (ulong)sc->mtda[0].mtd_txp,
		    PAGE_SIZE);
		return 1;
	}

	p = pp + PAGE_SIZE;
	pp = p;

	sc->sc_nrda = PAGE_SIZE / RXPKT_SIZE(sc);
	sc->p_rda = (void *)p;
	sc->v_rda = SONIC_GETDMA(p);

	p = pp + PAGE_SIZE;

	for (i = 0; i < NRBA; i++) {
		sc->rbuf[i] = (void *)p;
		p += PAGE_SIZE;
	}

	pp = p;
	for (i = 0; i < NTDA; i++) {
		struct mtd *mtdp = &sc->mtda[i];

		mtdp->mtd_buf = p;
		mtdp->mtd_vbuf = SONIC_GETDMA(p);
		p += TXBSIZE;
	}

#ifdef SNDEBUG
	camdump(sc);
#endif
	aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
	    ether_sprintf(lladdr));

#ifdef SNDEBUG
	aprint_debug_dev(sc->sc_dev, "buffers: rra=%p cda=%p rda=%p tda=%p\n",
	    device_xname(sc->sc_dev), sc->p_rra[0], sc->p_cda,
	    sc->p_rda, sc->mtda[0].mtd_txp);
#endif

	strcpy(ifp->if_xname, device_xname(sc->sc_dev));
	ifp->if_softc = sc;
	ifp->if_ioctl = snioctl;
	ifp->if_start = snstart;
	ifp->if_flags =
	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
	ifp->if_watchdog = snwatchdog;
	if_attach(ifp);
	ether_ifattach(ifp, lladdr);

	return 0;
}
Example #3
0
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.
 */
int
sncsetup(struct snc_softc *sc, u_int8_t *lladdr)
{
	u_int32_t p, pp;
	int	i;
	int	offset;

	/*
	 * Put the pup in reset mode (sncinit() will fix it later),
	 * stop the timer, disable all interrupts and clear any interrupts.
	 */
	NIC_PUT(sc, SNCR_CR, CR_STP);
	wbflush();
	NIC_PUT(sc, SNCR_CR, CR_RST);
	wbflush();
	NIC_PUT(sc, SNCR_IMR, 0);
	wbflush();
	NIC_PUT(sc, SNCR_ISR, ISR_ALL);
	wbflush();

	/*
	 * because the SONIC is basically 16bit device it 'concatenates'
	 * a higher buffer address to a 16 bit offset--this will cause wrap
	 * around problems near the end of 64k !!
	 */
	p = pp = 0;

	for (i = 0; i < NRRA; i++) {
		sc->v_rra[i] = SONIC_GETDMA(p);
		p += RXRSRC_SIZE(sc);
	}
	sc->v_rea = SONIC_GETDMA(p);

	p = SOALIGN(sc, p);

	sc->v_cda = SONIC_GETDMA(p);
	p += CDA_SIZE(sc);

	p = SOALIGN(sc, p);

	for (i = 0; i < NTDA; i++) {
		struct mtd *mtdp = &sc->mtda[i];
		mtdp->mtd_vtxp = SONIC_GETDMA(p);
		p += TXP_SIZE(sc);
	}

	p = SOALIGN(sc, p);

	if ((p - pp) > PAGE_SIZE) {
		device_printf (sc->sc_dev, "sizeof RRA (%ld) + CDA (%ld) +"
		    "TDA (%ld) > PAGE_SIZE (%d). Punt!\n",
		    (u_long)sc->v_cda - (u_long)sc->v_rra[0],
		    (u_long)sc->mtda[0].mtd_vtxp - (u_long)sc->v_cda,
		    (u_long)p - (u_long)sc->mtda[0].mtd_vtxp,
		    PAGE_SIZE);
		return(1);
	}

	p = pp + PAGE_SIZE;
	pp = p;

	sc->sc_nrda = PAGE_SIZE / RXPKT_SIZE(sc);
	sc->v_rda = SONIC_GETDMA(p);

	p = pp + PAGE_SIZE;

	for (i = 0; i < NRBA; i++) {
		sc->rbuf[i] = p;
		p += PAGE_SIZE;
	}

	pp = p;
	offset = TXBSIZE;
	for (i = 0; i < NTDA; i++) {
		struct mtd *mtdp = &sc->mtda[i];

		mtdp->mtd_vbuf = SONIC_GETDMA(p);
		offset += TXBSIZE;
		if (offset < PAGE_SIZE) {
			p += TXBSIZE;
		} else {
			p = pp + PAGE_SIZE;
			pp = p;
			offset = TXBSIZE;
		}
	}

	return (0);
}