if_ne_intio.c revision 1.20
11.20Sisaki/* $NetBSD: if_ne_intio.c,v 1.20 2024/01/06 05:16:57 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.1Sisaki * 151.1Sisaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161.1Sisaki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171.1Sisaki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181.1Sisaki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191.1Sisaki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 201.1Sisaki * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 211.1Sisaki * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 221.1Sisaki * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 231.1Sisaki * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 241.1Sisaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 251.1Sisaki * SUCH DAMAGE. 261.1Sisaki */ 271.1Sisaki 281.1Sisaki/* 291.1Sisaki * Ethernet part of Nereid Ethernet/USB/Memory board 301.1Sisaki */ 311.6Slukem 321.6Slukem#include <sys/cdefs.h> 331.20Sisaki__KERNEL_RCSID(0, "$NetBSD: if_ne_intio.c,v 1.20 2024/01/06 05:16:57 isaki Exp $"); 341.1Sisaki 351.1Sisaki#include "opt_inet.h" 361.1Sisaki#include "opt_ns.h" 371.1Sisaki 381.1Sisaki#include <sys/param.h> 391.1Sisaki#include <sys/systm.h> 401.1Sisaki#include <sys/mbuf.h> 411.1Sisaki#include <sys/socket.h> 421.1Sisaki#include <sys/select.h> 431.1Sisaki#include <sys/device.h> 441.1Sisaki 451.1Sisaki#include <net/if.h> 461.1Sisaki#include <net/if_dl.h> 471.1Sisaki#include <net/if_ether.h> 481.1Sisaki#include <net/if_media.h> 491.1Sisaki 501.1Sisaki#ifdef INET 511.1Sisaki#include <netinet/in.h> 521.1Sisaki#include <netinet/in_systm.h> 531.1Sisaki#include <netinet/in_var.h> 541.1Sisaki#include <netinet/ip.h> 551.1Sisaki#include <netinet/if_inarp.h> 561.1Sisaki#endif 571.1Sisaki 581.1Sisaki#if BPFILTER > 0 591.1Sisaki#include <net/bpf.h> 601.1Sisaki#endif 611.1Sisaki 621.1Sisaki#include <machine/bus.h> 631.1Sisaki#include <machine/cpu.h> 641.1Sisaki 651.1Sisaki#include <dev/ic/dp8390reg.h> 661.1Sisaki#include <dev/ic/dp8390var.h> 671.1Sisaki#include <dev/ic/ne2000reg.h> 681.1Sisaki#include <dev/ic/ne2000var.h> 691.1Sisaki 701.1Sisaki#include <arch/x68k/dev/intiovar.h> 711.1Sisaki 721.2Sisaki#define NE_INTIO_ADDR (0xece300) 731.2Sisaki#define NE_INTIO_ADDR2 (0xeceb00) 741.2Sisaki#define NE_INTIO_INTR (0xf9) 751.2Sisaki#define NE_INTIO_INTR2 (0xf8) 761.1Sisaki 771.11Stsutsuistatic int ne_intio_match(device_t, cfdata_t, void *); 781.11Stsutsuistatic void ne_intio_attach(device_t, device_t, void *); 791.1Sisaki 801.1Sisaki#define ne_intio_softc ne2000_softc 811.1Sisaki 821.11StsutsuiCFATTACH_DECL_NEW(ne_intio, sizeof(struct ne_intio_softc), 831.5Sthorpej ne_intio_match, ne_intio_attach, NULL, NULL); 841.1Sisaki 851.1Sisakistatic int 861.11Stsutsuine_intio_match(device_t parent, cfdata_t cf, void *aux) 871.1Sisaki{ 881.1Sisaki struct intio_attach_args *ia = aux; 891.1Sisaki bus_space_tag_t iot = ia->ia_bst; 901.1Sisaki bus_space_handle_t ioh; 911.1Sisaki bus_space_tag_t asict; 921.1Sisaki bus_space_handle_t asich; 931.1Sisaki int rv = 0; 941.1Sisaki 951.1Sisaki if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 961.1Sisaki ia->ia_addr = NE_INTIO_ADDR; 971.1Sisaki if (ia->ia_intr == INTIOCF_INTR_DEFAULT) 981.1Sisaki ia->ia_intr = NE_INTIO_INTR; 991.1Sisaki 1001.1Sisaki /* fixed parameters */ 1011.2Sisaki if (!(ia->ia_addr == NE_INTIO_ADDR && ia->ia_intr == NE_INTIO_INTR ) && 1021.2Sisaki !(ia->ia_addr == NE_INTIO_ADDR2 && ia->ia_intr == NE_INTIO_INTR2) ) 1031.1Sisaki return 0; 1041.1Sisaki 1051.1Sisaki /* Make sure this is a valid NE2000 I/O address */ 1061.1Sisaki if ((ia->ia_addr & 0x1f) != 0) 1071.1Sisaki return 0; 1081.1Sisaki 1091.1Sisaki /* Check whether the board is inserted or not */ 1101.12Sisaki if (badaddr((void *)IIOV(ia->ia_addr))) 1111.1Sisaki return 0; 1121.1Sisaki 1131.1Sisaki /* Map I/O space */ 1141.20Sisaki if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS * 2, 1151.1Sisaki BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)) 1161.1Sisaki return 0; 1171.1Sisaki 1181.1Sisaki asict = iot; 1191.20Sisaki if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET * 2, 1201.20Sisaki NE2000_ASIC_NPORTS * 2, &asich)) 1211.1Sisaki goto out; 1221.1Sisaki 1231.1Sisaki /* Look for an NE2000 compatible card */ 1241.1Sisaki rv = ne2000_detect(iot, ioh, asict, asich); 1251.1Sisaki 1261.1Sisaki out: 1271.1Sisaki bus_space_unmap(iot, ioh, NE2000_NPORTS); 1281.14Sisaki return (rv != 0) ? 1 : 0; 1291.1Sisaki} 1301.1Sisaki 1311.1Sisakistatic void 1321.11Stsutsuine_intio_attach(device_t parent, device_t self, void *aux) 1331.1Sisaki{ 1341.11Stsutsui struct ne_intio_softc *sc = device_private(self); 1351.1Sisaki struct dp8390_softc *dsc = &sc->sc_dp8390; 1361.1Sisaki struct intio_attach_args *ia = aux; 1371.1Sisaki bus_space_tag_t iot = ia->ia_bst; 1381.1Sisaki bus_space_handle_t ioh; 1391.1Sisaki bus_space_tag_t asict; 1401.1Sisaki bus_space_handle_t asich; 1411.1Sisaki const char *typestr; 1421.1Sisaki int netype; 1431.1Sisaki 1441.11Stsutsui dsc->sc_dev = self; 1451.11Stsutsui aprint_normal(": Nereid Ethernet\n"); 1461.1Sisaki 1471.1Sisaki /* Map I/O space */ 1481.20Sisaki if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS * 2, 1491.20Sisaki BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)) { 1501.11Stsutsui aprint_error_dev(self, "can't map I/O space\n"); 1511.1Sisaki return; 1521.1Sisaki } 1531.1Sisaki 1541.1Sisaki asict = iot; 1551.20Sisaki if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET * 2, 1561.20Sisaki NE2000_ASIC_NPORTS * 2, &asich)) { 1571.11Stsutsui aprint_error_dev(self, "can't subregion I/O space\n"); 1581.1Sisaki return; 1591.1Sisaki } 1601.1Sisaki 1611.1Sisaki dsc->sc_regt = iot; 1621.1Sisaki dsc->sc_regh = ioh; 1631.1Sisaki 1641.1Sisaki sc->sc_asict = asict; 1651.1Sisaki sc->sc_asich = asich; 1661.1Sisaki 1671.1Sisaki /* 1681.1Sisaki * detect it again, so we can print some information about 1691.1Sisaki * the interface. 1701.1Sisaki * XXX: Should I check NE1000 or NE2000 for Nereid? 1711.1Sisaki */ 1721.1Sisaki netype = ne2000_detect(iot, ioh, asict, asich); 1731.1Sisaki switch (netype) { 1741.1Sisaki case NE2000_TYPE_NE1000: 1751.1Sisaki typestr = "NE1000"; 1761.1Sisaki break; 1771.1Sisaki 1781.1Sisaki case NE2000_TYPE_NE2000: 1791.1Sisaki typestr = "NE2000"; 1801.16Stsutsui break; 1811.16Stsutsui 1821.16Stsutsui case NE2000_TYPE_RTL8019: 1831.16Stsutsui typestr = "NE2000 (RTL8019)"; 1841.1Sisaki break; 1851.1Sisaki 1861.1Sisaki default: 1871.11Stsutsui aprint_error_dev(self, "where did the card go?!\n"); 1881.1Sisaki return; 1891.1Sisaki } 1901.1Sisaki 1911.11Stsutsui aprint_normal_dev(self, "%s Ethernet\n", typestr); 1921.1Sisaki 1931.1Sisaki /* This interface is always enabled */ 1941.1Sisaki dsc->sc_enabled = 1; 1951.1Sisaki 1961.1Sisaki /* 1971.1Sisaki * Do generic NE2000 attach. 1981.1Sisaki * This will read the mac address from the EEPROM. 1991.1Sisaki */ 2001.1Sisaki ne2000_attach(sc, NULL); 2011.1Sisaki 2021.1Sisaki /* Establish the interrupt handler */ 2031.13Sisaki if (intio_intr_establish(ia->ia_intr, "ne", dp8390_intr, dsc)) 2041.11Stsutsui aprint_error_dev(self, 2051.11Stsutsui "couldn't establish interrupt handler\n"); 2061.1Sisaki} 207