if_ne_intio.c revision 1.16
11.16Stsutsui/* $NetBSD: if_ne_intio.c,v 1.16 2010/03/03 13:39:57 tsutsui 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.16Stsutsui__KERNEL_RCSID(0, "$NetBSD: if_ne_intio.c,v 1.16 2010/03/03 13:39:57 tsutsui Exp $"); 361.1Sisaki 371.1Sisaki#include "opt_inet.h" 381.1Sisaki#include "opt_ns.h" 391.1Sisaki 401.1Sisaki#include <sys/param.h> 411.1Sisaki#include <sys/systm.h> 421.1Sisaki#include <sys/mbuf.h> 431.1Sisaki#include <sys/socket.h> 441.1Sisaki#include <sys/select.h> 451.1Sisaki#include <sys/device.h> 461.1Sisaki 471.1Sisaki#include <net/if.h> 481.1Sisaki#include <net/if_dl.h> 491.1Sisaki#include <net/if_ether.h> 501.1Sisaki#include <net/if_media.h> 511.1Sisaki 521.1Sisaki#ifdef INET 531.1Sisaki#include <netinet/in.h> 541.1Sisaki#include <netinet/in_systm.h> 551.1Sisaki#include <netinet/in_var.h> 561.1Sisaki#include <netinet/ip.h> 571.1Sisaki#include <netinet/if_inarp.h> 581.1Sisaki#endif 591.1Sisaki 601.1Sisaki#ifdef NS 611.1Sisaki#include <netns/ns.h> 621.1Sisaki#include <netns/ns_if.h> 631.1Sisaki#endif 641.1Sisaki 651.1Sisaki#if BPFILTER > 0 661.1Sisaki#include <net/bpf.h> 671.1Sisaki#include <net/bpfdesc.h> 681.1Sisaki#endif 691.1Sisaki 701.1Sisaki#include <machine/bus.h> 711.1Sisaki#include <machine/cpu.h> 721.1Sisaki 731.1Sisaki#include <dev/ic/dp8390reg.h> 741.1Sisaki#include <dev/ic/dp8390var.h> 751.1Sisaki#include <dev/ic/ne2000reg.h> 761.1Sisaki#include <dev/ic/ne2000var.h> 771.1Sisaki 781.1Sisaki#include <arch/x68k/dev/intiovar.h> 791.1Sisaki 801.2Sisaki#define NE_INTIO_ADDR (0xece300) 811.2Sisaki#define NE_INTIO_ADDR2 (0xeceb00) 821.2Sisaki#define NE_INTIO_INTR (0xf9) 831.2Sisaki#define NE_INTIO_INTR2 (0xf8) 841.1Sisaki 851.11Stsutsuistatic int ne_intio_match(device_t, cfdata_t, void *); 861.11Stsutsuistatic void ne_intio_attach(device_t, device_t, void *); 871.1Sisaki 881.1Sisaki#define ne_intio_softc ne2000_softc 891.1Sisaki 901.11StsutsuiCFATTACH_DECL_NEW(ne_intio, sizeof(struct ne_intio_softc), 911.5Sthorpej ne_intio_match, ne_intio_attach, NULL, NULL); 921.1Sisaki 931.1Sisakistatic int 941.11Stsutsuine_intio_match(device_t parent, cfdata_t cf, void *aux) 951.1Sisaki{ 961.1Sisaki struct intio_attach_args *ia = aux; 971.1Sisaki bus_space_tag_t iot = ia->ia_bst; 981.1Sisaki bus_space_handle_t ioh; 991.1Sisaki bus_space_tag_t asict; 1001.1Sisaki bus_space_handle_t asich; 1011.1Sisaki int rv = 0; 1021.1Sisaki 1031.1Sisaki if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 1041.1Sisaki ia->ia_addr = NE_INTIO_ADDR; 1051.1Sisaki if (ia->ia_intr == INTIOCF_INTR_DEFAULT) 1061.1Sisaki ia->ia_intr = NE_INTIO_INTR; 1071.1Sisaki 1081.1Sisaki /* fixed parameters */ 1091.2Sisaki if (!(ia->ia_addr == NE_INTIO_ADDR && ia->ia_intr == NE_INTIO_INTR ) && 1101.2Sisaki !(ia->ia_addr == NE_INTIO_ADDR2 && ia->ia_intr == NE_INTIO_INTR2) ) 1111.1Sisaki return 0; 1121.1Sisaki 1131.1Sisaki /* Make sure this is a valid NE2000 I/O address */ 1141.1Sisaki if ((ia->ia_addr & 0x1f) != 0) 1151.1Sisaki return 0; 1161.1Sisaki 1171.1Sisaki /* Check whether the board is inserted or not */ 1181.12Sisaki if (badaddr((void *)IIOV(ia->ia_addr))) 1191.1Sisaki return 0; 1201.1Sisaki 1211.1Sisaki /* Map I/O space */ 1221.1Sisaki if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, 1231.1Sisaki BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)) 1241.1Sisaki return 0; 1251.1Sisaki 1261.1Sisaki asict = iot; 1271.1Sisaki if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, 1281.1Sisaki NE2000_ASIC_NPORTS*2, &asich)) 1291.1Sisaki goto out; 1301.1Sisaki 1311.1Sisaki /* Look for an NE2000 compatible card */ 1321.1Sisaki rv = ne2000_detect(iot, ioh, asict, asich); 1331.1Sisaki 1341.1Sisaki out: 1351.1Sisaki bus_space_unmap(iot, ioh, NE2000_NPORTS); 1361.14Sisaki return (rv != 0) ? 1 : 0; 1371.1Sisaki} 1381.1Sisaki 1391.1Sisakistatic void 1401.11Stsutsuine_intio_attach(device_t parent, device_t self, void *aux) 1411.1Sisaki{ 1421.11Stsutsui struct ne_intio_softc *sc = device_private(self); 1431.1Sisaki struct dp8390_softc *dsc = &sc->sc_dp8390; 1441.1Sisaki struct intio_attach_args *ia = aux; 1451.1Sisaki bus_space_tag_t iot = ia->ia_bst; 1461.1Sisaki bus_space_handle_t ioh; 1471.1Sisaki bus_space_tag_t asict; 1481.1Sisaki bus_space_handle_t asich; 1491.1Sisaki const char *typestr; 1501.1Sisaki int netype; 1511.1Sisaki 1521.11Stsutsui dsc->sc_dev = self; 1531.11Stsutsui aprint_normal(": Nereid Ethernet\n"); 1541.1Sisaki 1551.1Sisaki /* Map I/O space */ 1561.1Sisaki if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, 1571.1Sisaki BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)){ 1581.11Stsutsui aprint_error_dev(self, "can't map I/O space\n"); 1591.1Sisaki return; 1601.1Sisaki } 1611.1Sisaki 1621.1Sisaki asict = iot; 1631.1Sisaki if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, 1641.1Sisaki NE2000_ASIC_NPORTS*2, &asich)) { 1651.11Stsutsui aprint_error_dev(self, "can't subregion I/O space\n"); 1661.1Sisaki return; 1671.1Sisaki } 1681.1Sisaki 1691.1Sisaki dsc->sc_regt = iot; 1701.1Sisaki dsc->sc_regh = ioh; 1711.1Sisaki 1721.1Sisaki sc->sc_asict = asict; 1731.1Sisaki sc->sc_asich = asich; 1741.1Sisaki 1751.1Sisaki /* 1761.1Sisaki * detect it again, so we can print some information about 1771.1Sisaki * the interface. 1781.1Sisaki * XXX: Should I check NE1000 or NE2000 for Nereid? 1791.1Sisaki */ 1801.1Sisaki netype = ne2000_detect(iot, ioh, asict, asich); 1811.1Sisaki switch (netype) { 1821.1Sisaki case NE2000_TYPE_NE1000: 1831.1Sisaki typestr = "NE1000"; 1841.1Sisaki break; 1851.1Sisaki 1861.1Sisaki case NE2000_TYPE_NE2000: 1871.1Sisaki typestr = "NE2000"; 1881.16Stsutsui break; 1891.16Stsutsui 1901.16Stsutsui case NE2000_TYPE_RTL8019: 1911.16Stsutsui typestr = "NE2000 (RTL8019)"; 1921.1Sisaki break; 1931.1Sisaki 1941.1Sisaki default: 1951.11Stsutsui aprint_error_dev(self, "where did the card go?!\n"); 1961.1Sisaki return; 1971.1Sisaki } 1981.1Sisaki 1991.11Stsutsui aprint_normal_dev(self, "%s Ethernet\n", typestr); 2001.1Sisaki 2011.1Sisaki /* This interface is always enabled */ 2021.1Sisaki dsc->sc_enabled = 1; 2031.1Sisaki 2041.1Sisaki /* 2051.1Sisaki * Do generic NE2000 attach. 2061.1Sisaki * This will read the mac address from the EEPROM. 2071.1Sisaki */ 2081.1Sisaki ne2000_attach(sc, NULL); 2091.1Sisaki 2101.1Sisaki /* Establish the interrupt handler */ 2111.13Sisaki if (intio_intr_establish(ia->ia_intr, "ne", dp8390_intr, dsc)) 2121.11Stsutsui aprint_error_dev(self, 2131.11Stsutsui "couldn't establish interrupt handler\n"); 2141.1Sisaki} 215