if_ne_intio.c revision 1.13
11.13Sisaki/* $NetBSD: if_ne_intio.c,v 1.13 2009/01/18 04:48:53 isaki 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.13Sisaki__KERNEL_RCSID(0, "$NetBSD: if_ne_intio.c,v 1.13 2009/01/18 04:48:53 isaki 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.11Stsutsuistatic int ne_intio_match(device_t, cfdata_t, void *); 891.11Stsutsuistatic void ne_intio_attach(device_t, device_t, void *); 901.1Sisaki 911.1Sisaki#define ne_intio_softc ne2000_softc 921.1Sisaki 931.11StsutsuiCFATTACH_DECL_NEW(ne_intio, sizeof(struct ne_intio_softc), 941.5Sthorpej ne_intio_match, ne_intio_attach, NULL, NULL); 951.1Sisaki 961.1Sisakistatic int 971.11Stsutsuine_intio_match(device_t parent, cfdata_t cf, void *aux) 981.1Sisaki{ 991.1Sisaki struct intio_attach_args *ia = aux; 1001.1Sisaki bus_space_tag_t iot = ia->ia_bst; 1011.1Sisaki bus_space_handle_t ioh; 1021.1Sisaki bus_space_tag_t asict; 1031.1Sisaki bus_space_handle_t asich; 1041.1Sisaki int rv = 0; 1051.1Sisaki 1061.1Sisaki if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 1071.1Sisaki ia->ia_addr = NE_INTIO_ADDR; 1081.1Sisaki if (ia->ia_intr == INTIOCF_INTR_DEFAULT) 1091.1Sisaki ia->ia_intr = NE_INTIO_INTR; 1101.1Sisaki 1111.1Sisaki /* fixed parameters */ 1121.2Sisaki if (!(ia->ia_addr == NE_INTIO_ADDR && ia->ia_intr == NE_INTIO_INTR ) && 1131.2Sisaki !(ia->ia_addr == NE_INTIO_ADDR2 && ia->ia_intr == NE_INTIO_INTR2) ) 1141.1Sisaki return 0; 1151.1Sisaki 1161.1Sisaki /* Make sure this is a valid NE2000 I/O address */ 1171.1Sisaki if ((ia->ia_addr & 0x1f) != 0) 1181.1Sisaki return 0; 1191.1Sisaki 1201.1Sisaki /* Check whether the board is inserted or not */ 1211.12Sisaki if (badaddr((void *)IIOV(ia->ia_addr))) 1221.1Sisaki return 0; 1231.1Sisaki 1241.1Sisaki /* Map I/O space */ 1251.1Sisaki if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, 1261.1Sisaki BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)) 1271.1Sisaki return 0; 1281.1Sisaki 1291.1Sisaki asict = iot; 1301.1Sisaki if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, 1311.1Sisaki NE2000_ASIC_NPORTS*2, &asich)) 1321.1Sisaki goto out; 1331.1Sisaki 1341.1Sisaki /* Look for an NE2000 compatible card */ 1351.1Sisaki rv = ne2000_detect(iot, ioh, asict, asich); 1361.1Sisaki 1371.1Sisaki out: 1381.1Sisaki bus_space_unmap(iot, ioh, NE2000_NPORTS); 1391.1Sisaki return rv; 1401.1Sisaki} 1411.1Sisaki 1421.1Sisakistatic void 1431.11Stsutsuine_intio_attach(device_t parent, device_t self, void *aux) 1441.1Sisaki{ 1451.11Stsutsui struct ne_intio_softc *sc = device_private(self); 1461.1Sisaki struct dp8390_softc *dsc = &sc->sc_dp8390; 1471.1Sisaki struct intio_attach_args *ia = aux; 1481.1Sisaki bus_space_tag_t iot = ia->ia_bst; 1491.1Sisaki bus_space_handle_t ioh; 1501.1Sisaki bus_space_tag_t asict; 1511.1Sisaki bus_space_handle_t asich; 1521.1Sisaki const char *typestr; 1531.1Sisaki int netype; 1541.1Sisaki 1551.11Stsutsui dsc->sc_dev = self; 1561.11Stsutsui aprint_normal(": 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.11Stsutsui aprint_error_dev(self, "can't map I/O space\n"); 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.11Stsutsui aprint_error_dev(self, "can't subregion I/O space\n"); 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.11Stsutsui aprint_error_dev(self, "where did the card go?!\n"); 2101.1Sisaki return; 2111.1Sisaki } 2121.1Sisaki 2131.11Stsutsui aprint_normal_dev(self, "%s Ethernet\n", 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.13Sisaki if (intio_intr_establish(ia->ia_intr, "ne", dp8390_intr, dsc)) 2261.11Stsutsui aprint_error_dev(self, 2271.11Stsutsui "couldn't establish interrupt handler\n"); 2281.1Sisaki} 229