int beioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct be_softc *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 */ 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 BEDEBUG if (ifp->if_flags & IFF_DEBUG) sc->sc_debug = 1; else sc->sc_debug = 0; #endif break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); break; default: error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data); } if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) be_mcreset(sc); error = 0; } splx(s); return (error); }
int beinit(struct ifnet *ifp) { struct be_softc *sc = ifp->if_softc; bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t br = sc->sc_br; bus_space_handle_t cr = sc->sc_cr; struct qec_softc *qec = sc->sc_qec; uint32_t v; uint32_t qecaddr; uint8_t *ea; int rc, s; s = splnet(); qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ); bestop(ifp, 1); ea = sc->sc_enaddr; bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]); bus_space_write_4(t, br, BE_BRI_MACADDR1, (ea[2] << 8) | ea[3]); bus_space_write_4(t, br, BE_BRI_MACADDR2, (ea[4] << 8) | ea[5]); /* Clear hash table */ bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0); /* Re-initialize RX configuration */ v = BE_BR_RXCFG_FIFO; bus_space_write_4(t, br, BE_BRI_RXCFG, v); be_mcreset(sc); bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd); bus_space_write_4(t, br, BE_BRI_XIFCFG, BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV); bus_space_write_4(t, br, BE_BRI_JSIZE, 4); /* * Turn off counter expiration interrupts as well as * 'gotframe' and 'sentframe' */ bus_space_write_4(t, br, BE_BRI_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); /* Channel registers: */ bus_space_write_4(t, cr, BE_CRI_RXDS, (uint32_t)sc->sc_rb.rb_rxddma); bus_space_write_4(t, cr, BE_CRI_TXDS, (uint32_t)sc->sc_rb.rb_txddma); qecaddr = sc->sc_channel * qec->sc_msize; bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr); bus_space_write_4(t, cr, BE_CRI_RXRBUF, qecaddr); bus_space_write_4(t, cr, BE_CRI_TXWBUF, qecaddr + qec->sc_rsize); bus_space_write_4(t, cr, BE_CRI_TXRBUF, qecaddr + qec->sc_rsize); bus_space_write_4(t, cr, BE_CRI_RIMASK, 0); bus_space_write_4(t, cr, BE_CRI_TIMASK, 0); bus_space_write_4(t, cr, BE_CRI_QMASK, 0); bus_space_write_4(t, cr, BE_CRI_BMASK, 0); bus_space_write_4(t, cr, BE_CRI_CCNT, 0); /* Set max packet length */ v = ETHER_MAX_LEN; if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) v += ETHER_VLAN_ENCAP_LEN; bus_space_write_4(t, br, BE_BRI_RXMAX, v); bus_space_write_4(t, br, BE_BRI_TXMAX, v); /* Enable transmitter */ bus_space_write_4(t, br, BE_BRI_TXCFG, BE_BR_TXCFG_FIFO | BE_BR_TXCFG_ENABLE); /* Enable receiver */ v = bus_space_read_4(t, br, BE_BRI_RXCFG); v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE; bus_space_write_4(t, br, BE_BRI_RXCFG, v); if ((rc = be_ifmedia_upd(ifp)) != 0) goto out; ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; callout_reset(&sc->sc_tick_ch, hz, be_tick, sc); return 0; out: splx(s); return rc; }
void beinit(struct be_softc *sc) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t br = sc->sc_br; bus_space_handle_t cr = sc->sc_cr; struct qec_softc *qec = sc->sc_qec; u_int32_t v; u_int32_t qecaddr; u_int8_t *ea; int s; s = splnet(); qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ); bestop(sc); ea = sc->sc_arpcom.ac_enaddr; bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]); bus_space_write_4(t, br, BE_BRI_MACADDR1, (ea[2] << 8) | ea[3]); bus_space_write_4(t, br, BE_BRI_MACADDR2, (ea[4] << 8) | ea[5]); /* Clear hash table */ bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0); /* Re-initialize RX configuration */ v = BE_BR_RXCFG_FIFO; bus_space_write_4(t, br, BE_BRI_RXCFG, v); be_mcreset(sc); bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd); bus_space_write_4(t, br, BE_BRI_XIFCFG, BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV); bus_space_write_4(t, br, BE_BRI_JSIZE, 4); /* * Turn off counter expiration interrupts as well as * 'gotframe' and 'sentframe' */ bus_space_write_4(t, br, BE_BRI_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); /* Channel registers: */ bus_space_write_4(t, cr, BE_CRI_RXDS, (u_int32_t)sc->sc_rb.rb_rxddma); bus_space_write_4(t, cr, BE_CRI_TXDS, (u_int32_t)sc->sc_rb.rb_txddma); qecaddr = sc->sc_channel * qec->sc_msize; bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr); bus_space_write_4(t, cr, BE_CRI_RXRBUF, qecaddr); bus_space_write_4(t, cr, BE_CRI_TXWBUF, qecaddr + qec->sc_rsize); bus_space_write_4(t, cr, BE_CRI_TXRBUF, qecaddr + qec->sc_rsize); bus_space_write_4(t, cr, BE_CRI_RIMASK, 0); bus_space_write_4(t, cr, BE_CRI_TIMASK, 0); bus_space_write_4(t, cr, BE_CRI_QMASK, 0); bus_space_write_4(t, cr, BE_CRI_BMASK, 0); bus_space_write_4(t, cr, BE_CRI_CCNT, 0); /* Enable transmitter */ bus_space_write_4(t, br, BE_BRI_TXCFG, BE_BR_TXCFG_FIFO | BE_BR_TXCFG_ENABLE); /* Enable receiver */ v = bus_space_read_4(t, br, BE_BRI_RXCFG); v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE; bus_space_write_4(t, br, BE_BRI_RXCFG, v); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; be_ifmedia_upd(ifp); timeout_add_sec(&sc->sc_tick_ch, 1); splx(s); }