if_ne_intio.c revision 1.6
1/* $NetBSD: if_ne_intio.c,v 1.6 2003/07/15 01:44:51 lukem Exp $ */ 2 3/* 4 * Copyright (c) 2001 Tetsuya Isaki. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Tetsuya Isaki. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33/* 34 * Ethernet part of Nereid Ethernet/USB/Memory board 35 */ 36 37#include <sys/cdefs.h> 38__KERNEL_RCSID(0, "$NetBSD: if_ne_intio.c,v 1.6 2003/07/15 01:44:51 lukem Exp $"); 39 40#include "opt_inet.h" 41#include "opt_ns.h" 42#include "bpfilter.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/mbuf.h> 47#include <sys/socket.h> 48#include <sys/select.h> 49#include <sys/device.h> 50 51#include <net/if.h> 52#include <net/if_dl.h> 53#include <net/if_ether.h> 54#include <net/if_media.h> 55 56#ifdef INET 57#include <netinet/in.h> 58#include <netinet/in_systm.h> 59#include <netinet/in_var.h> 60#include <netinet/ip.h> 61#include <netinet/if_inarp.h> 62#endif 63 64#ifdef NS 65#include <netns/ns.h> 66#include <netns/ns_if.h> 67#endif 68 69#if BPFILTER > 0 70#include <net/bpf.h> 71#include <net/bpfdesc.h> 72#endif 73 74#include <machine/bus.h> 75#include <machine/cpu.h> 76 77#include <dev/ic/dp8390reg.h> 78#include <dev/ic/dp8390var.h> 79#include <dev/ic/ne2000reg.h> 80#include <dev/ic/ne2000var.h> 81#include <dev/ic/rtl80x9reg.h> 82#include <dev/ic/rtl80x9var.h> 83 84#include <arch/x68k/dev/intiovar.h> 85 86#define NE_INTIO_ADDR (0xece300) 87#define NE_INTIO_ADDR2 (0xeceb00) 88#define NE_INTIO_INTR (0xf9) 89#define NE_INTIO_INTR2 (0xf8) 90 91static int ne_intio_match(struct device *, struct cfdata *, void *); 92static void ne_intio_attach(struct device *, struct device *, void *); 93static int ne_intio_intr(void *); 94 95#define ne_intio_softc ne2000_softc 96 97CFATTACH_DECL(ne_intio, sizeof(struct ne_intio_softc), 98 ne_intio_match, ne_intio_attach, NULL, NULL); 99 100static int 101ne_intio_match(struct device *parent, struct cfdata *cf, void *aux) 102{ 103 struct intio_attach_args *ia = aux; 104 bus_space_tag_t iot = ia->ia_bst; 105 bus_space_handle_t ioh; 106 bus_space_tag_t asict; 107 bus_space_handle_t asich; 108 int rv = 0; 109 110 if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 111 ia->ia_addr = NE_INTIO_ADDR; 112 if (ia->ia_intr == INTIOCF_INTR_DEFAULT) 113 ia->ia_intr = NE_INTIO_INTR; 114 115 /* fixed parameters */ 116 if (!(ia->ia_addr == NE_INTIO_ADDR && ia->ia_intr == NE_INTIO_INTR ) && 117 !(ia->ia_addr == NE_INTIO_ADDR2 && ia->ia_intr == NE_INTIO_INTR2) ) 118 return 0; 119 120 /* Make sure this is a valid NE2000 I/O address */ 121 if ((ia->ia_addr & 0x1f) != 0) 122 return 0; 123 124 /* Check whether the board is inserted or not */ 125 if (badaddr((caddr_t)INTIO_ADDR(ia->ia_addr))) 126 return 0; 127 128 /* Map I/O space */ 129 if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, 130 BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)) 131 return 0; 132 133 asict = iot; 134 if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, 135 NE2000_ASIC_NPORTS*2, &asich)) 136 goto out; 137 138 /* Look for an NE2000 compatible card */ 139 rv = ne2000_detect(iot, ioh, asict, asich); 140 141 out: 142 bus_space_unmap(iot, ioh, NE2000_NPORTS); 143 return rv; 144} 145 146static void 147ne_intio_attach(struct device *parent, struct device *self, void *aux) 148{ 149 struct ne_intio_softc *sc = (struct ne_intio_softc *)self; 150 struct dp8390_softc *dsc = &sc->sc_dp8390; 151 struct intio_attach_args *ia = aux; 152 bus_space_tag_t iot = ia->ia_bst; 153 bus_space_handle_t ioh; 154 bus_space_tag_t asict; 155 bus_space_handle_t asich; 156 const char *typestr; 157 int netype; 158 159 printf(": Nereid Ethernet\n"); 160 161 /* Map I/O space */ 162 if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, 163 BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)){ 164 printf("%s: can't map I/O space\n", dsc->sc_dev.dv_xname); 165 return; 166 } 167 168 asict = iot; 169 if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, 170 NE2000_ASIC_NPORTS*2, &asich)) { 171 printf("%s: can't subregion I/O space\n", dsc->sc_dev.dv_xname); 172 return; 173 } 174 175 dsc->sc_regt = iot; 176 dsc->sc_regh = ioh; 177 178 sc->sc_asict = asict; 179 sc->sc_asich = asich; 180 181 /* 182 * detect it again, so we can print some information about 183 * the interface. 184 * XXX: Should I check NE1000 or NE2000 for Nereid? 185 */ 186 netype = ne2000_detect(iot, ioh, asict, asich); 187 switch (netype) { 188 case NE2000_TYPE_NE1000: 189 typestr = "NE1000"; 190 break; 191 192 case NE2000_TYPE_NE2000: 193 typestr = "NE2000"; 194 /* 195 * Check for a RealTek 8019. 196 */ 197 bus_space_write_1(iot, ioh, ED_P0_CR, 198 ED_CR_PAGE_0 | ED_CR_STP); 199 if (bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID0) == 200 RTL0_8019ID0 && 201 bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID1) == 202 RTL0_8019ID1) { 203 typestr = "NE2000 (RTL8019)"; 204 dsc->sc_mediachange = rtl80x9_mediachange; 205 dsc->sc_mediastatus = rtl80x9_mediastatus; 206 dsc->init_card = rtl80x9_init_card; 207 dsc->sc_media_init = rtl80x9_media_init; 208 } 209 break; 210 211 default: 212 printf("%s: where did the card go?!\n", dsc->sc_dev.dv_xname); 213 return; 214 } 215 216 printf("%s: %s Ethernet\n", dsc->sc_dev.dv_xname, typestr); 217 218 /* This interface is always enabled */ 219 dsc->sc_enabled = 1; 220 221 /* 222 * Do generic NE2000 attach. 223 * This will read the mac address from the EEPROM. 224 */ 225 ne2000_attach(sc, NULL); 226 227 /* Establish the interrupt handler */ 228 if (intio_intr_establish(ia->ia_intr, "ne", ne_intio_intr, dsc)) 229 printf("%s: couldn't establish interrupt handler\n", 230 dsc->sc_dev.dv_xname); 231} 232 233static int 234ne_intio_intr(void *arg) 235{ 236 int error; 237 int s; 238 239 s = splnet(); 240 error = dp8390_intr(arg); 241 splx(s); 242 return error; 243} 244