if_rtk_cardbus.c revision 1.1 1 /* $NetBSD: if_rtk_cardbus.c,v 1.1 2000/05/10 00:24:15 haya Exp $ */
2 /*
3 * Copyright (c) 2000 Masanori Kanaoka
4 * 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. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * if_rtk_cardbus.c:
31 * Cardbus specific routines for RealTek 8139 ethernet adapter.
32 * Tested for
33 * - elecom-Laneed LD-10/100CBA (Accton MPX5030)
34 * - MELCO LPC3-TX-CB (RealTek 8138)
35 */
36
37 #include "opt_inet.h"
38 #include "opt_ns.h"
39 #include "bpfilter.h"
40 #include "rnd.h"
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/callout.h>
45 #include <sys/device.h>
46 #include <sys/sockio.h>
47 #include <sys/mbuf.h>
48 #include <sys/malloc.h>
49 #include <sys/kernel.h>
50 #include <sys/socket.h>
51
52 #include <net/if.h>
53 #include <net/if_arp.h>
54 #include <net/if_ether.h>
55 #include <net/if_dl.h>
56 #include <net/if_media.h>
57 #ifdef INET
58 #include <netinet/in.h>
59 #include <netinet/if_inarp.h>
60 #endif
61 #ifdef NS
62 #include <netns/ns.h>
63 #include <netns/ns_if.h>
64 #endif
65
66 #if NBPFILTER > 0
67 #include <net/bpf.h>
68 #endif
69 #if NRND > 0
70 #include <sys/rnd.h>
71 #endif
72
73 #include <machine/bus.h>
74
75 #include <dev/pci/pcireg.h>
76 #include <dev/pci/pcivar.h>
77 #include <dev/pci/pcidevs.h>
78
79 #include <dev/cardbus/cardbusvar.h>
80 #include <dev/cardbus/cardbusdevs.h>
81
82 #include <dev/mii/mii.h>
83 #include <dev/mii/miivar.h>
84
85 /*
86 * Default to using PIO access for this driver. On SMP systems,
87 * there appear to be problems with memory mapped mode: it looks like
88 * doing too many memory mapped access back to back in rapid succession
89 * can hang the bus. I'm inclined to blame this on crummy design/construction
90 * on the part of RealTek. Memory mapped mode does appear to work on
91 * uniprocessor systems though.
92 */
93 #define RL_USEIOSPACE
94
95 #include <dev/ic/rtl81x9reg.h>
96 #include <dev/ic/rtl81x9var.h>
97
98 /*
99 * Various supported device vendors/types and their names.
100 */
101 static struct rl_type rl_cardbus_devs[] = {
102 { CARDBUS_VENDOR_ACCTON, CARDBUS_PRODUCT_ACCTON_MPX5030,
103 "Accton MPX 5030/5038 10/100BaseTX" },
104 { CARDBUS_VENDOR_REALTEK, CARDBUS_PRODUCT_REALTEK_RT8138,
105 "RealTek 8138 10/100BaseTX" },
106 { 0, 0, NULL }
107 };
108
109 const struct rl_type *rl_cardbus_lookup
110 __P((const struct cardbus_attach_args *));
111 static int rl_cardbus_match __P((struct device *, struct cfdata *, void *));
112 static void rl_cardbus_attach __P((struct device *, struct device *, void *));
113
114 struct rl_cardbus_softc {
115 struct rl_softc sc_rl; /* real rl softc */
116
117 /* CardBus-specific goo. */
118 void *sc_ih;
119 cardbus_devfunc_t sc_ct;
120 cardbustag_t sc_tag;
121 int sc_csr;
122 int sc_cben;
123 int sc_bar_reg;
124 pcireg_t sc_bar_val;
125 bus_size_t sc_mapsize;
126 int sc_intrline;
127 };
128
129 struct cfattach rtk_cardbus_ca = {
130 sizeof(struct rl_cardbus_softc), rl_cardbus_match, rl_cardbus_attach,
131 };
132
133 const struct rl_type *
134 rl_cardbus_lookup(ca)
135 const struct cardbus_attach_args *ca;
136 {
137 struct rl_type *t;
138
139 for (t = rl_cardbus_devs; t->rl_name != NULL; t++){
140 if (CARDBUS_VENDOR(ca->ca_id) == t->rl_vid &&
141 CARDBUS_PRODUCT(ca->ca_id) == t->rl_did) {
142 return (t);
143 }
144 }
145 return (NULL);
146 }
147
148 int
149 rl_cardbus_match(parent, match, aux)
150 struct device *parent;
151 struct cfdata *match;
152 void *aux;
153 {
154 struct cardbus_attach_args *ca = aux;
155
156 if (rl_cardbus_lookup(ca) != NULL)
157 return (1);
158 return (0);
159 }
160
161
162 void
163 rl_cardbus_attach(parent, self, aux)
164 struct device *parent, *self;
165 void *aux;
166 {
167 int s, pmreg;
168 pcireg_t command;
169 struct rl_cardbus_softc *csc = (struct rl_cardbus_softc *)self;
170 struct rl_softc *sc = &csc->sc_rl;
171 struct cardbus_attach_args *ca = aux;
172 cardbus_devfunc_t ct = ca->ca_ct;
173 cardbus_chipset_tag_t cc = ct->ct_cc;
174 cardbus_function_tag_t cf = ct->ct_cf;
175 const struct rl_type *t;
176 bus_addr_t adr;
177 pcireg_t reg;
178
179 sc->sc_dmat = ca->ca_dmat;
180 csc->sc_ct = ct;
181 csc->sc_tag = ca->ca_tag;
182 csc->sc_intrline = ca->ca_intrline;
183
184 t = rl_cardbus_lookup(ca);
185 if (t == NULL) {
186 printf("\n");
187 panic("rl_cardbus_attach: impossible");
188 }
189 printf(": %s\n", t->rl_name);
190
191 s = splimp();
192 /*
193 * Handle power management nonsense.
194 */
195 if (cardbus_get_capability(cc, cf, csc->sc_tag,
196 PCI_CAP_PWRMGMT, &pmreg, 0)) {
197 command = cardbus_conf_read(cc, cf, csc->sc_tag, pmreg + 4);
198 if (command & RL_PSTATE_MASK) {
199 pcireg_t iobase, membase, irq;
200
201 /* Save important PCI config data. */
202 iobase = cardbus_conf_read(cc, cf, csc->sc_tag,
203 RL_PCI_LOIO);
204 membase = cardbus_conf_read(cc, cf,csc->sc_tag,
205 RL_PCI_LOMEM);
206 irq = cardbus_conf_read(cc, cf,csc->sc_tag,
207 PCI_PRODUCT_DELTA_8139);
208
209 /* Reset the power state. */
210 printf("%s: chip is is in D%d power mode "
211 "-- setting to D0\n", sc->sc_dev.dv_xname,
212 command & RL_PSTATE_MASK);
213 command &= 0xFFFFFFFC;
214 cardbus_conf_write(cc, cf, csc->sc_tag,
215 pmreg + 4, command);
216
217 /* Restore PCI config data. */
218 cardbus_conf_write(cc, cf, csc->sc_tag,
219 RL_PCI_LOIO, iobase);
220 cardbus_conf_write(cc, cf, csc->sc_tag,
221 RL_PCI_LOMEM, membase);
222 cardbus_conf_write(cc, cf, csc->sc_tag,
223 PCI_PRODUCT_DELTA_8139, irq);
224 }
225 }
226 /*
227 * Map control/status registers.
228 */
229 #ifdef RL_USEIOSPACE
230 if (Cardbus_mapreg_map(ct, RL_PCI_LOIO, CARDBUS_MAPREG_TYPE_IO, 0,
231 &sc->rl_btag, &sc->rl_bhandle, &adr, &csc->sc_mapsize) == 0) {
232 #if rbus
233 #else
234 (*ct->ct_cf->cardbus_io_open)(cc, 0, adr, adr+csc->sc_mapsize);
235 #endif
236 csc->sc_cben = CARDBUS_IO_ENABLE;
237 csc->sc_csr |=
238 (CARDBUS_COMMAND_IO_ENABLE|CARDBUS_COMMAND_MASTER_ENABLE);
239 csc->sc_bar_reg = RL_PCI_LOIO;
240 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_IO;
241 }
242 #else
243 if (Cardbus_mapreg_map(ct, RL_PCI_LOMEM, CARDBUS_MAPREG_TYPE_MEM, 0,
244 &sc->rl_btag, &sc->rl_bhandle, &adr, &csc->sc_mapsize) == 0) {
245 #if rbus
246 #else
247 (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize);
248 #endif
249 csc->sc_cben = CARDBUS_MEM_ENABLE;
250 csc->sc_csr |=
251 (CARDBUS_COMMAND_MEM_ENABLE|CARDBUS_COMMAND_MASTER_ENABLE);
252 csc->sc_bar_reg = RL_PCI_LOMEM;
253 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_MEM;
254 }
255 #endif
256 else {
257 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
258 goto fail;
259 }
260 /* Make sure the right access type is on the CardBus bridge. */
261 (*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cben);
262 (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
263
264 /* Program the BAR */
265 cardbus_conf_write(cc, cf, csc->sc_tag,
266 csc->sc_bar_reg, csc->sc_bar_val);
267
268 /* Enable the appropriate bits in the CARDBUS CSR. */
269 reg = cardbus_conf_read(cc, cf, csc->sc_tag,
270 CARDBUS_COMMAND_STATUS_REG);
271 reg &= ~(CARDBUS_COMMAND_IO_ENABLE|CARDBUS_COMMAND_MEM_ENABLE);
272 reg |= csc->sc_csr;
273 cardbus_conf_write(cc, cf, csc->sc_tag,
274 CARDBUS_COMMAND_STATUS_REG, reg);
275
276 /*
277 * Make sure the latency timer is set to some reasonable
278 * value.
279 */
280 reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG);
281 if (CARDBUS_LATTIMER(reg) < 0x20) {
282 reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
283 reg |= (0x20 << CARDBUS_LATTIMER_SHIFT);
284 cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG, reg);
285 }
286
287 if (t->rl_did == CARDBUS_PRODUCT_ACCTON_MPX5030 ||
288 t->rl_did == CARDBUS_PRODUCT_REALTEK_RT8138){
289 sc->rl_type = RL_8139;
290
291 } else {
292 printf("%s: unknown device ID: 0x%x\n",
293 sc->sc_dev.dv_xname, t->rl_did);
294 goto fail;
295 }
296
297 /* Allocate interrupt */
298 printf("%s: interrupting at %d\n",
299 sc->sc_dev.dv_xname, csc->sc_intrline);
300 csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
301 rl_intr, sc);
302 if (csc->sc_ih == NULL) {
303 printf("%s: unable to establish interrupt at %d\n",
304 sc->sc_dev.dv_xname, csc->sc_intrline);
305 printf("\n");
306 goto fail;
307 }
308
309 rl_attach(sc);
310
311 fail:
312 splx(s);
313 return;
314 }
315
316