/* * 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; }
/* * 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); }