Line data Source code
1 : /* $OpenBSD: if_dc_pci.c,v 1.76 2017/04/11 14:43:49 dhill Exp $ */
2 :
3 : /*
4 : * Copyright (c) 1997, 1998, 1999
5 : * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : * 3. All advertising materials mentioning features or use of this software
16 : * must display the following acknowledgement:
17 : * This product includes software developed by Bill Paul.
18 : * 4. Neither the name of the author nor the names of any co-contributors
19 : * may be used to endorse or promote products derived from this software
20 : * without specific prior written permission.
21 : *
22 : * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 : * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 : * THE POSSIBILITY OF SUCH DAMAGE.
33 : *
34 : * $FreeBSD: src/sys/pci/if_dc.c,v 1.5 2000/01/12 22:24:05 wpaul Exp $
35 : */
36 :
37 : #include "bpfilter.h"
38 :
39 : #include <sys/param.h>
40 : #include <sys/systm.h>
41 : #include <sys/mbuf.h>
42 : #include <sys/protosw.h>
43 : #include <sys/socket.h>
44 : #include <sys/ioctl.h>
45 : #include <sys/errno.h>
46 : #include <sys/timeout.h>
47 : #include <sys/malloc.h>
48 : #include <sys/kernel.h>
49 : #include <sys/device.h>
50 :
51 : #include <net/if.h>
52 :
53 : #include <netinet/in.h>
54 : #include <netinet/if_ether.h>
55 :
56 : #include <net/if_media.h>
57 :
58 : #if NBPFILTER > 0
59 : #include <net/bpf.h>
60 : #endif
61 :
62 : #include <dev/mii/miivar.h>
63 :
64 : #include <dev/pci/pcireg.h>
65 : #include <dev/pci/pcivar.h>
66 : #include <dev/pci/pcidevs.h>
67 :
68 : #ifdef __sparc64__
69 : #include <dev/ofw/openfirm.h>
70 : #endif
71 :
72 : #ifndef __hppa__
73 : #define DC_USEIOSPACE
74 : #endif
75 :
76 : #include <dev/ic/dcreg.h>
77 :
78 : /*
79 : * Various supported device vendors/types and their names.
80 : */
81 : struct dc_type dc_devs[] = {
82 : { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21140 },
83 : { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21142 },
84 : { PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9009 },
85 : { PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9100 },
86 : { PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9102 },
87 : { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_ADM9511 },
88 : { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_ADM9513 },
89 : { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AL981 },
90 : { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AN983 },
91 : { PCI_VENDOR_ASIX, PCI_PRODUCT_ASIX_AX88140A },
92 : { PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98713 },
93 : { PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98715 },
94 : { PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98727 },
95 : { PCI_VENDOR_COMPEX, PCI_PRODUCT_COMPEX_98713 },
96 : { PCI_VENDOR_LITEON, PCI_PRODUCT_LITEON_PNIC },
97 : { PCI_VENDOR_LITEON, PCI_PRODUCT_LITEON_PNICII },
98 : { PCI_VENDOR_ACCTON, PCI_PRODUCT_ACCTON_EN1217 },
99 : { PCI_VENDOR_ACCTON, PCI_PRODUCT_ACCTON_EN2242 },
100 : { PCI_VENDOR_CONEXANT, PCI_PRODUCT_CONEXANT_RS7112 },
101 : { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_21145 },
102 : { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CSHO100BTX },
103 : { PCI_VENDOR_MICROSOFT, PCI_PRODUCT_MICROSOFT_MN130 },
104 : { PCI_VENDOR_XIRCOM, PCI_PRODUCT_XIRCOM_X3201_3_21143 },
105 : { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AN985 },
106 : { PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_FE2500 },
107 : { PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_FE2500MX },
108 : { PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_PCM200 },
109 : { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DRP32TXD },
110 : { PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_PCMPC200 },
111 : { PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_PCM200 },
112 : { PCI_VENDOR_HAWKING, PCI_PRODUCT_HAWKING_PN672TX },
113 : { PCI_VENDOR_MICROSOFT, PCI_PRODUCT_MICROSOFT_MN120 },
114 : { 0, 0 }
115 : };
116 :
117 : int dc_pci_match(struct device *, void *, void *);
118 : void dc_pci_attach(struct device *, struct device *, void *);
119 : int dc_pci_detach(struct device *, int);
120 :
121 : struct dc_pci_softc {
122 : struct dc_softc psc_softc;
123 : pci_chipset_tag_t psc_pc;
124 : bus_size_t psc_mapsize;
125 : };
126 :
127 : /*
128 : * Probe for a 21143 or clone chip. Check the PCI vendor and device
129 : * IDs against our list and return a device name if we find a match.
130 : */
131 : int
132 0 : dc_pci_match(struct device *parent, void *match, void *aux)
133 : {
134 0 : struct pci_attach_args *pa = (struct pci_attach_args *)aux;
135 : struct dc_type *t;
136 :
137 : /*
138 : * Support for the 21140 chip is experimental. If it works for you,
139 : * that's great. By default, this chip will use de.
140 : */
141 0 : if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
142 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140)
143 0 : return (1);
144 :
145 : /*
146 : * The following chip revision doesn't seem to work so well with dc,
147 : * so let's have de handle it. (de will return a match of 2)
148 : */
149 0 : if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
150 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142 &&
151 0 : PCI_REVISION(pa->pa_class) == 0x21)
152 0 : return (1);
153 :
154 0 : for (t = dc_devs; t->dc_vid != 0; t++) {
155 0 : if ((PCI_VENDOR(pa->pa_id) == t->dc_vid) &&
156 0 : (PCI_PRODUCT(pa->pa_id) == t->dc_did)) {
157 0 : return (3);
158 : }
159 : }
160 :
161 0 : return (0);
162 0 : }
163 :
164 : /*
165 : * Attach the interface. Allocate softc structures, do ifmedia
166 : * setup and ethernet/BPF attach.
167 : */
168 : void
169 0 : dc_pci_attach(struct device *parent, struct device *self, void *aux)
170 : {
171 : const char *intrstr = NULL;
172 : pcireg_t command;
173 0 : struct dc_pci_softc *psc = (struct dc_pci_softc *)self;
174 0 : struct dc_softc *sc = &psc->psc_softc;
175 0 : struct pci_attach_args *pa = aux;
176 0 : pci_chipset_tag_t pc = pa->pa_pc;
177 0 : pci_intr_handle_t ih;
178 : int found = 0;
179 :
180 0 : psc->psc_pc = pa->pa_pc;
181 0 : sc->sc_dmat = pa->pa_dmat;
182 :
183 0 : pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
184 :
185 0 : sc->dc_csid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
186 :
187 : /*
188 : * Map control/status registers.
189 : */
190 : #ifdef DC_USEIOSPACE
191 0 : if (pci_mapreg_map(pa, DC_PCI_CFBIO,
192 : PCI_MAPREG_TYPE_IO, 0,
193 0 : &sc->dc_btag, &sc->dc_bhandle, NULL, &psc->psc_mapsize, 0)) {
194 0 : printf(": can't map i/o space\n");
195 0 : return;
196 : }
197 : #else
198 : if (pci_mapreg_map(pa, DC_PCI_CFBMA,
199 : PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
200 : &sc->dc_btag, &sc->dc_bhandle, NULL, &psc->psc_mapsize, 0)) {
201 : printf(": can't map mem space\n");
202 : return;
203 : }
204 : #endif
205 :
206 : /* Allocate interrupt */
207 0 : if (pci_intr_map(pa, &ih)) {
208 0 : printf(": couldn't map interrupt\n");
209 0 : goto fail_1;
210 : }
211 0 : intrstr = pci_intr_string(pc, ih);
212 0 : sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, dc_intr, sc,
213 0 : self->dv_xname);
214 0 : if (sc->sc_ih == NULL) {
215 0 : printf(": couldn't establish interrupt");
216 0 : if (intrstr != NULL)
217 0 : printf(" at %s", intrstr);
218 0 : printf("\n");
219 0 : goto fail_1;
220 : }
221 0 : printf(": %s", intrstr);
222 :
223 : /* Need this info to decide on a chip type. */
224 0 : sc->dc_revision = PCI_REVISION(pa->pa_class);
225 :
226 : /* Get the eeprom width, if possible */
227 0 : if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LITEON &&
228 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC))
229 : ; /* PNIC has non-standard eeprom */
230 0 : else if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_XIRCOM &&
231 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_XIRCOM_X3201_3_21143))
232 : ; /* XIRCOM has non-standard eeprom */
233 : else
234 0 : dc_eeprom_width(sc);
235 :
236 0 : switch (PCI_VENDOR(pa->pa_id)) {
237 : case PCI_VENDOR_DEC:
238 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140 ||
239 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142) {
240 : found = 1;
241 0 : sc->dc_type = DC_TYPE_21143;
242 0 : sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
243 0 : sc->dc_flags |= DC_REDUCED_MII_POLL;
244 0 : dc_read_srom(sc, sc->dc_romwidth);
245 0 : }
246 : break;
247 : case PCI_VENDOR_INTEL:
248 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_21145) {
249 : found = 1;
250 0 : sc->dc_type = DC_TYPE_21145;
251 0 : sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
252 0 : sc->dc_flags |= DC_REDUCED_MII_POLL;
253 0 : dc_read_srom(sc, sc->dc_romwidth);
254 0 : }
255 : break;
256 : case PCI_VENDOR_DAVICOM:
257 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9100 ||
258 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9102 ||
259 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9009) {
260 : found = 1;
261 0 : sc->dc_type = DC_TYPE_DM9102;
262 0 : sc->dc_flags |= DC_TX_COALESCE|DC_TX_INTR_ALWAYS;
263 0 : sc->dc_flags |= DC_REDUCED_MII_POLL|DC_TX_STORENFWD;
264 0 : sc->dc_flags |= DC_TX_ALIGN;
265 0 : sc->dc_pmode = DC_PMODE_MII;
266 :
267 : /* Increase the latency timer value. */
268 0 : command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFLT);
269 0 : command &= 0xFFFF00FF;
270 0 : command |= 0x00008000;
271 0 : pci_conf_write(pc, pa->pa_tag, DC_PCI_CFLT, command);
272 0 : }
273 : break;
274 : case PCI_VENDOR_ADMTEK:
275 : case PCI_VENDOR_3COM:
276 : case PCI_VENDOR_MICROSOFT:
277 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AL981) {
278 : found = 1;
279 0 : sc->dc_type = DC_TYPE_AL981;
280 0 : sc->dc_flags |= DC_TX_USE_TX_INTR;
281 0 : sc->dc_flags |= DC_TX_ADMTEK_WAR;
282 0 : sc->dc_pmode = DC_PMODE_MII;
283 0 : dc_read_srom(sc, sc->dc_romwidth);
284 0 : }
285 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9511 ||
286 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9513 ||
287 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AN983 ||
288 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3COM_3CSHO100BTX ||
289 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MICROSOFT_MN130) {
290 : found = 1;
291 0 : sc->dc_type = DC_TYPE_AN983;
292 0 : sc->dc_flags |= DC_TX_USE_TX_INTR;
293 0 : sc->dc_flags |= DC_TX_ADMTEK_WAR;
294 0 : sc->dc_flags |= DC_64BIT_HASH;
295 0 : sc->dc_pmode = DC_PMODE_MII;
296 : /* Don't read SROM for - auto-loaded on reset */
297 0 : }
298 : break;
299 : case PCI_VENDOR_MACRONIX:
300 : case PCI_VENDOR_ACCTON:
301 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN2242) {
302 : found = 1;
303 0 : sc->dc_type = DC_TYPE_AN983;
304 0 : sc->dc_flags |= DC_TX_USE_TX_INTR;
305 0 : sc->dc_flags |= DC_TX_ADMTEK_WAR;
306 0 : sc->dc_flags |= DC_64BIT_HASH;
307 0 : sc->dc_pmode = DC_PMODE_MII;
308 : /* Don't read SROM for - auto-loaded on reset */
309 0 : }
310 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98713) {
311 : found = 1;
312 0 : if (sc->dc_revision < DC_REVISION_98713A)
313 0 : sc->dc_type = DC_TYPE_98713;
314 0 : if (sc->dc_revision >= DC_REVISION_98713A) {
315 0 : sc->dc_type = DC_TYPE_98713A;
316 0 : sc->dc_flags |= DC_21143_NWAY;
317 0 : }
318 0 : sc->dc_flags |= DC_REDUCED_MII_POLL;
319 0 : sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
320 0 : }
321 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98715 ||
322 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN1217) {
323 : found = 1;
324 0 : if (sc->dc_revision >= DC_REVISION_98715AEC_C &&
325 0 : sc->dc_revision < DC_REVISION_98725)
326 0 : sc->dc_flags |= DC_128BIT_HASH;
327 0 : sc->dc_type = DC_TYPE_987x5;
328 0 : sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
329 0 : sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
330 0 : }
331 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98727) {
332 : found = 1;
333 0 : sc->dc_type = DC_TYPE_987x5;
334 0 : sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
335 0 : sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
336 0 : }
337 : break;
338 : case PCI_VENDOR_COMPEX:
339 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_COMPEX_98713) {
340 : found = 1;
341 0 : if (sc->dc_revision < DC_REVISION_98713A) {
342 0 : sc->dc_type = DC_TYPE_98713;
343 0 : sc->dc_flags |= DC_REDUCED_MII_POLL;
344 0 : }
345 0 : if (sc->dc_revision >= DC_REVISION_98713A)
346 0 : sc->dc_type = DC_TYPE_98713A;
347 0 : sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
348 0 : }
349 : break;
350 : case PCI_VENDOR_LITEON:
351 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNICII) {
352 : found = 1;
353 0 : sc->dc_type = DC_TYPE_PNICII;
354 0 : sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
355 0 : sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
356 0 : sc->dc_flags |= DC_128BIT_HASH;
357 0 : }
358 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC) {
359 : found = 1;
360 0 : sc->dc_type = DC_TYPE_PNIC;
361 0 : sc->dc_flags |= DC_TX_STORENFWD|DC_TX_INTR_ALWAYS;
362 0 : sc->dc_flags |= DC_PNIC_RX_BUG_WAR;
363 0 : sc->dc_pnic_rx_buf = malloc(ETHER_MAX_DIX_LEN * 5,
364 : M_DEVBUF, M_NOWAIT);
365 0 : if (sc->dc_pnic_rx_buf == NULL)
366 0 : panic("dc_pci_attach");
367 0 : if (sc->dc_revision < DC_REVISION_82C169)
368 0 : sc->dc_pmode = DC_PMODE_SYM;
369 : }
370 : break;
371 : case PCI_VENDOR_ASIX:
372 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ASIX_AX88140A) {
373 : found = 1;
374 0 : sc->dc_type = DC_TYPE_ASIX;
375 0 : sc->dc_flags |= DC_TX_USE_TX_INTR|DC_TX_INTR_FIRSTFRAG;
376 0 : sc->dc_flags |= DC_REDUCED_MII_POLL;
377 0 : sc->dc_pmode = DC_PMODE_MII;
378 0 : }
379 : break;
380 : case PCI_VENDOR_CONEXANT:
381 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CONEXANT_RS7112) {
382 : found = 1;
383 0 : sc->dc_type = DC_TYPE_CONEXANT;
384 0 : sc->dc_flags |= DC_TX_INTR_ALWAYS;
385 0 : sc->dc_flags |= DC_REDUCED_MII_POLL;
386 0 : sc->dc_pmode = DC_PMODE_MII;
387 0 : dc_read_srom(sc, sc->dc_romwidth);
388 0 : }
389 : break;
390 : case PCI_VENDOR_XIRCOM:
391 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_XIRCOM_X3201_3_21143) {
392 : found = 1;
393 0 : sc->dc_type = DC_TYPE_XIRCOM;
394 0 : sc->dc_flags |= DC_TX_INTR_ALWAYS;
395 0 : sc->dc_flags |= DC_TX_COALESCE;
396 0 : sc->dc_flags |= DC_TX_ALIGN;
397 0 : sc->dc_pmode = DC_PMODE_MII;
398 0 : }
399 : break;
400 : }
401 0 : if (found == 0) {
402 : /* This shouldn't happen if probe has done its job... */
403 0 : printf(": unknown device: %x:%x\n",
404 0 : PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
405 : goto fail_2;
406 : }
407 :
408 : /* Save the cache line size. */
409 0 : if (DC_IS_DAVICOM(sc))
410 0 : sc->dc_cachesize = 0;
411 : else
412 0 : sc->dc_cachesize = pci_conf_read(pc, pa->pa_tag,
413 0 : DC_PCI_CFLT) & 0xFF;
414 :
415 : /* Reset the adapter. */
416 0 : dc_reset(sc);
417 :
418 : /* Take 21143 out of snooze mode */
419 0 : if (DC_IS_INTEL(sc) || DC_IS_XIRCOM(sc)) {
420 0 : command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD);
421 0 : command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
422 0 : pci_conf_write(pc, pa->pa_tag, DC_PCI_CFDD, command);
423 0 : }
424 :
425 : /*
426 : * If we discover later (in dc_attach) that we have an
427 : * MII with no PHY, we need to have the 21143 drive the LEDs.
428 : * Except there are some systems like the NEC VersaPro NoteBook PC
429 : * which have no LEDs, and twiddling these bits has adverse effects
430 : * on them. (I.e. you suddenly can't get a link.)
431 : *
432 : * If mii_attach() returns an error, we leave the DC_TULIP_LEDS
433 : * bit set, else we clear it. Since our dc(4) driver is split into
434 : * bus-dependent and bus-independent parts, we must do set this bit
435 : * here while we are able to do PCI configuration reads.
436 : */
437 0 : if (DC_IS_INTEL(sc)) {
438 0 : if (pci_conf_read(pc, pa->pa_tag, DC_PCI_CSID) != 0x80281033)
439 0 : sc->dc_flags |= DC_TULIP_LEDS;
440 : }
441 :
442 : /*
443 : * Try to learn something about the supported media.
444 : * We know that ASIX and ADMtek and Davicom devices
445 : * will *always* be using MII media, so that's a no-brainer.
446 : * The tricky ones are the Macronix/PNIC II and the
447 : * Intel 21143.
448 : */
449 0 : if (DC_IS_INTEL(sc))
450 0 : dc_parse_21143_srom(sc);
451 0 : else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
452 0 : if (sc->dc_type == DC_TYPE_98713)
453 0 : sc->dc_pmode = DC_PMODE_MII;
454 : else
455 0 : sc->dc_pmode = DC_PMODE_SYM;
456 0 : } else if (!sc->dc_pmode)
457 0 : sc->dc_pmode = DC_PMODE_MII;
458 :
459 : #ifdef __sparc64__
460 : {
461 : extern void myetheraddr(u_char *);
462 :
463 : if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
464 : sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
465 : myetheraddr(sc->sc_arpcom.ac_enaddr);
466 : if (sc->sc_arpcom.ac_enaddr[0] == 0x00 &&
467 : sc->sc_arpcom.ac_enaddr[1] == 0x03 &&
468 : sc->sc_arpcom.ac_enaddr[2] == 0xcc)
469 : sc->dc_flags |= DC_MOMENCO_BOTCH;
470 : sc->sc_hasmac = 1;
471 : }
472 : #endif
473 :
474 : #ifdef SRM_MEDIA
475 : sc->dc_srm_media = 0;
476 :
477 : /* Remember the SRM console media setting */
478 : if (DC_IS_INTEL(sc)) {
479 : command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD);
480 : command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
481 : switch ((command >> 8) & 0xff) {
482 : case 3:
483 : sc->dc_srm_media = IFM_10_T;
484 : break;
485 : case 4:
486 : sc->dc_srm_media = IFM_10_T | IFM_FDX;
487 : break;
488 : case 5:
489 : sc->dc_srm_media = IFM_100_TX;
490 : break;
491 : case 6:
492 : sc->dc_srm_media = IFM_100_TX | IFM_FDX;
493 : break;
494 : }
495 : if (sc->dc_srm_media)
496 : sc->dc_srm_media |= IFM_ACTIVE | IFM_ETHER;
497 : }
498 : #endif
499 0 : dc_attach(sc);
500 :
501 0 : return;
502 :
503 : fail_2:
504 0 : pci_intr_disestablish(pc, sc->sc_ih);
505 :
506 : fail_1:
507 0 : bus_space_unmap(sc->dc_btag, sc->dc_bhandle, psc->psc_mapsize);
508 0 : }
509 :
510 : int
511 0 : dc_pci_detach(struct device *self, int flags)
512 : {
513 0 : struct dc_pci_softc *psc = (void *)self;
514 0 : struct dc_softc *sc = &psc->psc_softc;
515 :
516 0 : if (sc->sc_ih != NULL)
517 0 : pci_intr_disestablish(psc->psc_pc, sc->sc_ih);
518 0 : dc_detach(sc);
519 0 : bus_space_unmap(sc->dc_btag, sc->dc_bhandle, psc->psc_mapsize);
520 :
521 0 : return (0);
522 : }
523 :
524 : struct cfattach dc_pci_ca = {
525 : sizeof(struct dc_softc), dc_pci_match, dc_pci_attach, dc_pci_detach,
526 : dc_activate
527 : };
|