1*c111cdafSkiyohara /* $NetBSD: if_ne_mainbus.c,v 1.1 2011/02/19 10:46:28 kiyohara Exp $ */
2*c111cdafSkiyohara /*
3*c111cdafSkiyohara * Copyright (c) 2010 KIYOHARA Takashi
4*c111cdafSkiyohara * All rights reserved.
5*c111cdafSkiyohara *
6*c111cdafSkiyohara * Redistribution and use in source and binary forms, with or without
7*c111cdafSkiyohara * modification, are permitted provided that the following conditions
8*c111cdafSkiyohara * are met:
9*c111cdafSkiyohara * 1. Redistributions of source code must retain the above copyright
10*c111cdafSkiyohara * notice, this list of conditions and the following disclaimer.
11*c111cdafSkiyohara * 2. Redistributions in binary form must reproduce the above copyright
12*c111cdafSkiyohara * notice, this list of conditions and the following disclaimer in the
13*c111cdafSkiyohara * documentation and/or other materials provided with the distribution.
14*c111cdafSkiyohara *
15*c111cdafSkiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16*c111cdafSkiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17*c111cdafSkiyohara * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18*c111cdafSkiyohara * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19*c111cdafSkiyohara * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20*c111cdafSkiyohara * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21*c111cdafSkiyohara * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*c111cdafSkiyohara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23*c111cdafSkiyohara * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24*c111cdafSkiyohara * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25*c111cdafSkiyohara * POSSIBILITY OF SUCH DAMAGE.
26*c111cdafSkiyohara *
27*c111cdafSkiyohara */
28*c111cdafSkiyohara #include <sys/cdefs.h>
29*c111cdafSkiyohara __KERNEL_RCSID(0, "$NetBSD: if_ne_mainbus.c,v 1.1 2011/02/19 10:46:28 kiyohara Exp $");
30*c111cdafSkiyohara
31*c111cdafSkiyohara #include <sys/param.h>
32*c111cdafSkiyohara #include <sys/bus.h>
33*c111cdafSkiyohara #include <sys/device.h>
34*c111cdafSkiyohara #include <sys/errno.h>
35*c111cdafSkiyohara
36*c111cdafSkiyohara #include <machine/autoconf.h>
37*c111cdafSkiyohara #include <machine/intr.h>
38*c111cdafSkiyohara #include <machine/mmeye.h>
39*c111cdafSkiyohara
40*c111cdafSkiyohara #include <net/if.h>
41*c111cdafSkiyohara #include <net/if_dl.h>
42*c111cdafSkiyohara #include <net/if_ether.h>
43*c111cdafSkiyohara #include <net/if_media.h>
44*c111cdafSkiyohara
45*c111cdafSkiyohara #include <dev/ic/dp8390reg.h>
46*c111cdafSkiyohara #include <dev/ic/dp8390var.h>
47*c111cdafSkiyohara
48*c111cdafSkiyohara #include <dev/ic/ne2000reg.h>
49*c111cdafSkiyohara #include <dev/ic/ne2000var.h>
50*c111cdafSkiyohara
51*c111cdafSkiyohara #include "locators.h"
52*c111cdafSkiyohara
53*c111cdafSkiyohara static int ne_mainbus_match(device_t, cfdata_t , void *);
54*c111cdafSkiyohara static void ne_mainbus_attach(device_t, device_t, void *);
55*c111cdafSkiyohara
56*c111cdafSkiyohara CFATTACH_DECL_NEW(ne_mainbus, sizeof(struct ne2000_softc),
57*c111cdafSkiyohara ne_mainbus_match, ne_mainbus_attach, NULL, NULL);
58*c111cdafSkiyohara
59*c111cdafSkiyohara static int
ne_mainbus_match(device_t parent,cfdata_t match,void * aux)60*c111cdafSkiyohara ne_mainbus_match(device_t parent, cfdata_t match, void *aux)
61*c111cdafSkiyohara {
62*c111cdafSkiyohara struct mainbus_attach_args *ma = aux;
63*c111cdafSkiyohara bus_space_tag_t nict, asict;
64*c111cdafSkiyohara bus_space_handle_t nich, asich;
65*c111cdafSkiyohara int rv = 0;
66*c111cdafSkiyohara
67*c111cdafSkiyohara if (strcmp(ma->ma_name, match->cf_name) != 0)
68*c111cdafSkiyohara return 0;
69*c111cdafSkiyohara
70*c111cdafSkiyohara /* Disallow wildcarded values. */
71*c111cdafSkiyohara if (ma->ma_addr1 == MAINBUSCF_ADDR1_DEFAULT ||
72*c111cdafSkiyohara ma->ma_irq1 == MAINBUSCF_IRQ1_DEFAULT)
73*c111cdafSkiyohara return 0;
74*c111cdafSkiyohara
75*c111cdafSkiyohara /* Make sure this is a valid NE[12]000 i/o address. */
76*c111cdafSkiyohara if ((ma->ma_addr1 & 0x1f) != 0)
77*c111cdafSkiyohara return 0;
78*c111cdafSkiyohara
79*c111cdafSkiyohara /* Map i/o space. */
80*c111cdafSkiyohara nict = SH3_BUS_SPACE_PCMCIA_IO;
81*c111cdafSkiyohara if (bus_space_map(nict, ma->ma_addr1, NE2000_NPORTS, 0, &nich))
82*c111cdafSkiyohara return 0;
83*c111cdafSkiyohara
84*c111cdafSkiyohara if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
85*c111cdafSkiyohara NE2000_ASIC_NPORTS, &asich))
86*c111cdafSkiyohara goto out;
87*c111cdafSkiyohara asict = nict;
88*c111cdafSkiyohara
89*c111cdafSkiyohara /* Look for an NE2000-compatible card. */
90*c111cdafSkiyohara rv = ne2000_detect(nict, nich, asict, asich);
91*c111cdafSkiyohara
92*c111cdafSkiyohara out:
93*c111cdafSkiyohara bus_space_unmap(nict, nich, NE2000_NPORTS);
94*c111cdafSkiyohara return rv;
95*c111cdafSkiyohara }
96*c111cdafSkiyohara
97*c111cdafSkiyohara void
ne_mainbus_attach(device_t parent,device_t self,void * aux)98*c111cdafSkiyohara ne_mainbus_attach(device_t parent, device_t self, void *aux)
99*c111cdafSkiyohara {
100*c111cdafSkiyohara struct ne2000_softc *sc = device_private(self);
101*c111cdafSkiyohara struct dp8390_softc *dsc = &sc->sc_dp8390;
102*c111cdafSkiyohara struct mainbus_attach_args *ma = aux;
103*c111cdafSkiyohara bus_space_tag_t nict, asict;
104*c111cdafSkiyohara bus_space_handle_t nich, asich;
105*c111cdafSkiyohara int netype;
106*c111cdafSkiyohara const char *typestr;
107*c111cdafSkiyohara void *ih;
108*c111cdafSkiyohara
109*c111cdafSkiyohara dsc->sc_dev = self;
110*c111cdafSkiyohara aprint_normal("\n");
111*c111cdafSkiyohara
112*c111cdafSkiyohara /* Map i/o space. */
113*c111cdafSkiyohara nict = SH3_BUS_SPACE_PCMCIA_IO;
114*c111cdafSkiyohara if (bus_space_map(nict, ma->ma_addr1, NE2000_NPORTS, 0, &nich)) {
115*c111cdafSkiyohara aprint_error_dev(self, "can't map i/o space\n");
116*c111cdafSkiyohara return;
117*c111cdafSkiyohara }
118*c111cdafSkiyohara
119*c111cdafSkiyohara if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
120*c111cdafSkiyohara NE2000_ASIC_NPORTS, &asich)) {
121*c111cdafSkiyohara aprint_error_dev(self, "can't subregion i/o space\n");
122*c111cdafSkiyohara return;
123*c111cdafSkiyohara }
124*c111cdafSkiyohara asict = nict;
125*c111cdafSkiyohara
126*c111cdafSkiyohara dsc->sc_regt = nict;
127*c111cdafSkiyohara dsc->sc_regh = nich;
128*c111cdafSkiyohara
129*c111cdafSkiyohara sc->sc_asict = asict;
130*c111cdafSkiyohara sc->sc_asich = asich;
131*c111cdafSkiyohara
132*c111cdafSkiyohara /*
133*c111cdafSkiyohara * Detect it again, so we can print some information about the
134*c111cdafSkiyohara * interface.
135*c111cdafSkiyohara */
136*c111cdafSkiyohara netype = ne2000_detect(nict, nich, asict, asich);
137*c111cdafSkiyohara switch (netype) {
138*c111cdafSkiyohara case NE2000_TYPE_RTL8019:
139*c111cdafSkiyohara typestr = "NE2000 (RTL8019)";
140*c111cdafSkiyohara break;
141*c111cdafSkiyohara
142*c111cdafSkiyohara case NE2000_TYPE_NE1000:
143*c111cdafSkiyohara case NE2000_TYPE_NE2000:
144*c111cdafSkiyohara default:
145*c111cdafSkiyohara aprint_error_dev(self, "where did the card go?!\n");
146*c111cdafSkiyohara return;
147*c111cdafSkiyohara }
148*c111cdafSkiyohara
149*c111cdafSkiyohara aprint_normal_dev(self, "%s Ethernet\n", typestr);
150*c111cdafSkiyohara
151*c111cdafSkiyohara /* This interface is always enabled. */
152*c111cdafSkiyohara dsc->sc_enabled = 1;
153*c111cdafSkiyohara
154*c111cdafSkiyohara /*
155*c111cdafSkiyohara * Do generic NE2000 attach. This will read the station address
156*c111cdafSkiyohara * from the EEPROM.
157*c111cdafSkiyohara */
158*c111cdafSkiyohara ne2000_attach(sc, NULL);
159*c111cdafSkiyohara
160*c111cdafSkiyohara /* Establish the interrupt handler. */
161*c111cdafSkiyohara ih = mmeye_intr_establish(ma->ma_irq1, IST_LEVEL, IPL_NET,
162*c111cdafSkiyohara dp8390_intr, dsc);
163*c111cdafSkiyohara if (ih == NULL)
164*c111cdafSkiyohara aprint_error_dev(self,
165*c111cdafSkiyohara "couldn't establish interrupt handler\n");
166*c111cdafSkiyohara }
167