1*7ffbd423Ssevan /* $NetBSD: if_mbe_g2.c,v 1.9 2018/07/18 23:10:27 sevan Exp $ */
2fbc8e474Stsutsui
3fbc8e474Stsutsui /*
4fbc8e474Stsutsui * Copyright (c) 2002 Christian Groessler
5fbc8e474Stsutsui * All rights reserved.
6fbc8e474Stsutsui *
7fbc8e474Stsutsui * Redistribution and use in source and binary forms, with or without
8fbc8e474Stsutsui * modification, are permitted provided that the following conditions
9fbc8e474Stsutsui * are met:
10fbc8e474Stsutsui * 1. Redistributions of source code must retain the above copyright
11fbc8e474Stsutsui * notice, this list of conditions and the following disclaimer.
12fbc8e474Stsutsui * 2. Redistributions in binary form must reproduce the above copyright
13fbc8e474Stsutsui * notice, this list of conditions and the following disclaimer in the
14fbc8e474Stsutsui * documentation and/or other materials provided with the distribution.
15fbc8e474Stsutsui * 3. The name of the author may not be used to endorse or promote products
16fbc8e474Stsutsui * derived from this software without specific prior written permission.
17fbc8e474Stsutsui *
18fbc8e474Stsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19fbc8e474Stsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20fbc8e474Stsutsui * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21fbc8e474Stsutsui * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22fbc8e474Stsutsui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23fbc8e474Stsutsui * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24fbc8e474Stsutsui * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25fbc8e474Stsutsui * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26fbc8e474Stsutsui * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27fbc8e474Stsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28fbc8e474Stsutsui * SUCH DAMAGE.
29fbc8e474Stsutsui */
30fbc8e474Stsutsui
31fbc8e474Stsutsui /*
32fbc8e474Stsutsui * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
33fbc8e474Stsutsui *
34fbc8e474Stsutsui * This software may be used, modified, copied, distributed, and sold, in
35fbc8e474Stsutsui * both source and binary form provided that the above copyright, these
36fbc8e474Stsutsui * terms and the following disclaimer are retained. The name of the author
37fbc8e474Stsutsui * and/or the contributor may not be used to endorse or promote products
38fbc8e474Stsutsui * derived from this software without specific prior written permission.
39fbc8e474Stsutsui *
40fbc8e474Stsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
41fbc8e474Stsutsui * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42fbc8e474Stsutsui * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43fbc8e474Stsutsui * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
44fbc8e474Stsutsui * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45fbc8e474Stsutsui * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46fbc8e474Stsutsui * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
47fbc8e474Stsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48fbc8e474Stsutsui * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49fbc8e474Stsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50fbc8e474Stsutsui * SUCH DAMAGE.
51fbc8e474Stsutsui */
52fbc8e474Stsutsui
53fbc8e474Stsutsui /*
54fbc8e474Stsutsui * Portions copyright (C) 1993, David Greenman. This software may be used,
55fbc8e474Stsutsui * modified, copied, distributed, and sold, in both source and binary form
56fbc8e474Stsutsui * provided that the above copyright and these terms are retained. Under no
57fbc8e474Stsutsui * circumstances is the author responsible for the proper functioning of this
58fbc8e474Stsutsui * software, nor does the author assume any responsibility for damages
59fbc8e474Stsutsui * incurred with its use.
60fbc8e474Stsutsui */
61fbc8e474Stsutsui
62fbc8e474Stsutsui /*
63fbc8e474Stsutsui * Driver for Sega LAN Adapter (HIT-0300)
64fbc8e474Stsutsui */
65fbc8e474Stsutsui
66fbc8e474Stsutsui #include <sys/cdefs.h>
67*7ffbd423Ssevan __KERNEL_RCSID(0, "$NetBSD: if_mbe_g2.c,v 1.9 2018/07/18 23:10:27 sevan Exp $");
68fbc8e474Stsutsui
69fbc8e474Stsutsui #include <sys/param.h>
70fbc8e474Stsutsui #include <sys/systm.h>
71fbc8e474Stsutsui #include <sys/device.h>
7286b5be6eSdyoung #include <sys/bus.h>
73fbc8e474Stsutsui
74fbc8e474Stsutsui #include <net/if.h>
75fbc8e474Stsutsui #include <net/if_ether.h>
76fbc8e474Stsutsui #include <net/if_media.h>
77fbc8e474Stsutsui
78fbc8e474Stsutsui #include <machine/intr.h>
79fbc8e474Stsutsui #include <machine/sysasicvar.h>
80fbc8e474Stsutsui #include <machine/cpu.h>
81fbc8e474Stsutsui
82fbc8e474Stsutsui #include <dev/ic/mb86960reg.h>
83fbc8e474Stsutsui #include <dev/ic/mb86960var.h>
84fbc8e474Stsutsui
85fbc8e474Stsutsui #include <dreamcast/dev/g2/g2busvar.h>
86fbc8e474Stsutsui
87fbc8e474Stsutsui
887c06c0a3Stsutsui int mbe_g2_match(device_t, cfdata_t, void *);
897c06c0a3Stsutsui void mbe_g2_attach(device_t, device_t, void *);
90cb6453dbStsutsui static int mbe_g2_detect(bus_space_tag_t, bus_space_handle_t, uint8_t *);
91fbc8e474Stsutsui
92fbc8e474Stsutsui struct mbe_g2_softc {
93fbc8e474Stsutsui struct mb86960_softc sc_mb86960; /* real "mb86960" softc */
94fbc8e474Stsutsui };
95fbc8e474Stsutsui
967c06c0a3Stsutsui CFATTACH_DECL_NEW(mbe_g2bus, sizeof(struct mbe_g2_softc),
97fbc8e474Stsutsui mbe_g2_match, mbe_g2_attach, NULL, NULL);
98fbc8e474Stsutsui
99fbc8e474Stsutsui #define LANA_NPORTS (0x20 * 4)
100fbc8e474Stsutsui
1017c06c0a3Stsutsui #ifdef LANA_DEBUG
1027c06c0a3Stsutsui #define DPRINTF printf
1037c06c0a3Stsutsui #else
1047c06c0a3Stsutsui #define DPRINTF while (/* CONSTCOND */0) printf
1057c06c0a3Stsutsui #endif
1067c06c0a3Stsutsui
107fbc8e474Stsutsui static struct dreamcast_bus_space mbe_g2_dbs;
108fbc8e474Stsutsui
109fbc8e474Stsutsui /*
110fbc8e474Stsutsui * Determine if the device is present.
111fbc8e474Stsutsui */
112fbc8e474Stsutsui int
mbe_g2_match(device_t parent,cfdata_t cf,void * aux)1137c06c0a3Stsutsui mbe_g2_match(device_t parent, cfdata_t cf, void *aux)
114fbc8e474Stsutsui {
115fbc8e474Stsutsui struct g2bus_attach_args *ga = aux;
116fbc8e474Stsutsui bus_space_handle_t memh;
117fbc8e474Stsutsui struct dreamcast_bus_space dbs;
118fbc8e474Stsutsui bus_space_tag_t memt = &dbs;
119fbc8e474Stsutsui static int lanafound;
120fbc8e474Stsutsui int rv;
121cb6453dbStsutsui uint8_t myea[ETHER_ADDR_LEN];
122fbc8e474Stsutsui
123fbc8e474Stsutsui if (lanafound)
124cb6453dbStsutsui return 0;
125fbc8e474Stsutsui
126fbc8e474Stsutsui if (strcmp("mbe", cf->cf_name))
127cb6453dbStsutsui return 0;
128fbc8e474Stsutsui
129fbc8e474Stsutsui memcpy(memt, ga->ga_memt, sizeof(struct dreamcast_bus_space));
130fbc8e474Stsutsui g2bus_set_bus_mem_sparse(memt);
131fbc8e474Stsutsui
132fbc8e474Stsutsui /* Map i/o ports. */
133fbc8e474Stsutsui if (bus_space_map(memt, 0x00600400, LANA_NPORTS, 0, &memh)) {
1347c06c0a3Stsutsui DPRINTF("%s: couldn't map iospace 0x%x\n",
1357c06c0a3Stsutsui __func__, 0x00600400);
136cb6453dbStsutsui return 0;
137fbc8e474Stsutsui }
138fbc8e474Stsutsui
139fbc8e474Stsutsui rv = 0;
140fbc8e474Stsutsui if (mbe_g2_detect(memt, memh, myea) == 0) {
1417c06c0a3Stsutsui DPRINTF("%s: LAN Adapter detection failed\n", __func__);
142fbc8e474Stsutsui goto out;
143fbc8e474Stsutsui }
144fbc8e474Stsutsui
145fbc8e474Stsutsui rv = 1;
146fbc8e474Stsutsui lanafound = 1;
147fbc8e474Stsutsui out:
148fbc8e474Stsutsui bus_space_unmap(memt, memh, LANA_NPORTS);
149cb6453dbStsutsui return rv;
150fbc8e474Stsutsui }
151fbc8e474Stsutsui
152fbc8e474Stsutsui
153fbc8e474Stsutsui /*
154fbc8e474Stsutsui * Determine type and ethernet address.
155fbc8e474Stsutsui */
156fbc8e474Stsutsui static int
mbe_g2_detect(bus_space_tag_t iot,bus_space_handle_t ioh,uint8_t * enaddr)157cb6453dbStsutsui mbe_g2_detect(bus_space_tag_t iot, bus_space_handle_t ioh, uint8_t *enaddr)
158fbc8e474Stsutsui {
159cb6453dbStsutsui uint8_t eeprom[FE_EEPROM_SIZE];
160fbc8e474Stsutsui
161c1acc622Stsutsui /* Read the chip type */
162c1acc622Stsutsui if ((bus_space_read_1(iot, ioh, FE_DLCR7) & FE_D7_IDENT) !=
163c1acc622Stsutsui FE_D7_IDENT_86967) {
1647c06c0a3Stsutsui DPRINTF("%s: unknown chip type\n", __func__);
165cb6453dbStsutsui return 0;
166c1acc622Stsutsui }
167c1acc622Stsutsui
168fbc8e474Stsutsui memset(eeprom, 0, FE_EEPROM_SIZE);
169fbc8e474Stsutsui
170fbc8e474Stsutsui /* Get our station address from EEPROM. */
171fbc8e474Stsutsui mb86965_read_eeprom(iot, ioh, eeprom);
172fbc8e474Stsutsui memcpy(enaddr, eeprom, ETHER_ADDR_LEN);
173fbc8e474Stsutsui
174*7ffbd423Ssevan DPRINTF("Ethernet address %s\n", ether_sprintf(enaddr));
175fbc8e474Stsutsui
176fbc8e474Stsutsui /* Make sure we got a valid station address. */
177fbc8e474Stsutsui if ((enaddr[0] & 0x03) != 0x00 ||
178fbc8e474Stsutsui (enaddr[0] == 0x00 && enaddr[1] == 0x00 && enaddr[2] == 0x00)) {
1797c06c0a3Stsutsui DPRINTF("%s: invalid ethernet address\n", __func__);
180cb6453dbStsutsui return 0;
181fbc8e474Stsutsui }
182fbc8e474Stsutsui
183cb6453dbStsutsui return 1;
184fbc8e474Stsutsui }
185fbc8e474Stsutsui
186fbc8e474Stsutsui void
mbe_g2_attach(device_t parent,device_t self,void * aux)1877c06c0a3Stsutsui mbe_g2_attach(device_t parent, device_t self, void *aux)
188fbc8e474Stsutsui {
1897c06c0a3Stsutsui struct mbe_g2_softc *isc = device_private(self);
190fbc8e474Stsutsui struct mb86960_softc *sc = &isc->sc_mb86960;
1917c06c0a3Stsutsui struct g2bus_attach_args *ga = aux;
192fbc8e474Stsutsui bus_space_tag_t memt = &mbe_g2_dbs;
193fbc8e474Stsutsui bus_space_handle_t memh;
194cb6453dbStsutsui uint8_t myea[ETHER_ADDR_LEN];
195fbc8e474Stsutsui
1967c06c0a3Stsutsui sc->sc_dev = self;
1977c06c0a3Stsutsui
198fbc8e474Stsutsui memcpy(memt, ga->ga_memt, sizeof(struct dreamcast_bus_space));
199fbc8e474Stsutsui g2bus_set_bus_mem_sparse(memt);
200fbc8e474Stsutsui
201fbc8e474Stsutsui /* Map i/o ports. */
202fbc8e474Stsutsui if (bus_space_map(memt, 0x00600400, LANA_NPORTS, 0, &memh)) {
2037c06c0a3Stsutsui aprint_error(": can't map i/o space\n");
204fbc8e474Stsutsui return;
205fbc8e474Stsutsui }
206fbc8e474Stsutsui
207fbc8e474Stsutsui sc->sc_bst = memt;
208fbc8e474Stsutsui sc->sc_bsh = memh;
209fbc8e474Stsutsui
210fbc8e474Stsutsui /* Determine the card type. */
211fbc8e474Stsutsui if (mbe_g2_detect(memt, memh, myea) == 0) {
2127c06c0a3Stsutsui aprint_error(": where did the card go?!\n");
213fbc8e474Stsutsui panic("unknown card");
214fbc8e474Stsutsui }
215fbc8e474Stsutsui
2167c06c0a3Stsutsui aprint_normal(": Sega LAN-Adapter Ethernet\n");
217fbc8e474Stsutsui
218fbc8e474Stsutsui /* This interface is always enabled. */
219fbc8e474Stsutsui sc->sc_stat |= FE_STAT_ENABLED;
220fbc8e474Stsutsui
2216aea963eStsutsui /* The LAN-Adapter uses 8 bit bus mode and slow SRAM. */
2226aea963eStsutsui sc->sc_flags |= FE_FLAGS_SBW_BYTE | FE_FLAGS_SRAM_150ns;
223fbc8e474Stsutsui
224fbc8e474Stsutsui /*
225fbc8e474Stsutsui * Do generic MB86960 attach.
226fbc8e474Stsutsui */
227fbc8e474Stsutsui mb86960_attach(sc, myea);
228fbc8e474Stsutsui
229fbc8e474Stsutsui mb86960_config(sc, NULL, 0, 0);
230fbc8e474Stsutsui
2310b5d7fc8Stsutsui sysasic_intr_establish(SYSASIC_EVENT_8BIT, IPL_NET, SYSASIC_IRL11,
2320b5d7fc8Stsutsui mb86960_intr, sc);
233fbc8e474Stsutsui }
234