1 /* $OpenBSD: if_gem_sbus.c,v 1.2 2006/12/21 22:16:09 jason Exp $ */
2 /* $NetBSD: if_gem_sbus.c,v 1.1 2006/11/24 13:23:32 martin Exp $ */
3
4 /*-
5 * Copyright (c) 2006 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Martin Husemann.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * SBus front-end for the GEM network driver
42 */
43
44 #if 0
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: if_gem_sbus.c,v 1.1 2006/11/24 13:23:32 martin Exp $");
47 #endif
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/syslog.h>
52 #include <sys/device.h>
53 #include <sys/malloc.h>
54 #include <sys/socket.h>
55
56 #include <net/if.h>
57 #include <net/if_dl.h>
58 #include <net/if_media.h>
59
60 #ifdef INET
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/in_var.h>
64 #include <netinet/ip.h>
65 #include <netinet/if_ether.h>
66 #endif
67
68 #include <dev/mii/mii.h>
69 #include <dev/mii/miivar.h>
70
71 #include <machine/bus.h>
72 #include <machine/intr.h>
73 #include <machine/autoconf.h>
74
75 #include <dev/sbus/sbusvar.h>
76
77 #include <dev/ic/gemreg.h>
78 #include <dev/ic/gemvar.h>
79
80 #include <dev/ofw/openfirm.h>
81
82 struct gem_sbus_softc {
83 struct gem_softc gsc_gem; /* GEM device */
84 };
85
86 int gemmatch_sbus(struct device *, void *, void *);
87 void gemattach_sbus(struct device *, struct device *, void *);
88
89 struct cfattach gem_sbus_ca = {
90 sizeof(struct gem_sbus_softc), gemmatch_sbus, gemattach_sbus
91 };
92
93 int
94 gemmatch_sbus(struct device *parent, void *vcf, void *aux)
95 {
96 struct sbus_attach_args *sa = aux;
97
98 return (strcmp("network", sa->sa_name) == 0);
99 }
100
101 void
102 gemattach_sbus(struct device *parent, struct device *self, void *aux)
103 {
104 struct sbus_attach_args *sa = aux;
105 struct gem_sbus_softc *gsc = (void *)self;
106 struct gem_softc *sc = &gsc->gsc_gem;
107 /* XXX the following declarations should be elsewhere */
108 extern void myetheraddr(u_char *);
109
110 /* Pass on the bus tags */
111 sc->sc_bustag = sa->sa_bustag;
112 sc->sc_dmatag = sa->sa_dmatag;
113
114 if (sa->sa_nreg < 2) {
115 printf("%s: only %d register sets\n",
116 self->dv_xname, sa->sa_nreg);
117 return;
118 }
119
120 /*
121 * Map two register banks:
122 *
123 * bank 0: status, config, reset
124 * bank 1: various gem parts
125 *
126 */
127 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
128 (bus_addr_t)sa->sa_reg[0].sbr_offset,
129 (bus_size_t)sa->sa_reg[0].sbr_size, 0, 0,
130 &sc->sc_h2) != 0) {
131 printf("%s: cannot map registers\n", self->dv_xname);
132 return;
133 }
134 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
135 (bus_addr_t)sa->sa_reg[1].sbr_offset,
136 (bus_size_t)sa->sa_reg[1].sbr_size, 0, 0,
137 &sc->sc_h1) != 0) {
138 printf("%s: cannot map registers\n", self->dv_xname);
139 return;
140 }
141
142 if (OF_getprop(sa->sa_node, "local-mac-address",
143 sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
144 myetheraddr(sc->sc_arpcom.ac_enaddr);
145
146 /*
147 * SBUS config
148 */
149 bus_space_write_4(sa->sa_bustag, sc->sc_h2, GEM_SBUS_CONFIG,
150 GEM_SBUS_CFG_PARITY|GEM_SBUS_CFG_BMODE64);
151
152 /* Establish interrupt handler */
153 if (sa->sa_nintr != 0)
154 (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET, 0,
155 gem_intr, sc, self->dv_xname);
156
157 gem_config(sc);
158 }