if_ne_intio.c revision 1.8
11.8Swiz/* $NetBSD: if_ne_intio.c,v 1.8 2004/02/13 10:05:49 wiz Exp $ */ 21.1Sisaki 31.1Sisaki/* 41.1Sisaki * Copyright (c) 2001 Tetsuya Isaki. All rights reserved. 51.1Sisaki * 61.1Sisaki * Redistribution and use in source and binary forms, with or without 71.1Sisaki * modification, are permitted provided that the following conditions 81.1Sisaki * are met: 91.1Sisaki * 1. Redistributions of source code must retain the above copyright 101.1Sisaki * notice, this list of conditions and the following disclaimer. 111.1Sisaki * 2. Redistributions in binary form must reproduce the above copyright 121.1Sisaki * notice, this list of conditions and the following disclaimer in the 131.1Sisaki * documentation and/or other materials provided with the distribution. 141.7Sisaki * 3. The name of the author may not be used to endorse or promote products 151.1Sisaki * derived from this software without specific prior written permission 161.1Sisaki * 171.1Sisaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 181.1Sisaki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 191.1Sisaki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 201.1Sisaki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 211.1Sisaki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 221.1Sisaki * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 231.1Sisaki * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 241.1Sisaki * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 251.1Sisaki * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261.1Sisaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271.1Sisaki * SUCH DAMAGE. 281.1Sisaki */ 291.1Sisaki 301.1Sisaki/* 311.1Sisaki * Ethernet part of Nereid Ethernet/USB/Memory board 321.1Sisaki */ 331.6Slukem 341.6Slukem#include <sys/cdefs.h> 351.8Swiz__KERNEL_RCSID(0, "$NetBSD: if_ne_intio.c,v 1.8 2004/02/13 10:05:49 wiz Exp $"); 361.1Sisaki 371.1Sisaki#include "opt_inet.h" 381.1Sisaki#include "opt_ns.h" 391.1Sisaki#include "bpfilter.h" 401.1Sisaki 411.1Sisaki#include <sys/param.h> 421.1Sisaki#include <sys/systm.h> 431.1Sisaki#include <sys/mbuf.h> 441.1Sisaki#include <sys/socket.h> 451.1Sisaki#include <sys/select.h> 461.1Sisaki#include <sys/device.h> 471.1Sisaki 481.1Sisaki#include <net/if.h> 491.1Sisaki#include <net/if_dl.h> 501.1Sisaki#include <net/if_ether.h> 511.1Sisaki#include <net/if_media.h> 521.1Sisaki 531.1Sisaki#ifdef INET 541.1Sisaki#include <netinet/in.h> 551.1Sisaki#include <netinet/in_systm.h> 561.1Sisaki#include <netinet/in_var.h> 571.1Sisaki#include <netinet/ip.h> 581.1Sisaki#include <netinet/if_inarp.h> 591.1Sisaki#endif 601.1Sisaki 611.1Sisaki#ifdef NS 621.1Sisaki#include <netns/ns.h> 631.1Sisaki#include <netns/ns_if.h> 641.1Sisaki#endif 651.1Sisaki 661.1Sisaki#if BPFILTER > 0 671.1Sisaki#include <net/bpf.h> 681.1Sisaki#include <net/bpfdesc.h> 691.1Sisaki#endif 701.1Sisaki 711.1Sisaki#include <machine/bus.h> 721.1Sisaki#include <machine/cpu.h> 731.1Sisaki 741.1Sisaki#include <dev/ic/dp8390reg.h> 751.1Sisaki#include <dev/ic/dp8390var.h> 761.1Sisaki#include <dev/ic/ne2000reg.h> 771.1Sisaki#include <dev/ic/ne2000var.h> 781.1Sisaki#include <dev/ic/rtl80x9reg.h> 791.1Sisaki#include <dev/ic/rtl80x9var.h> 801.1Sisaki 811.1Sisaki#include <arch/x68k/dev/intiovar.h> 821.1Sisaki 831.2Sisaki#define NE_INTIO_ADDR (0xece300) 841.2Sisaki#define NE_INTIO_ADDR2 (0xeceb00) 851.2Sisaki#define NE_INTIO_INTR (0xf9) 861.2Sisaki#define NE_INTIO_INTR2 (0xf8) 871.1Sisaki 881.1Sisakistatic int ne_intio_match(struct device *, struct cfdata *, void *); 891.1Sisakistatic void ne_intio_attach(struct device *, struct device *, void *); 901.1Sisakistatic int ne_intio_intr(void *); 911.1Sisaki 921.1Sisaki#define ne_intio_softc ne2000_softc 931.1Sisaki 941.4SthorpejCFATTACH_DECL(ne_intio, sizeof(struct ne_intio_softc), 951.5Sthorpej ne_intio_match, ne_intio_attach, NULL, NULL); 961.1Sisaki 971.1Sisakistatic int 981.1Sisakine_intio_match(struct device *parent, struct cfdata *cf, void *aux) 991.1Sisaki{ 1001.1Sisaki struct intio_attach_args *ia = aux; 1011.1Sisaki bus_space_tag_t iot = ia->ia_bst; 1021.1Sisaki bus_space_handle_t ioh; 1031.1Sisaki bus_space_tag_t asict; 1041.1Sisaki bus_space_handle_t asich; 1051.1Sisaki int rv = 0; 1061.1Sisaki 1071.1Sisaki if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 1081.1Sisaki ia->ia_addr = NE_INTIO_ADDR; 1091.1Sisaki if (ia->ia_intr == INTIOCF_INTR_DEFAULT) 1101.1Sisaki ia->ia_intr = NE_INTIO_INTR; 1111.1Sisaki 1121.1Sisaki /* fixed parameters */ 1131.2Sisaki if (!(ia->ia_addr == NE_INTIO_ADDR && ia->ia_intr == NE_INTIO_INTR ) && 1141.2Sisaki !(ia->ia_addr == NE_INTIO_ADDR2 && ia->ia_intr == NE_INTIO_INTR2) ) 1151.1Sisaki return 0; 1161.1Sisaki 1171.1Sisaki /* Make sure this is a valid NE2000 I/O address */ 1181.1Sisaki if ((ia->ia_addr & 0x1f) != 0) 1191.1Sisaki return 0; 1201.1Sisaki 1211.1Sisaki /* Check whether the board is inserted or not */ 1221.1Sisaki if (badaddr((caddr_t)INTIO_ADDR(ia->ia_addr))) 1231.1Sisaki return 0; 1241.1Sisaki 1251.1Sisaki /* Map I/O space */ 1261.1Sisaki if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, 1271.1Sisaki BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)) 1281.1Sisaki return 0; 1291.1Sisaki 1301.1Sisaki asict = iot; 1311.1Sisaki if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, 1321.1Sisaki NE2000_ASIC_NPORTS*2, &asich)) 1331.1Sisaki goto out; 1341.1Sisaki 1351.1Sisaki /* Look for an NE2000 compatible card */ 1361.1Sisaki rv = ne2000_detect(iot, ioh, asict, asich); 1371.1Sisaki 1381.1Sisaki out: 1391.1Sisaki bus_space_unmap(iot, ioh, NE2000_NPORTS); 1401.1Sisaki return rv; 1411.1Sisaki} 1421.1Sisaki 1431.1Sisakistatic void 1441.1Sisakine_intio_attach(struct device *parent, struct device *self, void *aux) 1451.1Sisaki{ 1461.1Sisaki struct ne_intio_softc *sc = (struct ne_intio_softc *)self; 1471.1Sisaki struct dp8390_softc *dsc = &sc->sc_dp8390; 1481.1Sisaki struct intio_attach_args *ia = aux; 1491.1Sisaki bus_space_tag_t iot = ia->ia_bst; 1501.1Sisaki bus_space_handle_t ioh; 1511.1Sisaki bus_space_tag_t asict; 1521.1Sisaki bus_space_handle_t asich; 1531.1Sisaki const char *typestr; 1541.1Sisaki int netype; 1551.1Sisaki 1561.1Sisaki printf(": Nereid Ethernet\n"); 1571.1Sisaki 1581.1Sisaki /* Map I/O space */ 1591.1Sisaki if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, 1601.1Sisaki BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)){ 1611.1Sisaki printf("%s: can't map I/O space\n", dsc->sc_dev.dv_xname); 1621.1Sisaki return; 1631.1Sisaki } 1641.1Sisaki 1651.1Sisaki asict = iot; 1661.1Sisaki if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, 1671.1Sisaki NE2000_ASIC_NPORTS*2, &asich)) { 1681.1Sisaki printf("%s: can't subregion I/O space\n", dsc->sc_dev.dv_xname); 1691.1Sisaki return; 1701.1Sisaki } 1711.1Sisaki 1721.1Sisaki dsc->sc_regt = iot; 1731.1Sisaki dsc->sc_regh = ioh; 1741.1Sisaki 1751.1Sisaki sc->sc_asict = asict; 1761.1Sisaki sc->sc_asich = asich; 1771.1Sisaki 1781.1Sisaki /* 1791.1Sisaki * detect it again, so we can print some information about 1801.1Sisaki * the interface. 1811.1Sisaki * XXX: Should I check NE1000 or NE2000 for Nereid? 1821.1Sisaki */ 1831.1Sisaki netype = ne2000_detect(iot, ioh, asict, asich); 1841.1Sisaki switch (netype) { 1851.1Sisaki case NE2000_TYPE_NE1000: 1861.1Sisaki typestr = "NE1000"; 1871.1Sisaki break; 1881.1Sisaki 1891.1Sisaki case NE2000_TYPE_NE2000: 1901.1Sisaki typestr = "NE2000"; 1911.1Sisaki /* 1921.8Swiz * Check for a Realtek 8019. 1931.1Sisaki */ 1941.1Sisaki bus_space_write_1(iot, ioh, ED_P0_CR, 1951.1Sisaki ED_CR_PAGE_0 | ED_CR_STP); 1961.1Sisaki if (bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID0) == 1971.1Sisaki RTL0_8019ID0 && 1981.1Sisaki bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID1) == 1991.1Sisaki RTL0_8019ID1) { 2001.1Sisaki typestr = "NE2000 (RTL8019)"; 2011.1Sisaki dsc->sc_mediachange = rtl80x9_mediachange; 2021.1Sisaki dsc->sc_mediastatus = rtl80x9_mediastatus; 2031.1Sisaki dsc->init_card = rtl80x9_init_card; 2041.1Sisaki dsc->sc_media_init = rtl80x9_media_init; 2051.1Sisaki } 2061.1Sisaki break; 2071.1Sisaki 2081.1Sisaki default: 2091.1Sisaki printf("%s: where did the card go?!\n", dsc->sc_dev.dv_xname); 2101.1Sisaki return; 2111.1Sisaki } 2121.1Sisaki 2131.1Sisaki printf("%s: %s Ethernet\n", dsc->sc_dev.dv_xname, typestr); 2141.1Sisaki 2151.1Sisaki /* This interface is always enabled */ 2161.1Sisaki dsc->sc_enabled = 1; 2171.1Sisaki 2181.1Sisaki /* 2191.1Sisaki * Do generic NE2000 attach. 2201.1Sisaki * This will read the mac address from the EEPROM. 2211.1Sisaki */ 2221.1Sisaki ne2000_attach(sc, NULL); 2231.1Sisaki 2241.1Sisaki /* Establish the interrupt handler */ 2251.1Sisaki if (intio_intr_establish(ia->ia_intr, "ne", ne_intio_intr, dsc)) 2261.1Sisaki printf("%s: couldn't establish interrupt handler\n", 2271.1Sisaki dsc->sc_dev.dv_xname); 2281.1Sisaki} 2291.1Sisaki 2301.1Sisakistatic int 2311.1Sisakine_intio_intr(void *arg) 2321.1Sisaki{ 2331.1Sisaki int error; 2341.1Sisaki int s; 2351.1Sisaki 2361.1Sisaki s = splnet(); 2371.1Sisaki error = dp8390_intr(arg); 2381.1Sisaki splx(s); 2391.1Sisaki return error; 2401.1Sisaki} 241