xref: /netbsd-src/sys/arch/dreamcast/dev/g2/if_mbe_g2.c (revision 7ffbd4231140fa0eb06ccc255de220886253fbe0)
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