1 /* $OpenBSD: if_de.c,v 1.144 2024/11/20 02:26:53 dlg Exp $ */
2 /* $NetBSD: if_de.c,v 1.58 1998/01/12 09:39:58 thorpej Exp $ */
3
4 /*-
5 * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Id: if_de.c,v 1.89 1997/06/03 19:19:55 thomas Exp
28 *
29 */
30
31 /*
32 * DEC 21040 PCI Ethernet Controller
33 *
34 * Written by Matt Thomas
35 * BPF support code stolen directly from if_ec.c
36 *
37 * This driver supports the DEC DE435 or any other PCI
38 * board which support 21040, 21041, or 21140 (mostly).
39 */
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/mbuf.h>
44 #include <sys/socket.h>
45 #include <sys/ioctl.h>
46 #include <sys/errno.h>
47 #include <sys/kernel.h>
48 #include <sys/device.h>
49 #include <sys/timeout.h>
50
51 #include <net/if.h>
52 #include <net/if_media.h>
53
54 #include "bpfilter.h"
55 #if NBPFILTER > 0
56 #include <net/bpf.h>
57 #endif
58
59 #include <netinet/in.h>
60 #include <netinet/if_ether.h>
61
62 #include <machine/bus.h>
63 #include <machine/intr.h>
64 #include <dev/pci/pcireg.h>
65 #include <dev/pci/pcivar.h>
66 #include <dev/ic/dc21040reg.h>
67
68 /*
69 * Intel CPUs should use I/O mapped access.
70 */
71 #if defined(__i386__)
72 #define TULIP_IOMAPPED
73 #endif
74
75 #define TULIP_HZ 10
76
77 #define TULIP_SIAGEN_WATCHDOG 0
78
79 #define TULIP_GPR_CMDBITS (TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER|TULIP_CMD_TXTHRSHLDCTL)
80
81 #define EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
82 #define MII_EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
83
84 #define tulip_mchash(mca) (ether_crc32_le(mca, 6) & 0x1FF)
85 #define tulip_srom_crcok(databuf) ( \
86 ((ether_crc32_le(databuf, 126) & 0xFFFFU) ^ 0xFFFFU) == \
87 ((databuf)[126] | ((databuf)[127] << 8)))
88
89 /*
90 * This is the PCI configuration support. Since the 21040 is available
91 * on both EISA and PCI boards, one must be careful in how defines the
92 * 21040 in the config file.
93 */
94
95 #define PCI_CFID 0x00 /* Configuration ID */
96 #define PCI_CFCS 0x04 /* Configuration Command/Status */
97 #define PCI_CFRV 0x08 /* Configuration Revision */
98 #define PCI_CFLT 0x0c /* Configuration Latency Timer */
99 #define PCI_CBIO 0x10 /* Configuration Base IO Address */
100 #define PCI_CBMA 0x14 /* Configuration Base Memory Address */
101 #define PCI_CFIT 0x3c /* Configuration Interrupt */
102 #define PCI_CFDA 0x40 /* Configuration Driver Area */
103
104 #define PCI_CONF_WRITE(r, v) pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v))
105 #define PCI_CONF_READ(r) pci_conf_read(pa->pa_pc, pa->pa_tag, (r))
106 #define PCI_GETBUSDEVINFO(sc) do { \
107 (sc)->tulip_pci_busno = parent; \
108 (sc)->tulip_pci_devno = pa->pa_device; \
109 } while (0)
110
111 #include <dev/pci/if_devar.h>
112 /*
113 * This module supports
114 * the DEC 21040 PCI Ethernet Controller.
115 * the DEC 21041 PCI Ethernet Controller.
116 * the DEC 21140 PCI Fast Ethernet Controller.
117 */
118 int tulip_probe(struct device *parent, void *match, void *aux);
119 void tulip_attach(struct device * const parent, struct device * const self, void * const aux);
120
121 const struct cfattach de_ca = {
122 sizeof(tulip_softc_t), tulip_probe, tulip_attach
123 };
124
125 struct cfdriver de_cd = {
126 NULL, "de", DV_IFNET
127 };
128
129 void tulip_timeout_callback(void *arg);
130 void tulip_timeout(tulip_softc_t * const sc);
131 int tulip_txprobe(tulip_softc_t * const sc);
132 void tulip_media_set(tulip_softc_t * const sc, tulip_media_t media);
133 void tulip_linkup(tulip_softc_t * const sc, tulip_media_t media);
134 void tulip_media_print(tulip_softc_t * const sc);
135 tulip_link_status_t tulip_media_link_monitor(tulip_softc_t * const sc);
136 void tulip_media_poll(tulip_softc_t * const sc, tulip_mediapoll_event_t event);
137 void tulip_media_select(tulip_softc_t * const sc);
138
139 void tulip_21040_mediainfo_init(tulip_softc_t * const sc, tulip_media_t media);
140 void tulip_21040_media_probe(tulip_softc_t * const sc);
141 void tulip_21040_10baset_only_media_probe(tulip_softc_t * const sc);
142 void tulip_21040_10baset_only_media_select(tulip_softc_t * const sc);
143 void tulip_21040_auibnc_only_media_probe(tulip_softc_t * const sc);
144 void tulip_21040_auibnc_only_media_select(tulip_softc_t * const sc);
145
146 void tulip_21041_mediainfo_init(tulip_softc_t * const sc);
147 void tulip_21041_media_probe(tulip_softc_t * const sc);
148 void tulip_21041_media_poll(tulip_softc_t * const sc, const tulip_mediapoll_event_t event);
149
150 tulip_media_t tulip_mii_phy_readspecific(tulip_softc_t * const sc);
151 unsigned tulip_mii_get_phyaddr(tulip_softc_t * const sc, unsigned offset);
152 int tulip_mii_map_abilities(tulip_softc_t * const sc, unsigned abilities);
153 void tulip_mii_autonegotiate(tulip_softc_t * const sc, const unsigned phyaddr);
154
155 void tulip_2114x_media_preset(tulip_softc_t * const sc);
156
157 void tulip_null_media_poll(tulip_softc_t * const sc, tulip_mediapoll_event_t event);
158
159 void tulip_21140_mediainit(tulip_softc_t * const sc, tulip_media_info_t * const mip,
160 tulip_media_t const media, unsigned gpdata, unsigned cmdmode);
161 void tulip_21140_evalboard_media_probe(tulip_softc_t * const sc);
162 void tulip_21140_accton_media_probe(tulip_softc_t * const sc);
163 void tulip_21140_smc9332_media_probe(tulip_softc_t * const sc);
164 void tulip_21140_cogent_em100_media_probe(tulip_softc_t * const sc);
165 void tulip_21140_znyx_zx34x_media_probe(tulip_softc_t * const sc);
166
167 void tulip_2114x_media_probe(tulip_softc_t * const sc);
168
169 void tulip_delay_300ns(tulip_softc_t * const sc);
170 void tulip_srom_idle(tulip_softc_t * const sc);
171 void tulip_srom_read(tulip_softc_t * const sc);
172 void tulip_mii_writebits(tulip_softc_t * const sc, unsigned data, unsigned bits);
173 void tulip_mii_turnaround(tulip_softc_t * const sc, unsigned cmd);
174 unsigned tulip_mii_readbits(tulip_softc_t * const sc);
175 unsigned tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno);
176 void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno,
177 unsigned data);
178
179 void tulip_identify_dec_nic(tulip_softc_t * const sc);
180 void tulip_identify_znyx_nic(tulip_softc_t * const sc);
181 void tulip_identify_smc_nic(tulip_softc_t * const sc);
182 void tulip_identify_cogent_nic(tulip_softc_t * const sc);
183 void tulip_identify_accton_nic(tulip_softc_t * const sc);
184 void tulip_identify_asante_nic(tulip_softc_t * const sc);
185 void tulip_identify_compex_nic(tulip_softc_t * const sc);
186
187 int tulip_srom_decode(tulip_softc_t * const sc);
188 int tulip_read_macaddr(tulip_softc_t * const sc);
189 void tulip_ifmedia_add(tulip_softc_t * const sc);
190 int tulip_ifmedia_change(struct ifnet * const ifp);
191 void tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req);
192 void tulip_addr_filter(tulip_softc_t * const sc);
193 void tulip_reset(tulip_softc_t * const sc);
194 void tulip_init(tulip_softc_t * const sc);
195 void tulip_rx_intr(tulip_softc_t * const sc);
196 int tulip_tx_intr(tulip_softc_t * const sc);
197 void tulip_print_abnormal_interrupt(tulip_softc_t * const sc, u_int32_t csr);
198 void tulip_intr_handler(tulip_softc_t * const sc, int *progress_p);
199 int tulip_intr_shared(void *arg);
200 int tulip_intr_normal(void *arg);
201 struct mbuf *tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int);
202 void tulip_txput_setup(tulip_softc_t * const sc);
203 int tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data);
204 void tulip_ifstart(struct ifnet *ifp);
205 void tulip_ifwatchdog(struct ifnet *ifp);
206 int tulip_busdma_allocmem(tulip_softc_t * const sc, size_t size,
207 bus_dmamap_t *map_p, tulip_desc_t **desc_p);
208 int tulip_busdma_init(tulip_softc_t * const sc);
209 void tulip_initcsrs(tulip_softc_t * const sc, bus_addr_t csr_base, size_t csr_size);
210 void tulip_initring(tulip_softc_t * const sc, tulip_ringinfo_t * const ri,
211 tulip_desc_t *descs, int ndescs);
212
213 bus_dmamap_t tulip_alloc_rxmap(tulip_softc_t *);
214 void tulip_free_rxmap(tulip_softc_t *, bus_dmamap_t);
215 bus_dmamap_t tulip_alloc_txmap(tulip_softc_t *);
216 void tulip_free_txmap(tulip_softc_t *, bus_dmamap_t);
217
218 void
tulip_timeout_callback(void * arg)219 tulip_timeout_callback(void *arg)
220 {
221 tulip_softc_t * const sc = arg;
222 int s;
223
224 s = splnet();
225
226 TULIP_PERFSTART(timeout)
227
228 sc->tulip_flags &= ~TULIP_TIMEOUTPENDING;
229 sc->tulip_probe_timeout -= 1000 / TULIP_HZ;
230 (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER);
231
232 TULIP_PERFEND(timeout);
233 splx(s);
234 }
235
236 void
tulip_timeout(tulip_softc_t * const sc)237 tulip_timeout(tulip_softc_t * const sc)
238 {
239 if (sc->tulip_flags & TULIP_TIMEOUTPENDING)
240 return;
241 sc->tulip_flags |= TULIP_TIMEOUTPENDING;
242 timeout_add(&sc->tulip_stmo, (hz + TULIP_HZ / 2) / TULIP_HZ);
243 }
244
245 int
tulip_txprobe(tulip_softc_t * const sc)246 tulip_txprobe(tulip_softc_t * const sc)
247 {
248 struct mbuf *m;
249
250 /*
251 * Before we are sure this is the right media we need
252 * to send a small packet to make sure there's carrier.
253 * Strangely, BNC and AUI will "see" receive data if
254 * either is connected so the transmit is the only way
255 * to verify the connectivity.
256 */
257 MGETHDR(m, M_DONTWAIT, MT_DATA);
258 if (m == NULL)
259 return (0);
260 /*
261 * Construct a LLC TEST message which will point to ourselves.
262 */
263 bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_dhost,
264 ETHER_ADDR_LEN);
265 bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_shost,
266 ETHER_ADDR_LEN);
267 mtod(m, struct ether_header *)->ether_type = htons(3);
268 mtod(m, unsigned char *)[14] = 0;
269 mtod(m, unsigned char *)[15] = 0;
270 mtod(m, unsigned char *)[16] = 0xE3; /* LLC Class1 TEST (no poll) */
271 m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
272 /*
273 * send it!
274 */
275 sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
276 sc->tulip_intrmask |= TULIP_STS_TXINTR;
277 sc->tulip_flags |= TULIP_TXPROBE_ACTIVE;
278 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
279 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
280 if ((m = tulip_txput(sc, m, 1)) != NULL)
281 m_freem(m);
282 sc->tulip_probe.probe_txprobes++;
283 return (1);
284 }
285
286 void
tulip_media_set(tulip_softc_t * const sc,tulip_media_t media)287 tulip_media_set(tulip_softc_t * const sc, tulip_media_t media)
288 {
289 const tulip_media_info_t *mi = sc->tulip_mediums[media];
290
291 if (mi == NULL)
292 return;
293
294 /* Reset the SIA first
295 */
296 if (mi->mi_type == TULIP_MEDIAINFO_SIA || (sc->tulip_features & TULIP_HAVE_SIANWAY))
297 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
298
299 /* Next, set full duplex if needed.
300 */
301 if (sc->tulip_flags & TULIP_FULLDUPLEX) {
302 #ifdef TULIP_DEBUG
303 if (TULIP_CSR_READ(sc, csr_command) & (TULIP_CMD_RXRUN|TULIP_CMD_TXRUN))
304 printf(TULIP_PRINTF_FMT ": warning: board is running (FD).\n", TULIP_PRINTF_ARGS);
305 if ((TULIP_CSR_READ(sc, csr_command) & TULIP_CMD_FULLDUPLEX) == 0)
306 printf(TULIP_PRINTF_FMT ": setting full duplex.\n", TULIP_PRINTF_ARGS);
307 #endif
308 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
309 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode & ~(TULIP_CMD_RXRUN|TULIP_CMD_TXRUN));
310 }
311
312 /* Now setup the media.
313 *
314 * If we are switching media, make sure we don't think there's
315 * any stale RX activity
316 */
317 sc->tulip_flags &= ~TULIP_RXACT;
318 if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
319 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, mi->mi_sia_tx_rx);
320 if (sc->tulip_features & TULIP_HAVE_SIAGP) {
321 TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_gp_control|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
322 DELAY(50);
323 TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_gp_data|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
324 } else
325 TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
326 TULIP_CSR_WRITE(sc, csr_sia_connectivity, mi->mi_sia_connectivity);
327 } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) {
328 /*
329 * If the cmdmode bits don't match the currently operating mode,
330 * set the cmdmode appropriately and reset the chip.
331 */
332 if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {
333 sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
334 sc->tulip_cmdmode |= mi->mi_cmdmode;
335 tulip_reset(sc);
336 }
337 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
338 DELAY(10);
339 TULIP_CSR_WRITE(sc, csr_gp, (u_int8_t) mi->mi_gpdata);
340 } else if (mi->mi_type == TULIP_MEDIAINFO_SYM) {
341 /*
342 * If the cmdmode bits don't match the currently operating mode,
343 * set the cmdmode appropriately and reset the chip.
344 */
345 if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {
346 sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
347 sc->tulip_cmdmode |= mi->mi_cmdmode;
348 tulip_reset(sc);
349 }
350 TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpcontrol);
351 TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpdata);
352 } else if (mi->mi_type == TULIP_MEDIAINFO_MII
353 && sc->tulip_probe_state != TULIP_PROBE_INACTIVE) {
354 int idx;
355 if (sc->tulip_features & TULIP_HAVE_SIAGP) {
356 const u_int8_t *dp;
357 dp = &sc->tulip_rombuf[mi->mi_reset_offset];
358 for (idx = 0; idx < mi->mi_reset_length; idx++, dp += 2) {
359 DELAY(10);
360 TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);
361 }
362 sc->tulip_phyaddr = mi->mi_phyaddr;
363 dp = &sc->tulip_rombuf[mi->mi_gpr_offset];
364 for (idx = 0; idx < mi->mi_gpr_length; idx++, dp += 2) {
365 DELAY(10);
366 TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);
367 }
368 } else {
369 for (idx = 0; idx < mi->mi_reset_length; idx++) {
370 DELAY(10);
371 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx]);
372 }
373 sc->tulip_phyaddr = mi->mi_phyaddr;
374 for (idx = 0; idx < mi->mi_gpr_length; idx++) {
375 DELAY(10);
376 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx]);
377 }
378 }
379
380 if (sc->tulip_features & TULIP_HAVE_SIANWAY) {
381 /* Set the SIA port into MII mode */
382 TULIP_CSR_WRITE(sc, csr_sia_general, 1);
383 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, 0);
384 TULIP_CSR_WRITE(sc, csr_sia_status, 0);
385 }
386
387 if (sc->tulip_flags & TULIP_TRYNWAY)
388 tulip_mii_autonegotiate(sc, sc->tulip_phyaddr);
389 else if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) {
390 u_int32_t data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_CONTROL);
391 data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX|PHYCTL_AUTONEG_ENABLE);
392 sc->tulip_flags &= ~TULIP_DIDNWAY;
393 if (TULIP_IS_MEDIA_FD(media))
394 data |= PHYCTL_FULL_DUPLEX;
395 if (TULIP_IS_MEDIA_100MB(media))
396 data |= PHYCTL_SELECT_100MB;
397 tulip_mii_writereg(sc, sc->tulip_phyaddr, PHYREG_CONTROL, data);
398 }
399 }
400 }
401
402 void
tulip_linkup(tulip_softc_t * const sc,tulip_media_t media)403 tulip_linkup(tulip_softc_t * const sc, tulip_media_t media)
404 {
405 if ((sc->tulip_flags & TULIP_LINKUP) == 0)
406 sc->tulip_flags |= TULIP_PRINTLINKUP;
407 sc->tulip_flags |= TULIP_LINKUP;
408 ifq_clr_oactive(&sc->tulip_if.if_snd);
409 if (sc->tulip_media != media) {
410 #ifdef TULIP_DEBUG
411 sc->tulip_dbg.dbg_last_media = sc->tulip_media;
412 #endif
413 sc->tulip_media = media;
414 sc->tulip_flags |= TULIP_PRINTMEDIA;
415 if (TULIP_IS_MEDIA_FD(sc->tulip_media))
416 sc->tulip_flags |= TULIP_FULLDUPLEX;
417 else if (sc->tulip_chipid != TULIP_21041 || (sc->tulip_flags & TULIP_DIDNWAY) == 0)
418 sc->tulip_flags &= ~TULIP_FULLDUPLEX;
419 }
420 /*
421 * We could set probe_timeout to 0 but setting to 3000 puts this
422 * in one central place and the only matters is tulip_link is
423 * followed by a tulip_timeout. Therefore setting it should not
424 * result in aberrant behaviour.
425 */
426 sc->tulip_probe_timeout = 3000;
427 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
428 sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TRYNWAY);
429 if (sc->tulip_flags & TULIP_INRESET)
430 tulip_media_set(sc, sc->tulip_media);
431 else if (sc->tulip_probe_media != sc->tulip_media) {
432 /*
433 * No reason to change media if we have the right media.
434 */
435 tulip_reset(sc);
436 }
437 tulip_init(sc);
438 }
439
440 void
tulip_media_print(tulip_softc_t * const sc)441 tulip_media_print(tulip_softc_t * const sc)
442 {
443 if ((sc->tulip_flags & TULIP_LINKUP) == 0)
444 return;
445 if (sc->tulip_flags & TULIP_PRINTMEDIA) {
446 #ifdef TULIP_DEBUG
447 printf(TULIP_PRINTF_FMT ": enabling %s port\n",
448 TULIP_PRINTF_ARGS,
449 tulip_mediums[sc->tulip_media]);
450 #endif
451 sc->tulip_flags &= ~(TULIP_PRINTMEDIA|TULIP_PRINTLINKUP);
452 } else if (sc->tulip_flags & TULIP_PRINTLINKUP) {
453 #ifdef TULIP_DEBUG
454 printf(TULIP_PRINTF_FMT ": link up\n", TULIP_PRINTF_ARGS);
455 #endif
456 sc->tulip_flags &= ~TULIP_PRINTLINKUP;
457 }
458 }
459
460 tulip_link_status_t
tulip_media_link_monitor(tulip_softc_t * const sc)461 tulip_media_link_monitor(tulip_softc_t * const sc)
462 {
463 const tulip_media_info_t * const mi = sc->tulip_mediums[sc->tulip_media];
464 tulip_link_status_t linkup = TULIP_LINK_DOWN;
465
466 if (mi == NULL) {
467 #if defined(TULIP_DEBUG)
468 printf("tulip_media_link_monitor: %s: botch at line %d\n",
469 tulip_mediums[sc->tulip_media],__LINE__);
470 #endif
471 return (TULIP_LINK_UNKNOWN);
472 }
473
474
475 /*
476 * Have we seen some packets? If so, the link must be good.
477 */
478 if ((sc->tulip_flags & (TULIP_RXACT|TULIP_LINKUP)) == (TULIP_RXACT|TULIP_LINKUP)) {
479 sc->tulip_flags &= ~TULIP_RXACT;
480 sc->tulip_probe_timeout = 3000;
481 return (TULIP_LINK_UP);
482 }
483
484 sc->tulip_flags &= ~TULIP_RXACT;
485 if (mi->mi_type == TULIP_MEDIAINFO_MII) {
486 u_int32_t status;
487 /*
488 * Read the PHY status register.
489 */
490 status = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_STATUS)
491 | tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_STATUS);
492 if (status & PHYSTS_AUTONEG_DONE) {
493 /*
494 * If the PHY has completed autonegotiation, see the if the
495 * remote systems abilities have changed. If so, upgrade or
496 * downgrade as appropriate.
497 */
498 u_int32_t abilities = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_AUTONEG_ABILITIES);
499 abilities = (abilities << 6) & status;
500 if (abilities != sc->tulip_abilities) {
501 #if defined(TULIP_DEBUG)
502 printf(TULIP_PRINTF_FMT "(phy%d): autonegotiation changed: 0x%04x -> 0x%04x\n",
503 TULIP_PRINTF_ARGS, sc->tulip_phyaddr,
504 sc->tulip_abilities, abilities);
505 #endif
506 if (tulip_mii_map_abilities(sc, abilities)) {
507 tulip_linkup(sc, sc->tulip_probe_media);
508 return (TULIP_LINK_UP);
509 }
510 /*
511 * if we had selected media because of autonegotiation,
512 * we need to probe for the new media.
513 */
514 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
515 if (sc->tulip_flags & TULIP_DIDNWAY)
516 return (TULIP_LINK_DOWN);
517 }
518 }
519 /*
520 * The link is now up. If was down, say its back up.
521 */
522 if ((status & (PHYSTS_LINK_UP|PHYSTS_REMOTE_FAULT)) == PHYSTS_LINK_UP)
523 linkup = TULIP_LINK_UP;
524 } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) {
525 /*
526 * No activity sensor? Assume all's well.
527 */
528 if (mi->mi_actmask == 0)
529 return (TULIP_LINK_UNKNOWN);
530 /*
531 * Does the activity data match?
532 */
533 if ((TULIP_CSR_READ(sc, csr_gp) & mi->mi_actmask) == mi->mi_actdata)
534 linkup = TULIP_LINK_UP;
535 } else if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
536 /*
537 * Assume non TP ok for now.
538 */
539 if (!TULIP_IS_MEDIA_TP(sc->tulip_media))
540 return (TULIP_LINK_UNKNOWN);
541 if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) == 0)
542 linkup = TULIP_LINK_UP;
543 #if defined(TULIP_DEBUG)
544 if (sc->tulip_probe_timeout <= 0)
545 printf(TULIP_PRINTF_FMT ": sia status = 0x%08x\n", TULIP_PRINTF_ARGS, TULIP_CSR_READ(sc, csr_sia_status));
546 #endif
547 } else if (mi->mi_type == TULIP_MEDIAINFO_SYM)
548 return (TULIP_LINK_UNKNOWN);
549 /*
550 * We will wait for 3 seconds until the link goes into suspect mode.
551 */
552 if (sc->tulip_flags & TULIP_LINKUP) {
553 if (linkup == TULIP_LINK_UP)
554 sc->tulip_probe_timeout = 3000;
555 if (sc->tulip_probe_timeout > 0)
556 return (TULIP_LINK_UP);
557
558 sc->tulip_flags &= ~TULIP_LINKUP;
559 }
560 #if defined(TULIP_DEBUG)
561 sc->tulip_dbg.dbg_link_downed++;
562 #endif
563 return (TULIP_LINK_DOWN);
564 }
565
566 void
tulip_media_poll(tulip_softc_t * const sc,tulip_mediapoll_event_t event)567 tulip_media_poll(tulip_softc_t * const sc, tulip_mediapoll_event_t event)
568 {
569 #if defined(TULIP_DEBUG)
570 sc->tulip_dbg.dbg_events[event]++;
571 #endif
572 if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE
573 && event == TULIP_MEDIAPOLL_TIMER) {
574 switch (tulip_media_link_monitor(sc)) {
575 case TULIP_LINK_DOWN: {
576 /*
577 * Link Monitor failed. Probe for new media.
578 */
579 event = TULIP_MEDIAPOLL_LINKFAIL;
580 break;
581 }
582 case TULIP_LINK_UP: {
583 /*
584 * Check again soon.
585 */
586 tulip_timeout(sc);
587 return;
588 }
589 case TULIP_LINK_UNKNOWN: {
590 /*
591 * We can't tell so don't bother.
592 */
593 return;
594 }
595 }
596 }
597
598 if (event == TULIP_MEDIAPOLL_LINKFAIL) {
599 if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE) {
600 if (TULIP_DO_AUTOSENSE(sc)) {
601 #if defined(TULIP_DEBUG)
602 sc->tulip_dbg.dbg_link_failures++;
603 #endif
604 sc->tulip_media = TULIP_MEDIA_UNKNOWN;
605 if (sc->tulip_if.if_flags & IFF_UP)
606 tulip_reset(sc); /* restart probe */
607 }
608 return;
609 }
610 #if defined(TULIP_DEBUG)
611 sc->tulip_dbg.dbg_link_pollintrs++;
612 #endif
613 }
614
615 if (event == TULIP_MEDIAPOLL_START) {
616 ifq_set_oactive(&sc->tulip_if.if_snd);
617 if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE)
618 return;
619 sc->tulip_probe_mediamask = 0;
620 sc->tulip_probe_passes = 0;
621 #if defined(TULIP_DEBUG)
622 sc->tulip_dbg.dbg_media_probes++;
623 #endif
624 /*
625 * If the SROM contained an explicit media to use, use it.
626 */
627 sc->tulip_cmdmode &= ~(TULIP_CMD_RXRUN|TULIP_CMD_FULLDUPLEX);
628 sc->tulip_flags |= TULIP_TRYNWAY|TULIP_PROBE1STPASS;
629 sc->tulip_flags &= ~(TULIP_DIDNWAY|TULIP_PRINTMEDIA|TULIP_PRINTLINKUP);
630 /*
631 * connidx is defaulted to a media_unknown type.
632 */
633 sc->tulip_probe_media = tulip_srom_conninfo[sc->tulip_connidx].sc_media;
634 if (sc->tulip_probe_media != TULIP_MEDIA_UNKNOWN) {
635 tulip_linkup(sc, sc->tulip_probe_media);
636 tulip_timeout(sc);
637 return;
638 }
639
640 if (sc->tulip_features & TULIP_HAVE_GPR) {
641 sc->tulip_probe_state = TULIP_PROBE_GPRTEST;
642 sc->tulip_probe_timeout = 2000;
643 } else {
644 sc->tulip_probe_media = TULIP_MEDIA_MAX;
645 sc->tulip_probe_timeout = 0;
646 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
647 }
648 }
649
650 /*
651 * Ignore txprobe failures or spurious callbacks.
652 */
653 if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED
654 && sc->tulip_probe_state != TULIP_PROBE_MEDIATEST) {
655 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
656 return;
657 }
658
659 /*
660 * If we really transmitted a packet, then that's the media we'll use.
661 */
662 if (event == TULIP_MEDIAPOLL_TXPROBE_OK || event == TULIP_MEDIAPOLL_LINKPASS) {
663 if (event == TULIP_MEDIAPOLL_LINKPASS) {
664 /* XXX Check media status just to be sure */
665 sc->tulip_probe_media = TULIP_MEDIA_10BASET;
666 #if defined(TULIP_DEBUG)
667 } else {
668 sc->tulip_dbg.dbg_txprobes_ok[sc->tulip_probe_media]++;
669 #endif
670 }
671 tulip_linkup(sc, sc->tulip_probe_media);
672 tulip_timeout(sc);
673 return;
674 }
675
676 if (sc->tulip_probe_state == TULIP_PROBE_GPRTEST) {
677 /*
678 * Brute force. We cycle through each of the media types
679 * and try to transmit a packet.
680 */
681 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
682 sc->tulip_probe_media = TULIP_MEDIA_MAX;
683 sc->tulip_probe_timeout = 0;
684 tulip_timeout(sc);
685 return;
686 }
687
688 if (sc->tulip_probe_state != TULIP_PROBE_MEDIATEST
689 && (sc->tulip_features & TULIP_HAVE_MII)) {
690 tulip_media_t old_media = sc->tulip_probe_media;
691 tulip_mii_autonegotiate(sc, sc->tulip_phyaddr);
692 switch (sc->tulip_probe_state) {
693 case TULIP_PROBE_FAILED:
694 case TULIP_PROBE_MEDIATEST: {
695 /*
696 * Try the next media.
697 */
698 sc->tulip_probe_mediamask |= sc->tulip_mediums[sc->tulip_probe_media]->mi_mediamask;
699 sc->tulip_probe_timeout = 0;
700 break;
701 }
702 case TULIP_PROBE_PHYAUTONEG: {
703 return;
704 }
705 case TULIP_PROBE_INACTIVE: {
706 /*
707 * Only probe if we autonegotiated a media that hasn't failed.
708 */
709 sc->tulip_probe_timeout = 0;
710 if (sc->tulip_probe_mediamask & TULIP_BIT(sc->tulip_probe_media)) {
711 sc->tulip_probe_media = old_media;
712 break;
713 }
714 tulip_linkup(sc, sc->tulip_probe_media);
715 tulip_timeout(sc);
716 return;
717 }
718 default: {
719 #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
720 printf("tulip_media_poll: botch at line %d\n", __LINE__);
721 #endif
722 break;
723 }
724 }
725 }
726
727 if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED) {
728 #if defined(TULIP_DEBUG)
729 sc->tulip_dbg.dbg_txprobes_failed[sc->tulip_probe_media]++;
730 #endif
731 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
732 return;
733 }
734
735 /*
736 * Switch to another media if we tried this one enough.
737 */
738 if (/* event == TULIP_MEDIAPOLL_TXPROBE_FAILED || */ sc->tulip_probe_timeout <= 0) {
739 #if defined(TULIP_DEBUG)
740 if (sc->tulip_probe_media == TULIP_MEDIA_UNKNOWN) {
741 printf(TULIP_PRINTF_FMT ": poll media unknown!\n",
742 TULIP_PRINTF_ARGS);
743 sc->tulip_probe_media = TULIP_MEDIA_MAX;
744 }
745 #endif
746 /*
747 * Find the next media type to check for. Full Duplex
748 * types are not allowed.
749 */
750 do {
751 sc->tulip_probe_media -= 1;
752 if (sc->tulip_probe_media == TULIP_MEDIA_UNKNOWN) {
753 if (++sc->tulip_probe_passes == 3) {
754 if ((sc->tulip_if.if_flags & IFF_UP) == 0) {
755 sc->tulip_if.if_flags &= ~IFF_RUNNING;
756 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
757 return;
758 }
759 }
760 sc->tulip_flags ^= TULIP_TRYNWAY; /* XXX */
761 sc->tulip_probe_mediamask = 0;
762 sc->tulip_probe_media = TULIP_MEDIA_MAX - 1;
763 }
764 } while (sc->tulip_mediums[sc->tulip_probe_media] == NULL
765 || (sc->tulip_probe_mediamask & TULIP_BIT(sc->tulip_probe_media))
766 || TULIP_IS_MEDIA_FD(sc->tulip_probe_media));
767
768 #if defined(TULIP_DEBUG)
769 printf(TULIP_PRINTF_FMT ": %s: probing %s\n", TULIP_PRINTF_ARGS,
770 event == TULIP_MEDIAPOLL_TXPROBE_FAILED ? "txprobe failed" : "timeout",
771 tulip_mediums[sc->tulip_probe_media]);
772 #endif
773 sc->tulip_probe_timeout = TULIP_IS_MEDIA_TP(sc->tulip_probe_media) ? 2500 : 1000;
774 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
775 sc->tulip_probe.probe_txprobes = 0;
776 tulip_reset(sc);
777 tulip_media_set(sc, sc->tulip_probe_media);
778 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
779 }
780 tulip_timeout(sc);
781
782 /*
783 * If this is hanging off a phy, we know are doing NWAY and we have
784 * forced the phy to a specific speed. Wait for link up before
785 * before sending a packet.
786 */
787 switch (sc->tulip_mediums[sc->tulip_probe_media]->mi_type) {
788 case TULIP_MEDIAINFO_MII: {
789 if (sc->tulip_probe_media != tulip_mii_phy_readspecific(sc))
790 return;
791 break;
792 }
793 case TULIP_MEDIAINFO_SIA: {
794 if (TULIP_IS_MEDIA_TP(sc->tulip_probe_media)) {
795 if (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL)
796 return;
797 tulip_linkup(sc, sc->tulip_probe_media);
798 return;
799 }
800 break;
801 }
802 case TULIP_MEDIAINFO_RESET:
803 case TULIP_MEDIAINFO_SYM:
804 case TULIP_MEDIAINFO_NONE:
805 case TULIP_MEDIAINFO_GPR: {
806 break;
807 }
808 }
809 /*
810 * Try to send a packet.
811 */
812 tulip_txprobe(sc);
813 }
814
815 void
tulip_media_select(tulip_softc_t * const sc)816 tulip_media_select(tulip_softc_t * const sc)
817 {
818 if (sc->tulip_features & TULIP_HAVE_GPR) {
819 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
820 DELAY(10);
821 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_gpdata);
822 }
823 /*
824 * If this board has no media, just return
825 */
826 if (sc->tulip_features & TULIP_HAVE_NOMEDIA)
827 return;
828
829 if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
830 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
831 (*sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_START);
832 } else
833 tulip_media_set(sc, sc->tulip_media);
834 }
835
836 void
tulip_21040_mediainfo_init(tulip_softc_t * const sc,tulip_media_t media)837 tulip_21040_mediainfo_init(tulip_softc_t * const sc, tulip_media_t media)
838 {
839 sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
840 |TULIP_CMD_BACKOFFCTR;
841 sc->tulip_if.if_baudrate = 10000000;
842
843 if (media == TULIP_MEDIA_10BASET || media == TULIP_MEDIA_UNKNOWN) {
844 TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[0], 21040, 10BASET);
845 TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[1], 21040, 10BASET_FD);
846 sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
847 }
848
849 if (media == TULIP_MEDIA_AUIBNC || media == TULIP_MEDIA_UNKNOWN)
850 TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[2], 21040, AUIBNC);
851
852 if (media == TULIP_MEDIA_UNKNOWN)
853 TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[3], 21040, EXTSIA);
854 }
855
856 void
tulip_21040_media_probe(tulip_softc_t * const sc)857 tulip_21040_media_probe(tulip_softc_t * const sc)
858 {
859 tulip_21040_mediainfo_init(sc, TULIP_MEDIA_UNKNOWN);
860 }
861
862 void
tulip_21040_10baset_only_media_probe(tulip_softc_t * const sc)863 tulip_21040_10baset_only_media_probe(tulip_softc_t * const sc)
864 {
865 tulip_21040_mediainfo_init(sc, TULIP_MEDIA_10BASET);
866 tulip_media_set(sc, TULIP_MEDIA_10BASET);
867 sc->tulip_media = TULIP_MEDIA_10BASET;
868 }
869
870 void
tulip_21040_10baset_only_media_select(tulip_softc_t * const sc)871 tulip_21040_10baset_only_media_select(tulip_softc_t * const sc)
872 {
873 sc->tulip_flags |= TULIP_LINKUP;
874 if (sc->tulip_media == TULIP_MEDIA_10BASET_FD) {
875 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
876 sc->tulip_flags &= ~TULIP_SQETEST;
877 } else {
878 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
879 sc->tulip_flags |= TULIP_SQETEST;
880 }
881 tulip_media_set(sc, sc->tulip_media);
882 }
883
884 void
tulip_21040_auibnc_only_media_probe(tulip_softc_t * const sc)885 tulip_21040_auibnc_only_media_probe(tulip_softc_t * const sc)
886 {
887 tulip_21040_mediainfo_init(sc, TULIP_MEDIA_AUIBNC);
888 sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP;
889 tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
890 sc->tulip_media = TULIP_MEDIA_AUIBNC;
891 }
892
893 void
tulip_21040_auibnc_only_media_select(tulip_softc_t * const sc)894 tulip_21040_auibnc_only_media_select(tulip_softc_t * const sc)
895 {
896 tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
897 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
898 }
899
900 static const tulip_boardsw_t tulip_21040_boardsw = {
901 TULIP_21040_GENERIC,
902 tulip_21040_media_probe,
903 tulip_media_select,
904 tulip_media_poll,
905 };
906
907 static const tulip_boardsw_t tulip_21040_10baset_only_boardsw = {
908 TULIP_21040_GENERIC,
909 tulip_21040_10baset_only_media_probe,
910 tulip_21040_10baset_only_media_select,
911 NULL,
912 };
913
914 static const tulip_boardsw_t tulip_21040_auibnc_only_boardsw = {
915 TULIP_21040_GENERIC,
916 tulip_21040_auibnc_only_media_probe,
917 tulip_21040_auibnc_only_media_select,
918 NULL,
919 };
920
921 void
tulip_21041_mediainfo_init(tulip_softc_t * const sc)922 tulip_21041_mediainfo_init(tulip_softc_t * const sc)
923 {
924 tulip_media_info_t * const mi = sc->tulip_mediainfo;
925
926 TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041, 10BASET);
927 TULIP_MEDIAINFO_SIA_INIT(sc, &mi[1], 21041, 10BASET_FD);
928 TULIP_MEDIAINFO_SIA_INIT(sc, &mi[2], 21041, AUI);
929 TULIP_MEDIAINFO_SIA_INIT(sc, &mi[3], 21041, BNC);
930 }
931
932 void
tulip_21041_media_probe(tulip_softc_t * const sc)933 tulip_21041_media_probe(tulip_softc_t * const sc)
934 {
935 sc->tulip_if.if_baudrate = 10000000;
936 sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT
937 |TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR;
938 sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
939 tulip_21041_mediainfo_init(sc);
940 }
941
942 void
tulip_21041_media_poll(tulip_softc_t * const sc,const tulip_mediapoll_event_t event)943 tulip_21041_media_poll(tulip_softc_t * const sc, const tulip_mediapoll_event_t event)
944 {
945 u_int32_t sia_status;
946
947 #if defined(TULIP_DEBUG)
948 sc->tulip_dbg.dbg_events[event]++;
949 #endif
950
951 if (event == TULIP_MEDIAPOLL_LINKFAIL) {
952 if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE
953 || !TULIP_DO_AUTOSENSE(sc))
954 return;
955 sc->tulip_media = TULIP_MEDIA_UNKNOWN;
956 tulip_reset(sc); /* start probe */
957 return;
958 }
959
960 /*
961 * If we've been asked to start a poll or link change interrupt
962 * restart the probe (and reset the tulip to a known state).
963 */
964 if (event == TULIP_MEDIAPOLL_START) {
965 ifq_set_oactive(&sc->tulip_if.if_snd);
966 sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_RXRUN);
967 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
968 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
969 sc->tulip_probe_media = TULIP_MEDIA_10BASET;
970 sc->tulip_probe_timeout = TULIP_21041_PROBE_10BASET_TIMEOUT;
971 tulip_media_set(sc, TULIP_MEDIA_10BASET);
972 tulip_timeout(sc);
973 return;
974 }
975
976 if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
977 return;
978
979 if (event == TULIP_MEDIAPOLL_TXPROBE_OK) {
980 #if defined(TULIP_DEBUG)
981 sc->tulip_dbg.dbg_txprobes_ok[sc->tulip_probe_media]++;
982 #endif
983 tulip_linkup(sc, sc->tulip_probe_media);
984 return;
985 }
986
987 sia_status = TULIP_CSR_READ(sc, csr_sia_status);
988 TULIP_CSR_WRITE(sc, csr_sia_status, sia_status);
989 if ((sia_status & TULIP_SIASTS_LINKFAIL) == 0) {
990 if (sc->tulip_revinfo >= 0x20) {
991 if (sia_status & (PHYSTS_10BASET_FD << (16 - 6)))
992 sc->tulip_probe_media = TULIP_MEDIA_10BASET_FD;
993 }
994 /*
995 * If the link has passed LinkPass, 10baseT is the
996 * proper media to use.
997 */
998 tulip_linkup(sc, sc->tulip_probe_media);
999 return;
1000 }
1001
1002 /*
1003 * wait for up to 2.4 seconds for the link to reach pass state.
1004 * Only then start scanning the other media for activity.
1005 * choose media with receive activity over those without.
1006 */
1007 if (sc->tulip_probe_media == TULIP_MEDIA_10BASET) {
1008 if (event != TULIP_MEDIAPOLL_TIMER)
1009 return;
1010 if (sc->tulip_probe_timeout > 0
1011 && (sia_status & TULIP_SIASTS_OTHERRXACTIVITY) == 0) {
1012 tulip_timeout(sc);
1013 return;
1014 }
1015 sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1016 sc->tulip_flags |= TULIP_WANTRXACT;
1017 if (sia_status & TULIP_SIASTS_OTHERRXACTIVITY)
1018 sc->tulip_probe_media = TULIP_MEDIA_BNC;
1019 else
1020 sc->tulip_probe_media = TULIP_MEDIA_AUI;
1021 tulip_media_set(sc, sc->tulip_probe_media);
1022 tulip_timeout(sc);
1023 return;
1024 }
1025
1026 /*
1027 * If we failed, clear the txprobe active flag.
1028 */
1029 if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED)
1030 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1031
1032
1033 if (event == TULIP_MEDIAPOLL_TIMER) {
1034 /*
1035 * If we've received something, then that's our link!
1036 */
1037 if (sc->tulip_flags & TULIP_RXACT) {
1038 tulip_linkup(sc, sc->tulip_probe_media);
1039 return;
1040 }
1041 /*
1042 * if no txprobe active
1043 */
1044 if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0
1045 && ((sc->tulip_flags & TULIP_WANTRXACT) == 0
1046 || (sia_status & TULIP_SIASTS_RXACTIVITY))) {
1047 sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1048 tulip_txprobe(sc);
1049 tulip_timeout(sc);
1050 return;
1051 }
1052 /*
1053 * Take 2 passes through before deciding to not
1054 * wait for receive activity. Then take another
1055 * two passes before spitting out a warning.
1056 */
1057 if (sc->tulip_probe_timeout <= 0) {
1058 if (sc->tulip_flags & TULIP_WANTRXACT) {
1059 sc->tulip_flags &= ~TULIP_WANTRXACT;
1060 sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1061 } else {
1062 if ((sc->tulip_if.if_flags & IFF_UP) == 0) {
1063 sc->tulip_if.if_flags &= ~IFF_RUNNING;
1064 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1065 return;
1066 }
1067 }
1068 }
1069 }
1070
1071 /*
1072 * Since this media failed to probe, try the other one.
1073 */
1074 sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1075 if (sc->tulip_probe_media == TULIP_MEDIA_AUI)
1076 sc->tulip_probe_media = TULIP_MEDIA_BNC;
1077 else
1078 sc->tulip_probe_media = TULIP_MEDIA_AUI;
1079 tulip_media_set(sc, sc->tulip_probe_media);
1080 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1081 tulip_timeout(sc);
1082 }
1083
1084 static const tulip_boardsw_t tulip_21041_boardsw = {
1085 TULIP_21041_GENERIC,
1086 tulip_21041_media_probe,
1087 tulip_media_select,
1088 tulip_21041_media_poll
1089 };
1090
1091 static const tulip_phy_attr_t tulip_mii_phy_attrlist[] = {
1092 { 0x20005c00, 0, /* 08-00-17 */
1093 {
1094 { 0x19, 0x0040, 0x0040 }, /* 10TX */
1095 { 0x19, 0x0040, 0x0000 }, /* 100TX */
1096 },
1097 #if defined(TULIP_DEBUG)
1098 "NS DP83840",
1099 #endif
1100 },
1101 { 0x0281F400, 0, /* 00-A0-7D */
1102 {
1103 { 0x12, 0x0010, 0x0000 }, /* 10T */
1104 { 0 }, /* 100TX */
1105 { 0x12, 0x0010, 0x0010 }, /* 100T4 */
1106 { 0x12, 0x0008, 0x0008 }, /* FULL_DUPLEX */
1107 },
1108 #if defined(TULIP_DEBUG)
1109 "Seeq 80C240"
1110 #endif
1111 },
1112 { 0x0281F400, 3, /* 00-A0-7D */
1113 {
1114 { 0x12, 0x0080, 0x0000 }, /* 10T */
1115 { 0x12, 0x0080, 0x0080 }, /* 100TX */
1116 { 0 }, /* 100T4 */
1117 { 0x12, 0x0040, 0x0040 }, /* FULL_DUPLEX */
1118 },
1119 #if defined(TULIP_DEBUG)
1120 "Seeq 80225"
1121 #endif
1122 },
1123 { 0x0281F400, 0, /* 00-A0-BE */
1124 {
1125 { 0x11, 0x8000, 0x0000 }, /* 10T */
1126 { 0x11, 0x8000, 0x8000 }, /* 100TX */
1127 { 0 }, /* 100T4 */
1128 { 0x11, 0x4000, 0x4000 }, /* FULL_DUPLEX */
1129 },
1130 #if defined(TULIP_DEBUG)
1131 "ICS 1890"
1132 #endif
1133 },
1134 { 0x78100000, 0, /* 00-A0-CC */
1135 {
1136 { 0x14, 0x0800, 0x0000 }, /* 10TX */
1137 { 0x14, 0x0800, 0x0800 }, /* 100TX */
1138 { 0 }, /* 100T4 */
1139 { 0x14, 0x1000, 0x1000 }, /* FULL_DUPLEX */
1140 },
1141 #if defined(TULIP_DEBUG)
1142 "LEVEL1 LXT970"
1143 #endif
1144 },
1145 { 0 }
1146 };
1147
1148 tulip_media_t
tulip_mii_phy_readspecific(tulip_softc_t * const sc)1149 tulip_mii_phy_readspecific(tulip_softc_t * const sc)
1150 {
1151 const tulip_phy_attr_t *attr;
1152 u_int16_t data;
1153 u_int32_t id;
1154 unsigned idx = 0;
1155 static const tulip_media_t table[] = {
1156 TULIP_MEDIA_UNKNOWN,
1157 TULIP_MEDIA_10BASET,
1158 TULIP_MEDIA_100BASETX,
1159 TULIP_MEDIA_100BASET4,
1160 TULIP_MEDIA_UNKNOWN,
1161 TULIP_MEDIA_10BASET_FD,
1162 TULIP_MEDIA_100BASETX_FD,
1163 TULIP_MEDIA_UNKNOWN
1164 };
1165
1166 /*
1167 * Don't read phy specific registers if link is not up.
1168 */
1169 data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_STATUS)
1170 | tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_STATUS);
1171 if ((data & (PHYSTS_LINK_UP|PHYSTS_EXTENDED_REGS)) != (PHYSTS_LINK_UP|PHYSTS_EXTENDED_REGS))
1172 return (TULIP_MEDIA_UNKNOWN);
1173
1174 id = (tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_IDLOW) << 16) |
1175 tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_IDHIGH);
1176 for (attr = tulip_mii_phy_attrlist;; attr++) {
1177 if (attr->attr_id == 0)
1178 return (TULIP_MEDIA_UNKNOWN);
1179 if ((id & ~0x0F) == attr->attr_id)
1180 break;
1181 }
1182
1183 if (attr->attr_modes[PHY_MODE_100TX].pm_regno) {
1184 const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100TX];
1185 data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
1186 if ((data & pm->pm_mask) == pm->pm_value)
1187 idx = 2;
1188 }
1189 if (idx == 0 && attr->attr_modes[PHY_MODE_100T4].pm_regno) {
1190 const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100T4];
1191 data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
1192 if ((data & pm->pm_mask) == pm->pm_value)
1193 idx = 3;
1194 }
1195 if (idx == 0 && attr->attr_modes[PHY_MODE_10T].pm_regno) {
1196 const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_10T];
1197 data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
1198 if ((data & pm->pm_mask) == pm->pm_value)
1199 idx = 1;
1200 }
1201 if (idx != 0 && attr->attr_modes[PHY_MODE_FULLDUPLEX].pm_regno) {
1202 const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_FULLDUPLEX];
1203 data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
1204 idx += ((data & pm->pm_mask) == pm->pm_value ? 4 : 0);
1205 }
1206 return (table[idx]);
1207 }
1208
1209 unsigned
tulip_mii_get_phyaddr(tulip_softc_t * const sc,unsigned offset)1210 tulip_mii_get_phyaddr(tulip_softc_t * const sc, unsigned offset)
1211 {
1212 unsigned phyaddr;
1213
1214 for (phyaddr = 1; phyaddr < 32; phyaddr++) {
1215 unsigned status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
1216 if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
1217 continue;
1218 if (offset == 0)
1219 return (phyaddr);
1220 offset--;
1221 }
1222 if (offset == 0) {
1223 unsigned status = tulip_mii_readreg(sc, 0, PHYREG_STATUS);
1224 if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
1225 return (TULIP_MII_NOPHY);
1226 return (0);
1227 }
1228 return (TULIP_MII_NOPHY);
1229 }
1230
1231 int
tulip_mii_map_abilities(tulip_softc_t * const sc,unsigned abilities)1232 tulip_mii_map_abilities(tulip_softc_t * const sc, unsigned abilities)
1233 {
1234 sc->tulip_abilities = abilities;
1235 if (abilities & PHYSTS_100BASETX_FD)
1236 sc->tulip_probe_media = TULIP_MEDIA_100BASETX_FD;
1237 else if (abilities & PHYSTS_100BASET4)
1238 sc->tulip_probe_media = TULIP_MEDIA_100BASET4;
1239 else if (abilities & PHYSTS_100BASETX)
1240 sc->tulip_probe_media = TULIP_MEDIA_100BASETX;
1241 else if (abilities & PHYSTS_10BASET_FD)
1242 sc->tulip_probe_media = TULIP_MEDIA_10BASET_FD;
1243 else if (abilities & PHYSTS_10BASET)
1244 sc->tulip_probe_media = TULIP_MEDIA_10BASET;
1245 else {
1246 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1247 return (0);
1248 }
1249 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1250 return (1);
1251 }
1252
1253 void
tulip_mii_autonegotiate(tulip_softc_t * const sc,const unsigned phyaddr)1254 tulip_mii_autonegotiate(tulip_softc_t * const sc, const unsigned phyaddr)
1255 {
1256 switch (sc->tulip_probe_state) {
1257 case TULIP_PROBE_MEDIATEST:
1258 case TULIP_PROBE_INACTIVE: {
1259 sc->tulip_flags |= TULIP_DIDNWAY;
1260 tulip_mii_writereg(sc, phyaddr, PHYREG_CONTROL, PHYCTL_RESET);
1261 sc->tulip_probe_timeout = 3000;
1262 sc->tulip_intrmask |= TULIP_STS_ABNRMLINTR|TULIP_STS_NORMALINTR;
1263 sc->tulip_probe_state = TULIP_PROBE_PHYRESET;
1264 /* FALLTHROUGH */
1265 }
1266 case TULIP_PROBE_PHYRESET: {
1267 u_int32_t status;
1268 u_int32_t data = tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL);
1269 if (data & PHYCTL_RESET) {
1270 if (sc->tulip_probe_timeout > 0) {
1271 tulip_timeout(sc);
1272 return;
1273 }
1274 #ifdef TULIP_DEBUG
1275 printf(TULIP_PRINTF_FMT "(phy%d): error: reset of PHY never completed!\n",
1276 TULIP_PRINTF_ARGS, phyaddr);
1277 #endif
1278 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1279 sc->tulip_probe_state = TULIP_PROBE_FAILED;
1280 sc->tulip_if.if_flags &= ~IFF_RUNNING;
1281 return;
1282 }
1283 status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS)
1284 | tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
1285 if ((status & PHYSTS_CAN_AUTONEG) == 0) {
1286 #if defined(TULIP_DEBUG)
1287 printf(TULIP_PRINTF_FMT "(phy%d): autonegotiation disabled\n",
1288 TULIP_PRINTF_ARGS, phyaddr);
1289 #endif
1290 sc->tulip_flags &= ~TULIP_DIDNWAY;
1291 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1292 return;
1293 }
1294 if (tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ADVERTISEMENT) != ((status >> 6) | 0x01))
1295 tulip_mii_writereg(sc, phyaddr, PHYREG_AUTONEG_ADVERTISEMENT, (status >> 6) | 0x01);
1296 tulip_mii_writereg(sc, phyaddr, PHYREG_CONTROL, data|PHYCTL_AUTONEG_RESTART|PHYCTL_AUTONEG_ENABLE);
1297 data = tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL);
1298 #if defined(TULIP_DEBUG)
1299 if ((data & PHYCTL_AUTONEG_ENABLE) == 0)
1300 printf(TULIP_PRINTF_FMT "(phy%d): oops: enable autonegotiation failed: 0x%04x\n",
1301 TULIP_PRINTF_ARGS, phyaddr, data);
1302 else
1303 printf(TULIP_PRINTF_FMT "(phy%d): autonegotiation restarted: 0x%04x (ad=0x%04x)\n",
1304 TULIP_PRINTF_ARGS, phyaddr, data,
1305 tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ADVERTISEMENT));
1306 sc->tulip_dbg.dbg_nway_starts++;
1307 #endif
1308 sc->tulip_probe_state = TULIP_PROBE_PHYAUTONEG;
1309 sc->tulip_probe_timeout = 3000;
1310 /* FALLTHROUGH */
1311 }
1312 case TULIP_PROBE_PHYAUTONEG: {
1313 u_int32_t status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS)
1314 | tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
1315 u_int32_t data;
1316 if ((status & PHYSTS_AUTONEG_DONE) == 0) {
1317 if (sc->tulip_probe_timeout > 0) {
1318 tulip_timeout(sc);
1319 return;
1320 }
1321 #if defined(TULIP_DEBUG)
1322 printf(TULIP_PRINTF_FMT "(phy%d): autonegotiation timeout: sts=0x%04x, ctl=0x%04x\n",
1323 TULIP_PRINTF_ARGS, phyaddr, status,
1324 tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL));
1325 #endif
1326 sc->tulip_flags &= ~TULIP_DIDNWAY;
1327 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1328 return;
1329 }
1330 data = tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ABILITIES)
1331 | tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ABILITIES);
1332 #if defined(TULIP_DEBUG)
1333 printf(TULIP_PRINTF_FMT "(phy%d): autonegotiation complete: 0x%04x (sts=0x%04x)\n",
1334 TULIP_PRINTF_ARGS, phyaddr, data, status);
1335 #endif
1336 data = (data << 6) & status;
1337 if (!tulip_mii_map_abilities(sc, data))
1338 sc->tulip_flags &= ~TULIP_DIDNWAY;
1339 return;
1340 }
1341 default: {
1342 #if defined(DIAGNOSTIC)
1343 printf("tulip_media_poll: botch at line %d\n", __LINE__);
1344 #endif
1345 break;
1346 }
1347 }
1348 #if defined(TULIP_DEBUG)
1349 printf(TULIP_PRINTF_FMT "(phy%d): autonegotiation failure: state = %d\n",
1350 TULIP_PRINTF_ARGS, phyaddr, sc->tulip_probe_state);
1351 sc->tulip_dbg.dbg_nway_failures++;
1352 #endif
1353 }
1354
1355 void
tulip_2114x_media_preset(tulip_softc_t * const sc)1356 tulip_2114x_media_preset(tulip_softc_t * const sc)
1357 {
1358 const tulip_media_info_t *mi = NULL;
1359 tulip_media_t media = sc->tulip_media;
1360
1361 if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
1362 media = sc->tulip_media;
1363 else
1364 media = sc->tulip_probe_media;
1365
1366 sc->tulip_cmdmode &= ~(TULIP_CMD_PORTSELECT|TULIP_CMD_NOHEARTBEAT
1367 |TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL);
1368 sc->tulip_flags &= ~(TULIP_SQETEST|TULIP_FULLDUPLEX);
1369 if (media != TULIP_MEDIA_UNKNOWN && media != TULIP_MEDIA_MAX) {
1370 #if defined(TULIP_DEBUG)
1371 if (media < TULIP_MEDIA_MAX && sc->tulip_mediums[media] != NULL) {
1372 #endif
1373 mi = sc->tulip_mediums[media];
1374 if (mi->mi_type == TULIP_MEDIAINFO_MII)
1375 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT;
1376 else if (mi->mi_type == TULIP_MEDIAINFO_GPR
1377 || mi->mi_type == TULIP_MEDIAINFO_SYM) {
1378 sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
1379 sc->tulip_cmdmode |= mi->mi_cmdmode;
1380 } else if (mi->mi_type == TULIP_MEDIAINFO_SIA)
1381 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1382 #if defined(TULIP_DEBUG)
1383 } else {
1384 printf(TULIP_PRINTF_FMT ": preset: bad media %d!\n",
1385 TULIP_PRINTF_ARGS, media);
1386 }
1387 #endif
1388 }
1389 switch (media) {
1390 case TULIP_MEDIA_BNC:
1391 case TULIP_MEDIA_AUI:
1392 case TULIP_MEDIA_10BASET: {
1393 sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL;
1394 sc->tulip_if.if_baudrate = 10000000;
1395 sc->tulip_flags |= TULIP_SQETEST;
1396 break;
1397 }
1398 case TULIP_MEDIA_10BASET_FD: {
1399 sc->tulip_flags |= TULIP_FULLDUPLEX;
1400 sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX;
1401 sc->tulip_if.if_baudrate = 10000000;
1402 break;
1403 }
1404 case TULIP_MEDIA_100BASEFX:
1405 case TULIP_MEDIA_100BASET4:
1406 case TULIP_MEDIA_100BASETX: {
1407 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT;
1408 sc->tulip_if.if_baudrate = 100000000;
1409 if (mi->mi_type == TULIP_MEDIAINFO_SYM
1410 || mi->mi_type == TULIP_MEDIAINFO_MII) {
1411 sc->tulip_cmdmode |= TULIP_CMD_NOHEARTBEAT;
1412 }
1413 break;
1414 }
1415 case TULIP_MEDIA_100BASEFX_FD:
1416 case TULIP_MEDIA_100BASETX_FD: {
1417 sc->tulip_flags |= TULIP_FULLDUPLEX;
1418 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT|TULIP_CMD_FULLDUPLEX;
1419 sc->tulip_if.if_baudrate = 100000000;
1420 if (mi->mi_type == TULIP_MEDIAINFO_SYM
1421 || mi->mi_type == TULIP_MEDIAINFO_MII) {
1422 sc->tulip_cmdmode |= TULIP_CMD_NOHEARTBEAT;
1423 }
1424 break;
1425 }
1426 default: {
1427 break;
1428 }
1429 }
1430 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
1431 }
1432
1433 /*
1434 ********************************************************************
1435 * Start of 21140/21140A support which does not use the MII interface
1436 */
1437
1438 void
tulip_null_media_poll(tulip_softc_t * const sc,tulip_mediapoll_event_t event)1439 tulip_null_media_poll(tulip_softc_t * const sc, tulip_mediapoll_event_t event)
1440 {
1441 #if defined(TULIP_DEBUG)
1442 sc->tulip_dbg.dbg_events[event]++;
1443 #endif
1444 #if defined(DIAGNOSTIC)
1445 printf(TULIP_PRINTF_FMT ": botch(media_poll) at line %d\n",
1446 TULIP_PRINTF_ARGS, __LINE__);
1447 #endif
1448 }
1449
1450 void
tulip_21140_mediainit(tulip_softc_t * const sc,tulip_media_info_t * const mip,tulip_media_t const media,unsigned gpdata,unsigned cmdmode)1451 tulip_21140_mediainit(tulip_softc_t * const sc, tulip_media_info_t * const mip,
1452 tulip_media_t const media, unsigned gpdata, unsigned cmdmode)
1453 {
1454 sc->tulip_mediums[media] = mip;
1455 mip->mi_type = TULIP_MEDIAINFO_GPR;
1456 mip->mi_cmdmode = cmdmode;
1457 mip->mi_gpdata = gpdata;
1458 }
1459
1460 void
tulip_21140_evalboard_media_probe(tulip_softc_t * const sc)1461 tulip_21140_evalboard_media_probe(tulip_softc_t * const sc)
1462 {
1463 tulip_media_info_t *mip = sc->tulip_mediainfo;
1464
1465 sc->tulip_gpinit = TULIP_GP_EB_PINS;
1466 sc->tulip_gpdata = TULIP_GP_EB_INIT;
1467 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
1468 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
1469 TULIP_CSR_WRITE(sc, csr_command,
1470 TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1471 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1472 TULIP_CSR_WRITE(sc, csr_command,
1473 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1474 DELAY(1000000);
1475 if ((TULIP_CSR_READ(sc, csr_gp) & TULIP_GP_EB_OK100) != 0)
1476 sc->tulip_media = TULIP_MEDIA_10BASET;
1477 else
1478 sc->tulip_media = TULIP_MEDIA_100BASETX;
1479 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1480 TULIP_GP_EB_INIT,
1481 TULIP_CMD_TXTHRSHLDCTL);
1482 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1483 TULIP_GP_EB_INIT,
1484 TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1485 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1486 TULIP_GP_EB_INIT,
1487 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1488 |TULIP_CMD_SCRAMBLER);
1489 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1490 TULIP_GP_EB_INIT,
1491 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1492 |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1493 }
1494
1495 static const tulip_boardsw_t tulip_21140_eb_boardsw = {
1496 TULIP_21140_DEC_EB,
1497 tulip_21140_evalboard_media_probe,
1498 tulip_media_select,
1499 tulip_null_media_poll,
1500 tulip_2114x_media_preset,
1501 };
1502
1503 void
tulip_21140_accton_media_probe(tulip_softc_t * const sc)1504 tulip_21140_accton_media_probe(tulip_softc_t * const sc)
1505 {
1506 tulip_media_info_t *mip = sc->tulip_mediainfo;
1507 unsigned gpdata;
1508
1509 sc->tulip_gpinit = TULIP_GP_EB_PINS;
1510 sc->tulip_gpdata = TULIP_GP_EB_INIT;
1511 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
1512 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
1513 TULIP_CSR_WRITE(sc, csr_command,
1514 TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1515 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1516 TULIP_CSR_WRITE(sc, csr_command,
1517 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1518 DELAY(1000000);
1519 gpdata = TULIP_CSR_READ(sc, csr_gp);
1520 if ((gpdata & TULIP_GP_EN1207_UTP_INIT) == 0)
1521 sc->tulip_media = TULIP_MEDIA_10BASET;
1522 else {
1523 if ((gpdata & TULIP_GP_EN1207_BNC_INIT) == 0)
1524 sc->tulip_media = TULIP_MEDIA_BNC;
1525 else
1526 sc->tulip_media = TULIP_MEDIA_100BASETX;
1527 }
1528 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_BNC,
1529 TULIP_GP_EN1207_BNC_INIT,
1530 TULIP_CMD_TXTHRSHLDCTL);
1531 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1532 TULIP_GP_EN1207_UTP_INIT,
1533 TULIP_CMD_TXTHRSHLDCTL);
1534 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1535 TULIP_GP_EN1207_UTP_INIT,
1536 TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1537 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1538 TULIP_GP_EN1207_100_INIT,
1539 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1540 |TULIP_CMD_SCRAMBLER);
1541 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1542 TULIP_GP_EN1207_100_INIT,
1543 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1544 |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1545 }
1546
1547 static const tulip_boardsw_t tulip_21140_accton_boardsw = {
1548 TULIP_21140_EN1207,
1549 tulip_21140_accton_media_probe,
1550 tulip_media_select,
1551 tulip_null_media_poll,
1552 tulip_2114x_media_preset,
1553 };
1554
1555 void
tulip_21140_smc9332_media_probe(tulip_softc_t * const sc)1556 tulip_21140_smc9332_media_probe(tulip_softc_t * const sc)
1557 {
1558 tulip_media_info_t *mip = sc->tulip_mediainfo;
1559 int idx, cnt = 0;
1560
1561 TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT|TULIP_CMD_MUSTBEONE);
1562 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
1563 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
1564 33MHz that comes to two microseconds but wait a
1565 bit longer anyways) */
1566 TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT |
1567 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1568 sc->tulip_gpinit = TULIP_GP_SMC_9332_PINS;
1569 sc->tulip_gpdata = TULIP_GP_SMC_9332_INIT;
1570 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_PINS|TULIP_GP_PINSET);
1571 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_INIT);
1572 DELAY(200000);
1573 for (idx = 1000; idx > 0; idx--) {
1574 u_int32_t csr = TULIP_CSR_READ(sc, csr_gp);
1575 if ((csr & (TULIP_GP_SMC_9332_OK10|TULIP_GP_SMC_9332_OK100)) == (TULIP_GP_SMC_9332_OK10|TULIP_GP_SMC_9332_OK100)) {
1576 if (++cnt > 100)
1577 break;
1578 } else if ((csr & TULIP_GP_SMC_9332_OK10) == 0)
1579 break;
1580 else
1581 cnt = 0;
1582 DELAY(1000);
1583 }
1584 sc->tulip_media = cnt > 100 ? TULIP_MEDIA_100BASETX : TULIP_MEDIA_10BASET;
1585 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1586 TULIP_GP_SMC_9332_INIT,
1587 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1588 |TULIP_CMD_SCRAMBLER);
1589 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1590 TULIP_GP_SMC_9332_INIT,
1591 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1592 |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1593 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1594 TULIP_GP_SMC_9332_INIT,
1595 TULIP_CMD_TXTHRSHLDCTL);
1596 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1597 TULIP_GP_SMC_9332_INIT,
1598 TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1599 }
1600
1601 static const tulip_boardsw_t tulip_21140_smc9332_boardsw = {
1602 TULIP_21140_SMC_9332,
1603 tulip_21140_smc9332_media_probe,
1604 tulip_media_select,
1605 tulip_null_media_poll,
1606 tulip_2114x_media_preset,
1607 };
1608
1609 void
tulip_21140_cogent_em100_media_probe(tulip_softc_t * const sc)1610 tulip_21140_cogent_em100_media_probe(tulip_softc_t * const sc)
1611 {
1612 tulip_media_info_t *mip = sc->tulip_mediainfo;
1613 u_int32_t cmdmode = TULIP_CSR_READ(sc, csr_command);
1614
1615 sc->tulip_gpinit = TULIP_GP_EM100_PINS;
1616 sc->tulip_gpdata = TULIP_GP_EM100_INIT;
1617 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS);
1618 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_INIT);
1619
1620 cmdmode = TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_MUSTBEONE;
1621 cmdmode &= ~(TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_SCRAMBLER);
1622 if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100FX_ID) {
1623 TULIP_CSR_WRITE(sc, csr_command, cmdmode);
1624 sc->tulip_media = TULIP_MEDIA_100BASEFX;
1625
1626 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASEFX,
1627 TULIP_GP_EM100_INIT,
1628 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION);
1629 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASEFX_FD,
1630 TULIP_GP_EM100_INIT,
1631 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1632 |TULIP_CMD_FULLDUPLEX);
1633 } else {
1634 TULIP_CSR_WRITE(sc, csr_command, cmdmode|TULIP_CMD_SCRAMBLER);
1635 sc->tulip_media = TULIP_MEDIA_100BASETX;
1636 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1637 TULIP_GP_EM100_INIT,
1638 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1639 |TULIP_CMD_SCRAMBLER);
1640 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1641 TULIP_GP_EM100_INIT,
1642 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1643 |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1644 }
1645 }
1646
1647 static const tulip_boardsw_t tulip_21140_cogent_em100_boardsw = {
1648 TULIP_21140_COGENT_EM100,
1649 tulip_21140_cogent_em100_media_probe,
1650 tulip_media_select,
1651 tulip_null_media_poll,
1652 tulip_2114x_media_preset
1653 };
1654
1655 void
tulip_21140_znyx_zx34x_media_probe(tulip_softc_t * const sc)1656 tulip_21140_znyx_zx34x_media_probe(tulip_softc_t * const sc)
1657 {
1658 tulip_media_info_t *mip = sc->tulip_mediainfo;
1659 int cnt10 = 0, cnt100 = 0, idx;
1660
1661 sc->tulip_gpinit = TULIP_GP_ZX34X_PINS;
1662 sc->tulip_gpdata = TULIP_GP_ZX34X_INIT;
1663 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS);
1664 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_INIT);
1665 TULIP_CSR_WRITE(sc, csr_command,
1666 TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1667 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1668 TULIP_CSR_WRITE(sc, csr_command,
1669 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1670
1671 DELAY(200000);
1672 for (idx = 1000; idx > 0; idx--) {
1673 u_int32_t csr = TULIP_CSR_READ(sc, csr_gp);
1674 if ((csr & (TULIP_GP_ZX34X_LNKFAIL|TULIP_GP_ZX34X_SYMDET|TULIP_GP_ZX34X_SIGDET)) == (TULIP_GP_ZX34X_LNKFAIL|TULIP_GP_ZX34X_SYMDET|TULIP_GP_ZX34X_SIGDET)) {
1675 if (++cnt100 > 100)
1676 break;
1677 } else if ((csr & TULIP_GP_ZX34X_LNKFAIL) == 0) {
1678 if (++cnt10 > 100)
1679 break;
1680 } else {
1681 cnt10 = 0;
1682 cnt100 = 0;
1683 }
1684 DELAY(1000);
1685 }
1686 sc->tulip_media = cnt100 > 100 ? TULIP_MEDIA_100BASETX : TULIP_MEDIA_10BASET;
1687 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1688 TULIP_GP_ZX34X_INIT,
1689 TULIP_CMD_TXTHRSHLDCTL);
1690 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1691 TULIP_GP_ZX34X_INIT,
1692 TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1693 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1694 TULIP_GP_ZX34X_INIT,
1695 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1696 |TULIP_CMD_SCRAMBLER);
1697 tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1698 TULIP_GP_ZX34X_INIT,
1699 TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1700 |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1701 }
1702
1703 static const tulip_boardsw_t tulip_21140_znyx_zx34x_boardsw = {
1704 TULIP_21140_ZNYX_ZX34X,
1705 tulip_21140_znyx_zx34x_media_probe,
1706 tulip_media_select,
1707 tulip_null_media_poll,
1708 tulip_2114x_media_preset,
1709 };
1710
1711 void
tulip_2114x_media_probe(tulip_softc_t * const sc)1712 tulip_2114x_media_probe(tulip_softc_t * const sc)
1713 {
1714 sc->tulip_cmdmode |= TULIP_CMD_MUSTBEONE
1715 |TULIP_CMD_BACKOFFCTR|TULIP_CMD_THRSHLD72;
1716 }
1717
1718 static const tulip_boardsw_t tulip_2114x_isv_boardsw = {
1719 TULIP_21140_ISV,
1720 tulip_2114x_media_probe,
1721 tulip_media_select,
1722 tulip_media_poll,
1723 tulip_2114x_media_preset,
1724 };
1725
1726 /*
1727 * ******** END of chip-specific handlers. ***********
1728 */
1729
1730 /*
1731 * Code the read the SROM and MII bit streams (I2C)
1732 */
1733 void
tulip_delay_300ns(tulip_softc_t * const sc)1734 tulip_delay_300ns(tulip_softc_t * const sc)
1735 {
1736 int idx;
1737 for (idx = (300 / 33) + 1; idx > 0; idx--)
1738 (void) TULIP_CSR_READ(sc, csr_busmode);
1739 }
1740
1741 void
tulip_srom_idle(tulip_softc_t * const sc)1742 tulip_srom_idle(tulip_softc_t * const sc)
1743 {
1744 unsigned bit, csr;
1745
1746 csr = SROMSEL ; EMIT;
1747 csr = SROMSEL | SROMRD; EMIT;
1748 csr ^= SROMCS; EMIT;
1749 csr ^= SROMCLKON; EMIT;
1750
1751 /*
1752 * Write 25 cycles of 0 which will force the SROM to be idle.
1753 */
1754 for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
1755 csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
1756 csr ^= SROMCLKON; EMIT; /* clock high; data valid */
1757 }
1758 csr ^= SROMCLKOFF; EMIT;
1759 csr ^= SROMCS; EMIT;
1760 csr = 0; EMIT;
1761 }
1762
1763 void
tulip_srom_read(tulip_softc_t * const sc)1764 tulip_srom_read(tulip_softc_t * const sc)
1765 {
1766 unsigned idx;
1767 const unsigned bitwidth = SROM_BITWIDTH;
1768 const unsigned cmdmask = (SROMCMD_RD << bitwidth);
1769 const unsigned msb = 1 << (bitwidth + 3 - 1);
1770 unsigned lastidx = (1 << bitwidth) - 1;
1771
1772 tulip_srom_idle(sc);
1773
1774 for (idx = 0; idx <= lastidx; idx++) {
1775 unsigned lastbit, data, bits, bit, csr;
1776 csr = SROMSEL ; EMIT;
1777 csr = SROMSEL | SROMRD; EMIT;
1778 csr ^= SROMCSON; EMIT;
1779 csr ^= SROMCLKON; EMIT;
1780
1781 lastbit = 0;
1782 for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1) {
1783 const unsigned thisbit = bits & msb;
1784 csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
1785 if (thisbit != lastbit) {
1786 csr ^= SROMDOUT; EMIT; /* clock low; invert data */
1787 } else {
1788 EMIT;
1789 }
1790 csr ^= SROMCLKON; EMIT; /* clock high; data valid */
1791 lastbit = thisbit;
1792 }
1793 csr ^= SROMCLKOFF; EMIT;
1794
1795 for (data = 0, bits = 0; bits < 16; bits++) {
1796 data <<= 1;
1797 csr ^= SROMCLKON; EMIT; /* clock high; data valid */
1798 data |= TULIP_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0;
1799 csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
1800 }
1801 sc->tulip_rombuf[idx*2] = data & 0xFF;
1802 sc->tulip_rombuf[idx*2+1] = data >> 8;
1803 csr = SROMSEL | SROMRD; EMIT;
1804 csr = 0; EMIT;
1805 }
1806 tulip_srom_idle(sc);
1807 }
1808
1809 void
tulip_mii_writebits(tulip_softc_t * const sc,unsigned data,unsigned bits)1810 tulip_mii_writebits(tulip_softc_t * const sc, unsigned data, unsigned bits)
1811 {
1812 unsigned msb = 1 << (bits - 1);
1813 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1814 unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
1815
1816 csr |= MII_WR; MII_EMIT; /* clock low; assert write */
1817
1818 for (; bits > 0; bits--, data <<= 1) {
1819 const unsigned thisbit = data & msb;
1820 if (thisbit != lastbit)
1821 csr ^= MII_DOUT; MII_EMIT; /* clock low; invert data */
1822 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
1823 lastbit = thisbit;
1824 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
1825 }
1826 }
1827
1828 void
tulip_mii_turnaround(tulip_softc_t * const sc,unsigned cmd)1829 tulip_mii_turnaround(tulip_softc_t * const sc, unsigned cmd)
1830 {
1831 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1832
1833 if (cmd == MII_WRCMD) {
1834 csr |= MII_DOUT; MII_EMIT; /* clock low; change data */
1835 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
1836 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
1837 csr ^= MII_DOUT; MII_EMIT; /* clock low; change data */
1838 } else
1839 csr |= MII_RD; MII_EMIT; /* clock low; switch to read */
1840 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
1841 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
1842 }
1843
1844 unsigned
tulip_mii_readbits(tulip_softc_t * const sc)1845 tulip_mii_readbits(tulip_softc_t * const sc)
1846 {
1847 unsigned data;
1848 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1849 int idx;
1850
1851 for (idx = 0, data = 0; idx < 16; idx++) {
1852 data <<= 1; /* this is NOOP on the first pass through */
1853 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
1854 if (TULIP_CSR_READ(sc, csr_srom_mii) & MII_DIN)
1855 data |= 1;
1856 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
1857 }
1858 csr ^= MII_RD; MII_EMIT; /* clock low; turn off read */
1859
1860 return (data);
1861 }
1862
1863 unsigned
tulip_mii_readreg(tulip_softc_t * const sc,unsigned devaddr,unsigned regno)1864 tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno)
1865 {
1866 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1867 unsigned data;
1868
1869 csr &= ~(MII_RD|MII_CLK); MII_EMIT;
1870 tulip_mii_writebits(sc, MII_PREAMBLE, 32);
1871 tulip_mii_writebits(sc, MII_RDCMD, 8);
1872 tulip_mii_writebits(sc, devaddr, 5);
1873 tulip_mii_writebits(sc, regno, 5);
1874 tulip_mii_turnaround(sc, MII_RDCMD);
1875
1876 data = tulip_mii_readbits(sc);
1877 #if defined(TULIP_DEBUG)
1878 sc->tulip_dbg.dbg_phyregs[regno][0] = data;
1879 sc->tulip_dbg.dbg_phyregs[regno][1]++;
1880 #endif
1881 return (data);
1882 }
1883
1884 void
tulip_mii_writereg(tulip_softc_t * const sc,unsigned devaddr,unsigned regno,unsigned data)1885 tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr,
1886 unsigned regno, unsigned data)
1887 {
1888 unsigned csr;
1889
1890 csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1891 csr &= ~(MII_RD|MII_CLK); MII_EMIT;
1892 tulip_mii_writebits(sc, MII_PREAMBLE, 32);
1893 tulip_mii_writebits(sc, MII_WRCMD, 8);
1894 tulip_mii_writebits(sc, devaddr, 5);
1895 tulip_mii_writebits(sc, regno, 5);
1896 tulip_mii_turnaround(sc, MII_WRCMD);
1897 tulip_mii_writebits(sc, data, 16);
1898 #if defined(TULIP_DEBUG)
1899 sc->tulip_dbg.dbg_phyregs[regno][2] = data;
1900 sc->tulip_dbg.dbg_phyregs[regno][3]++;
1901 #endif
1902 }
1903
1904 void
tulip_identify_dec_nic(tulip_softc_t * const sc)1905 tulip_identify_dec_nic(tulip_softc_t * const sc)
1906 {
1907 strlcpy(sc->tulip_boardid, "DEC ", sizeof(sc->tulip_boardid));
1908 #define D0 4
1909 if (sc->tulip_chipid <= TULIP_DE425)
1910 return;
1911 if (bcmp(sc->tulip_rombuf + 29, "DE500", 5) == 0
1912 || bcmp(sc->tulip_rombuf + 29, "DE450", 5) == 0) {
1913 bcopy(sc->tulip_rombuf + 29, &sc->tulip_boardid[D0], 8);
1914 sc->tulip_boardid[D0+8] = ' ';
1915 }
1916 #undef D0
1917 }
1918
1919 void
tulip_identify_znyx_nic(tulip_softc_t * const sc)1920 tulip_identify_znyx_nic(tulip_softc_t * const sc)
1921 {
1922 unsigned id = 0;
1923 strlcpy(sc->tulip_boardid, "ZNYX ZX3XX ", sizeof(sc->tulip_boardid));
1924 if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
1925 unsigned znyx_ptr;
1926 sc->tulip_boardid[8] = '4';
1927 znyx_ptr = sc->tulip_rombuf[124] + 256 * sc->tulip_rombuf[125];
1928 if (znyx_ptr < 26 || znyx_ptr > 116) {
1929 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
1930 return;
1931 }
1932 /* ZX344 = 0010 .. 0013FF
1933 */
1934 if (sc->tulip_rombuf[znyx_ptr] == 0x4A
1935 && sc->tulip_rombuf[znyx_ptr + 1] == 0x52
1936 && sc->tulip_rombuf[znyx_ptr + 2] == 0x01) {
1937 id = sc->tulip_rombuf[znyx_ptr + 5] + 256 * sc->tulip_rombuf[znyx_ptr + 4];
1938 if ((id >> 8) == (TULIP_ZNYX_ID_ZX342 >> 8)) {
1939 sc->tulip_boardid[9] = '2';
1940 if (id == TULIP_ZNYX_ID_ZX342B) {
1941 sc->tulip_boardid[10] = 'B';
1942 sc->tulip_boardid[11] = ' ';
1943 }
1944 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
1945 } else if (id == TULIP_ZNYX_ID_ZX344) {
1946 sc->tulip_boardid[10] = '4';
1947 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
1948 } else if (id == TULIP_ZNYX_ID_ZX345) {
1949 sc->tulip_boardid[9] = (sc->tulip_rombuf[19] > 1) ? '8' : '5';
1950 } else if (id == TULIP_ZNYX_ID_ZX346) {
1951 sc->tulip_boardid[9] = '6';
1952 } else if (id == TULIP_ZNYX_ID_ZX351) {
1953 sc->tulip_boardid[8] = '5';
1954 sc->tulip_boardid[9] = '1';
1955 }
1956 }
1957 if (id == 0) {
1958 /*
1959 * Assume it's a ZX342...
1960 */
1961 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
1962 }
1963 return;
1964 }
1965 sc->tulip_boardid[8] = '1';
1966 if (sc->tulip_chipid == TULIP_21041) {
1967 sc->tulip_boardid[10] = '1';
1968 return;
1969 }
1970 if (sc->tulip_rombuf[32] == 0x4A && sc->tulip_rombuf[33] == 0x52) {
1971 id = sc->tulip_rombuf[37] + 256 * sc->tulip_rombuf[36];
1972 if (id == TULIP_ZNYX_ID_ZX312T) {
1973 sc->tulip_boardid[9] = '2';
1974 sc->tulip_boardid[10] = 'T';
1975 sc->tulip_boardid[11] = ' ';
1976 sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
1977 } else if (id == TULIP_ZNYX_ID_ZX314_INTA) {
1978 sc->tulip_boardid[9] = '4';
1979 sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
1980 sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
1981 } else if (id == TULIP_ZNYX_ID_ZX314) {
1982 sc->tulip_boardid[9] = '4';
1983 sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
1984 sc->tulip_features |= TULIP_HAVE_BASEROM;
1985 } else if (id == TULIP_ZNYX_ID_ZX315_INTA) {
1986 sc->tulip_boardid[9] = '5';
1987 sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
1988 } else if (id == TULIP_ZNYX_ID_ZX315) {
1989 sc->tulip_boardid[9] = '5';
1990 sc->tulip_features |= TULIP_HAVE_BASEROM;
1991 } else
1992 id = 0;
1993 }
1994 if (id == 0) {
1995 if ((sc->tulip_enaddr[3] & ~3) == 0xF0 && (sc->tulip_enaddr[5] & 3) == 0) {
1996 sc->tulip_boardid[9] = '4';
1997 sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
1998 sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
1999 } else if ((sc->tulip_enaddr[3] & ~3) == 0xF4 && (sc->tulip_enaddr[5] & 1) == 0) {
2000 sc->tulip_boardid[9] = '5';
2001 sc->tulip_boardsw = &tulip_21040_boardsw;
2002 sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
2003 } else if ((sc->tulip_enaddr[3] & ~3) == 0xEC) {
2004 sc->tulip_boardid[9] = '2';
2005 sc->tulip_boardsw = &tulip_21040_boardsw;
2006 }
2007 }
2008 }
2009
2010 void
tulip_identify_smc_nic(tulip_softc_t * const sc)2011 tulip_identify_smc_nic(tulip_softc_t * const sc)
2012 {
2013 u_int32_t id1, id2, ei;
2014 int auibnc = 0, utp = 0;
2015 char *cp;
2016
2017 strlcpy(sc->tulip_boardid, "SMC ", sizeof(sc->tulip_boardid));
2018 if (sc->tulip_chipid == TULIP_21041)
2019 return;
2020 if (sc->tulip_chipid != TULIP_21040) {
2021 if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
2022 strlcat(sc->tulip_boardid, "9332DST ", sizeof(sc->tulip_boardid));
2023 sc->tulip_boardsw = &tulip_21140_smc9332_boardsw;
2024 } else if (sc->tulip_features & (TULIP_HAVE_BASEROM|TULIP_HAVE_SLAVEDROM))
2025 strlcat(sc->tulip_boardid, "9334BDT ", sizeof(sc->tulip_boardid));
2026 else
2027 strlcat(sc->tulip_boardid, "9332BDT ", sizeof(sc->tulip_boardid));
2028 return;
2029 }
2030 id1 = sc->tulip_rombuf[0x60] | (sc->tulip_rombuf[0x61] << 8);
2031 id2 = sc->tulip_rombuf[0x62] | (sc->tulip_rombuf[0x63] << 8);
2032 ei = sc->tulip_rombuf[0x66] | (sc->tulip_rombuf[0x67] << 8);
2033
2034 strlcat(sc->tulip_boardid, "8432", sizeof(sc->tulip_boardid));
2035 cp = &sc->tulip_boardid[8];
2036 if ((id1 & 1) == 0)
2037 *cp++ = 'B', auibnc = 1;
2038 if ((id1 & 0xFF) > 0x32)
2039 *cp++ = 'T', utp = 1;
2040 if ((id1 & 0x4000) == 0)
2041 *cp++ = 'A', auibnc = 1;
2042 if (id2 == 0x15) {
2043 sc->tulip_boardid[7] = '4';
2044 *cp++ = '-';
2045 *cp++ = 'C';
2046 *cp++ = 'H';
2047 *cp++ = (ei ? '2' : '1');
2048 }
2049 *cp++ = ' ';
2050 *cp = '\0';
2051 if (utp && !auibnc)
2052 sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
2053 else if (!utp && auibnc)
2054 sc->tulip_boardsw = &tulip_21040_auibnc_only_boardsw;
2055 }
2056
2057 void
tulip_identify_cogent_nic(tulip_softc_t * const sc)2058 tulip_identify_cogent_nic(tulip_softc_t * const sc)
2059 {
2060 strlcpy(sc->tulip_boardid, "Cogent ", sizeof(sc->tulip_boardid));
2061 if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
2062 if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100TX_ID) {
2063 strlcat(sc->tulip_boardid, "EM100TX ", sizeof(sc->tulip_boardid));
2064 sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
2065 #if defined(TULIP_COGENT_EM110TX_ID)
2066 } else if (sc->tulip_rombuf[32] == TULIP_COGENT_EM110TX_ID) {
2067 strlcat(sc->tulip_boardid, "EM110TX ", sizeof(sc->tulip_boardid));
2068 sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
2069 #endif
2070 } else if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100FX_ID) {
2071 strlcat(sc->tulip_boardid, "EM100FX ", sizeof(sc->tulip_boardid));
2072 sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
2073 }
2074 /*
2075 * Magic number (0x24001109U) is the SubVendor (0x2400) and
2076 * SubDevId (0x1109) for the ANA6944TX (EM440TX).
2077 */
2078 if (*(u_int32_t *) sc->tulip_rombuf == 0x24001109U
2079 && (sc->tulip_features & TULIP_HAVE_BASEROM)) {
2080 /*
2081 * Cogent (Adaptec) is still mapping all INTs to INTA of
2082 * first 21140. Dumb! Dumb!
2083 */
2084 strlcat(sc->tulip_boardid, "EM440TX ", sizeof(sc->tulip_boardid));
2085 sc->tulip_features |= TULIP_HAVE_SHAREDINTR;
2086 }
2087 } else if (sc->tulip_chipid == TULIP_21040)
2088 sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
2089 }
2090
2091 void
tulip_identify_accton_nic(tulip_softc_t * const sc)2092 tulip_identify_accton_nic(tulip_softc_t * const sc)
2093 {
2094 strlcpy(sc->tulip_boardid, "ACCTON ", sizeof(sc->tulip_boardid));
2095 switch (sc->tulip_chipid) {
2096 case TULIP_21140A:
2097 strlcat(sc->tulip_boardid, "EN1207 ", sizeof(sc->tulip_boardid));
2098 if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw)
2099 sc->tulip_boardsw = &tulip_21140_accton_boardsw;
2100 break;
2101 case TULIP_21140:
2102 strlcat(sc->tulip_boardid, "EN1207TX ", sizeof(sc->tulip_boardid));
2103 if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw)
2104 sc->tulip_boardsw = &tulip_21140_eb_boardsw;
2105 break;
2106 case TULIP_21040:
2107 strlcat(sc->tulip_boardid, "EN1203 ", sizeof(sc->tulip_boardid));
2108 sc->tulip_boardsw = &tulip_21040_boardsw;
2109 break;
2110 case TULIP_21041:
2111 strlcat(sc->tulip_boardid, "EN1203 ", sizeof(sc->tulip_boardid));
2112 sc->tulip_boardsw = &tulip_21041_boardsw;
2113 break;
2114 default:
2115 sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2116 break;
2117 }
2118 }
2119
2120 void
tulip_identify_asante_nic(tulip_softc_t * const sc)2121 tulip_identify_asante_nic(tulip_softc_t * const sc)
2122 {
2123 strlcpy(sc->tulip_boardid, "Asante ", sizeof(sc->tulip_boardid));
2124 if ((sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A)
2125 && sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
2126 tulip_media_info_t *mi = sc->tulip_mediainfo;
2127 int idx;
2128 /*
2129 * The Asante Fast Ethernet doesn't always ship with a valid
2130 * new format SROM. So if isn't in the new format, we cheat
2131 * set it up as if we had.
2132 */
2133
2134 sc->tulip_gpinit = TULIP_GP_ASANTE_PINS;
2135 sc->tulip_gpdata = 0;
2136
2137 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ASANTE_PINS|TULIP_GP_PINSET);
2138 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ASANTE_PHYRESET);
2139 DELAY(100);
2140 TULIP_CSR_WRITE(sc, csr_gp, 0);
2141
2142 mi->mi_type = TULIP_MEDIAINFO_MII;
2143 mi->mi_gpr_length = 0;
2144 mi->mi_gpr_offset = 0;
2145 mi->mi_reset_length = 0;
2146 mi->mi_reset_offset = 0;
2147
2148 mi->mi_phyaddr = TULIP_MII_NOPHY;
2149 for (idx = 20; idx > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx--) {
2150 DELAY(10000);
2151 mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, 0);
2152 }
2153 if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
2154 #ifdef TULIP_DEBUG
2155 printf(TULIP_PRINTF_FMT ": can't find phy 0\n", TULIP_PRINTF_ARGS);
2156 #endif
2157 return;
2158 }
2159
2160 sc->tulip_features |= TULIP_HAVE_MII;
2161 mi->mi_capabilities = PHYSTS_10BASET|PHYSTS_10BASET_FD|PHYSTS_100BASETX|PHYSTS_100BASETX_FD;
2162 mi->mi_advertisement = PHYSTS_10BASET|PHYSTS_10BASET_FD|PHYSTS_100BASETX|PHYSTS_100BASETX_FD;
2163 mi->mi_full_duplex = PHYSTS_10BASET_FD|PHYSTS_100BASETX_FD;
2164 mi->mi_tx_threshold = PHYSTS_10BASET|PHYSTS_10BASET_FD;
2165 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
2166 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
2167 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
2168 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
2169 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
2170 mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
2171 tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
2172
2173 sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2174 }
2175 }
2176
2177 void
tulip_identify_compex_nic(tulip_softc_t * const sc)2178 tulip_identify_compex_nic(tulip_softc_t * const sc)
2179 {
2180 strlcpy(sc->tulip_boardid, "COMPEX ", sizeof(sc->tulip_boardid));
2181 if (sc->tulip_chipid == TULIP_21140A) {
2182 int root_unit;
2183 tulip_softc_t *root_sc = NULL;
2184
2185 strlcat(sc->tulip_boardid, "400TX/PCI ", sizeof(sc->tulip_boardid));
2186 /*
2187 * All 4 chips on these boards share an interrupt. This code
2188 * copied from tulip_read_macaddr.
2189 */
2190 sc->tulip_features |= TULIP_HAVE_SHAREDINTR;
2191 for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) {
2192 root_sc = TULIP_UNIT_TO_SOFTC(root_unit);
2193 if (root_sc == NULL
2194 || !(root_sc->tulip_features & TULIP_HAVE_SLAVEDINTR))
2195 break;
2196 root_sc = NULL;
2197 }
2198 if (root_sc != NULL
2199 && root_sc->tulip_chipid == sc->tulip_chipid
2200 && root_sc->tulip_pci_busno == sc->tulip_pci_busno) {
2201 sc->tulip_features |= TULIP_HAVE_SLAVEDINTR;
2202 sc->tulip_slaves = root_sc->tulip_slaves;
2203 root_sc->tulip_slaves = sc;
2204 } else if(sc->tulip_features & TULIP_HAVE_SLAVEDINTR)
2205 printf("\nCannot find master device for de%d interrupts", sc->tulip_unit);
2206 } else
2207 strlcat(sc->tulip_boardid, "unknown ", sizeof(sc->tulip_boardid));
2208
2209 /* sc->tulip_boardsw = &tulip_21140_eb_boardsw; */
2210 }
2211
2212 int
tulip_srom_decode(tulip_softc_t * const sc)2213 tulip_srom_decode(tulip_softc_t * const sc)
2214 {
2215 unsigned idx1, idx2, idx3;
2216
2217 const tulip_srom_header_t *shp = (tulip_srom_header_t *) &sc->tulip_rombuf[0];
2218 const tulip_srom_adapter_info_t *saip = (tulip_srom_adapter_info_t *) (shp + 1);
2219 tulip_srom_media_t srom_media;
2220 tulip_media_info_t *mi = sc->tulip_mediainfo;
2221 const u_int8_t *dp;
2222 u_int32_t leaf_offset, blocks, data;
2223
2224 for (idx1 = 0; idx1 < shp->sh_adapter_count; idx1++, saip++) {
2225 if (shp->sh_adapter_count == 1)
2226 break;
2227 if (saip->sai_device == sc->tulip_pci_devno)
2228 break;
2229 }
2230 /*
2231 * Didn't find the right media block for this card.
2232 */
2233 if (idx1 == shp->sh_adapter_count)
2234 return (0);
2235
2236 /*
2237 * Save the hardware address.
2238 */
2239 bcopy((caddr_t) shp->sh_ieee802_address, (caddr_t) sc->tulip_enaddr,
2240 ETHER_ADDR_LEN);
2241 /*
2242 * If this is a multiple port card, add the adapter index to the last
2243 * byte of the hardware address. (if it isn't multiport, adding 0
2244 * won't hurt.
2245 */
2246 sc->tulip_enaddr[5] += idx1;
2247
2248 leaf_offset = saip->sai_leaf_offset_lowbyte
2249 + saip->sai_leaf_offset_highbyte * 256;
2250 dp = sc->tulip_rombuf + leaf_offset;
2251
2252 sc->tulip_conntype = (tulip_srom_connection_t) (dp[0] + dp[1] * 256); dp += 2;
2253
2254 for (idx2 = 0;; idx2++) {
2255 if (tulip_srom_conninfo[idx2].sc_type == sc->tulip_conntype
2256 || tulip_srom_conninfo[idx2].sc_type == TULIP_SROM_CONNTYPE_NOT_USED)
2257 break;
2258 }
2259 sc->tulip_connidx = idx2;
2260
2261 if (sc->tulip_chipid == TULIP_21041) {
2262 blocks = *dp++;
2263 for (idx2 = 0; idx2 < blocks; idx2++) {
2264 tulip_media_t media;
2265 data = *dp++;
2266 srom_media = (tulip_srom_media_t) (data & 0x3F);
2267 for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2268 if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2269 break;
2270 }
2271 media = tulip_srom_mediums[idx3].sm_type;
2272 if (media != TULIP_MEDIA_UNKNOWN) {
2273 if (data & TULIP_SROM_21041_EXTENDED) {
2274 mi->mi_type = TULIP_MEDIAINFO_SIA;
2275 sc->tulip_mediums[media] = mi;
2276 mi->mi_sia_connectivity = dp[0] + dp[1] * 256;
2277 mi->mi_sia_tx_rx = dp[2] + dp[3] * 256;
2278 mi->mi_sia_general = dp[4] + dp[5] * 256;
2279 mi++;
2280 } else {
2281 switch (media) {
2282 case TULIP_MEDIA_BNC: {
2283 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, BNC);
2284 mi++;
2285 break;
2286 }
2287 case TULIP_MEDIA_AUI: {
2288 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, AUI);
2289 mi++;
2290 break;
2291 }
2292 case TULIP_MEDIA_10BASET: {
2293 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET);
2294 mi++;
2295 break;
2296 }
2297 case TULIP_MEDIA_10BASET_FD: {
2298 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET_FD);
2299 mi++;
2300 break;
2301 }
2302 default: {
2303 break;
2304 }
2305 }
2306 }
2307 }
2308 if (data & TULIP_SROM_21041_EXTENDED)
2309 dp += 6;
2310 }
2311 } else {
2312 unsigned length, type;
2313 tulip_media_t gp_media = TULIP_MEDIA_UNKNOWN;
2314 if (sc->tulip_features & TULIP_HAVE_GPR)
2315 sc->tulip_gpinit = *dp++;
2316 blocks = *dp++;
2317 for (idx2 = 0; idx2 < blocks; idx2++) {
2318 const u_int8_t *ep;
2319 if ((*dp & 0x80) == 0) {
2320 length = 4;
2321 type = 0;
2322 } else {
2323 length = (*dp++ & 0x7f) - 1;
2324 type = *dp++ & 0x3f;
2325 }
2326 ep = dp + length;
2327 switch (type & 0x3f) {
2328 case 0: { /* 21140[A] GPR block */
2329 tulip_media_t media;
2330 srom_media = (tulip_srom_media_t)(dp[0] & 0x3f);
2331 for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2332 if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2333 break;
2334 }
2335 media = tulip_srom_mediums[idx3].sm_type;
2336 if (media == TULIP_MEDIA_UNKNOWN)
2337 break;
2338 mi->mi_type = TULIP_MEDIAINFO_GPR;
2339 sc->tulip_mediums[media] = mi;
2340 mi->mi_gpdata = dp[1];
2341 if (media > gp_media && !TULIP_IS_MEDIA_FD(media)) {
2342 sc->tulip_gpdata = mi->mi_gpdata;
2343 gp_media = media;
2344 }
2345 data = dp[2] + dp[3] * 256;
2346 mi->mi_cmdmode = TULIP_SROM_2114X_CMDBITS(data);
2347 if (data & TULIP_SROM_2114X_NOINDICATOR)
2348 mi->mi_actmask = 0;
2349 else {
2350 mi->mi_actmask = TULIP_SROM_2114X_BITPOS(data);
2351 mi->mi_actdata = (data & TULIP_SROM_2114X_POLARITY) ? 0 : mi->mi_actmask;
2352 }
2353 mi++;
2354 break;
2355 }
2356 case 1: { /* 21140[A] MII block */
2357 const unsigned phyno = *dp++;
2358 mi->mi_type = TULIP_MEDIAINFO_MII;
2359 mi->mi_gpr_length = *dp++;
2360 mi->mi_gpr_offset = dp - sc->tulip_rombuf;
2361 dp += mi->mi_gpr_length;
2362 mi->mi_reset_length = *dp++;
2363 mi->mi_reset_offset = dp - sc->tulip_rombuf;
2364 dp += mi->mi_reset_length;
2365
2366 /*
2367 * Before we probe for a PHY, use the GPR information
2368 * to select it. If we don't, it may be inaccessible.
2369 */
2370 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_gpinit|TULIP_GP_PINSET);
2371 for (idx3 = 0; idx3 < mi->mi_reset_length; idx3++) {
2372 DELAY(10);
2373 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx3]);
2374 }
2375 sc->tulip_phyaddr = mi->mi_phyaddr;
2376 for (idx3 = 0; idx3 < mi->mi_gpr_length; idx3++) {
2377 DELAY(10);
2378 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx3]);
2379 }
2380
2381 /*
2382 * At least write something!
2383 */
2384 if (mi->mi_reset_length == 0 && mi->mi_gpr_length == 0)
2385 TULIP_CSR_WRITE(sc, csr_gp, 0);
2386
2387 mi->mi_phyaddr = TULIP_MII_NOPHY;
2388 for (idx3 = 20; idx3 > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx3--) {
2389 DELAY(10000);
2390 mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno);
2391 }
2392 if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
2393 #if defined(TULIP_DEBUG)
2394 printf(TULIP_PRINTF_FMT ": can't find phy %d\n",
2395 TULIP_PRINTF_ARGS, phyno);
2396 #endif
2397 break;
2398 }
2399 sc->tulip_features |= TULIP_HAVE_MII;
2400 mi->mi_capabilities = dp[0] + dp[1] * 256; dp += 2;
2401 mi->mi_advertisement = dp[0] + dp[1] * 256; dp += 2;
2402 mi->mi_full_duplex = dp[0] + dp[1] * 256; dp += 2;
2403 mi->mi_tx_threshold = dp[0] + dp[1] * 256; dp += 2;
2404 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
2405 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
2406 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
2407 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
2408 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
2409 mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
2410 tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
2411 mi++;
2412 break;
2413 }
2414 case 2: { /* 2114[23] SIA block */
2415 tulip_media_t media;
2416 srom_media = (tulip_srom_media_t)(dp[0] & 0x3f);
2417 for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2418 if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2419 break;
2420 }
2421 media = tulip_srom_mediums[idx3].sm_type;
2422 if (media == TULIP_MEDIA_UNKNOWN)
2423 break;
2424 mi->mi_type = TULIP_MEDIAINFO_SIA;
2425 sc->tulip_mediums[media] = mi;
2426 if (dp[0] & 0x40) {
2427 mi->mi_sia_connectivity = dp[1] + dp[2] * 256;
2428 mi->mi_sia_tx_rx = dp[3] + dp[4] * 256;
2429 mi->mi_sia_general = dp[5] + dp[6] * 256;
2430 dp += 6;
2431 } else {
2432 switch (media) {
2433 case TULIP_MEDIA_BNC: {
2434 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, BNC);
2435 break;
2436 }
2437 case TULIP_MEDIA_AUI: {
2438 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, AUI);
2439 break;
2440 }
2441 case TULIP_MEDIA_10BASET: {
2442 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET);
2443 sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
2444 break;
2445 }
2446 case TULIP_MEDIA_10BASET_FD: {
2447 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET_FD);
2448 sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
2449 break;
2450 }
2451 default: {
2452 goto bad_media;
2453 }
2454 }
2455 }
2456 mi->mi_sia_gp_control = (dp[1] + dp[2] * 256) << 16;
2457 mi->mi_sia_gp_data = (dp[3] + dp[4] * 256) << 16;
2458 mi++;
2459 bad_media:
2460 break;
2461 }
2462 case 3: { /* 2114[23] MII PHY block */
2463 const unsigned phyno = *dp++;
2464 const u_int8_t *dp0;
2465 mi->mi_type = TULIP_MEDIAINFO_MII;
2466 mi->mi_gpr_length = *dp++;
2467 mi->mi_gpr_offset = dp - sc->tulip_rombuf;
2468 dp += 2 * mi->mi_gpr_length;
2469 mi->mi_reset_length = *dp++;
2470 mi->mi_reset_offset = dp - sc->tulip_rombuf;
2471 dp += 2 * mi->mi_reset_length;
2472
2473 dp0 = &sc->tulip_rombuf[mi->mi_reset_offset];
2474 for (idx3 = 0; idx3 < mi->mi_reset_length; idx3++, dp0 += 2) {
2475 DELAY(10);
2476 TULIP_CSR_WRITE(sc, csr_sia_general, (dp0[0] + 256 * dp0[1]) << 16);
2477 }
2478 sc->tulip_phyaddr = mi->mi_phyaddr;
2479 dp0 = &sc->tulip_rombuf[mi->mi_gpr_offset];
2480 for (idx3 = 0; idx3 < mi->mi_gpr_length; idx3++, dp0 += 2) {
2481 DELAY(10);
2482 TULIP_CSR_WRITE(sc, csr_sia_general, (dp0[0] + 256 * dp0[1]) << 16);
2483 }
2484
2485 if (mi->mi_reset_length == 0 && mi->mi_gpr_length == 0)
2486 TULIP_CSR_WRITE(sc, csr_sia_general, 0);
2487
2488 mi->mi_phyaddr = TULIP_MII_NOPHY;
2489 for (idx3 = 20; idx3 > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx3--) {
2490 DELAY(10000);
2491 mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno);
2492 }
2493 if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
2494 #if defined(TULIP_DEBUG)
2495 printf(TULIP_PRINTF_FMT ": can't find phy %d\n",
2496 TULIP_PRINTF_ARGS, phyno);
2497 #endif
2498 break;
2499 }
2500 sc->tulip_features |= TULIP_HAVE_MII;
2501 mi->mi_capabilities = dp[0] + dp[1] * 256; dp += 2;
2502 mi->mi_advertisement = dp[0] + dp[1] * 256; dp += 2;
2503 mi->mi_full_duplex = dp[0] + dp[1] * 256; dp += 2;
2504 mi->mi_tx_threshold = dp[0] + dp[1] * 256; dp += 2;
2505 mi->mi_mii_interrupt = dp[0] + dp[1] * 256; dp += 2;
2506 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
2507 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
2508 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
2509 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
2510 TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
2511 mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
2512 tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
2513 mi++;
2514 break;
2515 }
2516 case 4: { /* 21143 SYM block */
2517 tulip_media_t media;
2518 srom_media = (tulip_srom_media_t) dp[0];
2519 for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2520 if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2521 break;
2522 }
2523 media = tulip_srom_mediums[idx3].sm_type;
2524 if (media == TULIP_MEDIA_UNKNOWN)
2525 break;
2526 mi->mi_type = TULIP_MEDIAINFO_SYM;
2527 sc->tulip_mediums[media] = mi;
2528 mi->mi_gpcontrol = (dp[1] + dp[2] * 256) << 16;
2529 mi->mi_gpdata = (dp[3] + dp[4] * 256) << 16;
2530 data = dp[5] + dp[6] * 256;
2531 mi->mi_cmdmode = TULIP_SROM_2114X_CMDBITS(data);
2532 if (data & TULIP_SROM_2114X_NOINDICATOR)
2533 mi->mi_actmask = 0;
2534 else {
2535 mi->mi_default = (data & TULIP_SROM_2114X_DEFAULT) != 0;
2536 mi->mi_actmask = TULIP_SROM_2114X_BITPOS(data);
2537 mi->mi_actdata = (data & TULIP_SROM_2114X_POLARITY) ? 0 : mi->mi_actmask;
2538 }
2539 if (TULIP_IS_MEDIA_TP(media))
2540 sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
2541 mi++;
2542 break;
2543 }
2544 default: {
2545 }
2546 }
2547 dp = ep;
2548 }
2549 }
2550 return (mi - sc->tulip_mediainfo);
2551 }
2552
2553 static const struct {
2554 void (*vendor_identify_nic)(tulip_softc_t * const sc);
2555 unsigned char vendor_oui[3];
2556 } tulip_vendors[] = {
2557 { tulip_identify_dec_nic, { 0x08, 0x00, 0x2B } },
2558 { tulip_identify_dec_nic, { 0x00, 0x00, 0xF8 } },
2559 { tulip_identify_smc_nic, { 0x00, 0x00, 0xC0 } },
2560 { tulip_identify_smc_nic, { 0x00, 0xE0, 0x29 } },
2561 { tulip_identify_znyx_nic, { 0x00, 0xC0, 0x95 } },
2562 { tulip_identify_cogent_nic, { 0x00, 0x00, 0x92 } },
2563 { tulip_identify_cogent_nic, { 0x00, 0x00, 0xD1 } },
2564 { tulip_identify_asante_nic, { 0x00, 0x00, 0x94 } },
2565 { tulip_identify_accton_nic, { 0x00, 0x00, 0xE8 } },
2566 { tulip_identify_compex_nic, { 0x00, 0x80, 0x48 } },
2567 { NULL }
2568 };
2569
2570 /*
2571 * This deals with the vagaries of the address roms and the
2572 * brain-deadness that various vendors commit in using them.
2573 */
2574 int
tulip_read_macaddr(tulip_softc_t * const sc)2575 tulip_read_macaddr(tulip_softc_t * const sc)
2576 {
2577 unsigned cksum, rom_cksum, idx;
2578 u_int32_t csr;
2579 unsigned char tmpbuf[8];
2580 static const u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
2581
2582 sc->tulip_connidx = TULIP_SROM_LASTCONNIDX;
2583
2584 if (sc->tulip_chipid == TULIP_21040) {
2585 TULIP_CSR_WRITE(sc, csr_enetrom, 1);
2586 for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) {
2587 int cnt = 0;
2588 while (((csr = TULIP_CSR_READ(sc, csr_enetrom)) & 0x80000000L) && cnt < 10000)
2589 cnt++;
2590 sc->tulip_rombuf[idx] = csr & 0xFF;
2591 }
2592 sc->tulip_boardsw = &tulip_21040_boardsw;
2593 } else {
2594 if (sc->tulip_chipid == TULIP_21041) {
2595 /*
2596 * Thankfully all 21041's act the same.
2597 */
2598 sc->tulip_boardsw = &tulip_21041_boardsw;
2599 } else {
2600 /*
2601 * Assume all 21140 board are compatible with the
2602 * DEC 10/100 evaluation board. Not really valid but
2603 * it's the best we can do until every one switches to
2604 * the new SROM format.
2605 */
2606
2607 sc->tulip_boardsw = &tulip_21140_eb_boardsw;
2608 }
2609 tulip_srom_read(sc);
2610 if (tulip_srom_crcok(sc->tulip_rombuf)) {
2611 /*
2612 * SROM CRC is valid therefore it must be in the
2613 * new format.
2614 */
2615 sc->tulip_features |= TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM;
2616 } else if (sc->tulip_rombuf[126] == 0xff && sc->tulip_rombuf[127] == 0xFF) {
2617 /*
2618 * No checksum is present. See if the SROM id checks out;
2619 * the first 18 bytes should be 0 followed by a 1 followed
2620 * by the number of adapters (which we don't deal with yet).
2621 */
2622 for (idx = 0; idx < 18; idx++) {
2623 if (sc->tulip_rombuf[idx] != 0)
2624 break;
2625 }
2626 if (idx == 18 && sc->tulip_rombuf[18] == 1 && sc->tulip_rombuf[19] != 0)
2627 sc->tulip_features |= TULIP_HAVE_ISVSROM;
2628 } else if (sc->tulip_chipid >= TULIP_21142) {
2629 sc->tulip_features |= TULIP_HAVE_ISVSROM;
2630 sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2631 }
2632 if ((sc->tulip_features & TULIP_HAVE_ISVSROM) && tulip_srom_decode(sc)) {
2633 if (sc->tulip_chipid != TULIP_21041)
2634 sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2635
2636 /*
2637 * If the SROM specifies more than one adapter, tag this as a
2638 * BASE rom.
2639 */
2640 if (sc->tulip_rombuf[19] > 1)
2641 sc->tulip_features |= TULIP_HAVE_BASEROM;
2642 if (sc->tulip_boardsw == NULL)
2643 return (-6);
2644 goto check_oui;
2645 }
2646 }
2647
2648 if (bcmp(&sc->tulip_rombuf[0], &sc->tulip_rombuf[16], 8) != 0) {
2649 /*
2650 * Some folks don't use the standard ethernet rom format
2651 * but instead just put the address in the first 6 bytes
2652 * of the rom and let the rest be all 0xffs. (Can we say
2653 * ZNYX???) (well sometimes they put in a checksum so we'll
2654 * start at 8).
2655 */
2656 for (idx = 8; idx < 32; idx++) {
2657 if (sc->tulip_rombuf[idx] != 0xFF)
2658 return (-4);
2659 }
2660 /*
2661 * Make sure the address is not multicast or locally assigned
2662 * that the OUI is not 00-00-00.
2663 */
2664 if ((sc->tulip_rombuf[0] & 3) != 0)
2665 return (-4);
2666 if (sc->tulip_rombuf[0] == 0 && sc->tulip_rombuf[1] == 0
2667 && sc->tulip_rombuf[2] == 0)
2668 return (-4);
2669 bcopy(sc->tulip_rombuf, sc->tulip_enaddr, ETHER_ADDR_LEN);
2670 sc->tulip_features |= TULIP_HAVE_OKROM;
2671 goto check_oui;
2672 } else {
2673 /*
2674 * A number of makers of multiport boards (ZNYX and Cogent)
2675 * only put on one address ROM on their 21040 boards. So
2676 * if the ROM is all zeros (or all 0xFFs), look at the
2677 * previous configured boards (as long as they are on the same
2678 * PCI bus and the bus number is non-zero) until we find the
2679 * master board with address ROM. We then use its address ROM
2680 * as the base for this board. (we add our relative board
2681 * to the last byte of its address).
2682 */
2683 for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) {
2684 if (sc->tulip_rombuf[idx] != 0 && sc->tulip_rombuf[idx] != 0xFF)
2685 break;
2686 }
2687 if (idx == sizeof(sc->tulip_rombuf)) {
2688 int root_unit;
2689 tulip_softc_t *root_sc = NULL;
2690 for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) {
2691 root_sc = TULIP_UNIT_TO_SOFTC(root_unit);
2692 if (root_sc == NULL || (root_sc->tulip_features & (TULIP_HAVE_OKROM|TULIP_HAVE_SLAVEDROM)) == TULIP_HAVE_OKROM)
2693 break;
2694 root_sc = NULL;
2695 }
2696 if (root_sc != NULL && (root_sc->tulip_features & TULIP_HAVE_BASEROM)
2697 && root_sc->tulip_chipid == sc->tulip_chipid
2698 && root_sc->tulip_pci_busno == sc->tulip_pci_busno) {
2699 sc->tulip_features |= TULIP_HAVE_SLAVEDROM;
2700 sc->tulip_boardsw = root_sc->tulip_boardsw;
2701 strlcpy(sc->tulip_boardid, root_sc->tulip_boardid,
2702 sizeof(sc->tulip_boardid));
2703 if (sc->tulip_boardsw->bd_type == TULIP_21140_ISV) {
2704 bcopy(root_sc->tulip_rombuf, sc->tulip_rombuf,
2705 sizeof(sc->tulip_rombuf));
2706 if (!tulip_srom_decode(sc))
2707 return (-5);
2708 } else {
2709 bcopy(root_sc->tulip_enaddr, sc->tulip_enaddr,
2710 ETHER_ADDR_LEN);
2711 sc->tulip_enaddr[5] += sc->tulip_unit - root_sc->tulip_unit;
2712 }
2713 /*
2714 * Now for a truly disgusting kludge: all 4 21040s on
2715 * the ZX314 share the same INTA line so the mapping
2716 * setup by the BIOS on the PCI bridge is worthless.
2717 * Rather than reprogramming the value in the config
2718 * register, we will handle this internally.
2719 */
2720 if (root_sc->tulip_features & TULIP_HAVE_SHAREDINTR) {
2721 sc->tulip_slaves = root_sc->tulip_slaves;
2722 root_sc->tulip_slaves = sc;
2723 sc->tulip_features |= TULIP_HAVE_SLAVEDINTR;
2724 }
2725 return (0);
2726 }
2727 }
2728 }
2729
2730 /*
2731 * This is the standard DEC address ROM test.
2732 */
2733
2734 if (bcmp(&sc->tulip_rombuf[24], testpat, 8) != 0)
2735 return (-3);
2736
2737 tmpbuf[0] = sc->tulip_rombuf[15]; tmpbuf[1] = sc->tulip_rombuf[14];
2738 tmpbuf[2] = sc->tulip_rombuf[13]; tmpbuf[3] = sc->tulip_rombuf[12];
2739 tmpbuf[4] = sc->tulip_rombuf[11]; tmpbuf[5] = sc->tulip_rombuf[10];
2740 tmpbuf[6] = sc->tulip_rombuf[9]; tmpbuf[7] = sc->tulip_rombuf[8];
2741 if (bcmp(&sc->tulip_rombuf[0], tmpbuf, 8) != 0)
2742 return (-2);
2743
2744 bcopy(sc->tulip_rombuf, sc->tulip_enaddr, ETHER_ADDR_LEN);
2745
2746 cksum = *(u_int16_t *) &sc->tulip_enaddr[0];
2747 cksum *= 2;
2748 if (cksum > 65535) cksum -= 65535;
2749 cksum += *(u_int16_t *) &sc->tulip_enaddr[2];
2750 if (cksum > 65535) cksum -= 65535;
2751 cksum *= 2;
2752 if (cksum > 65535) cksum -= 65535;
2753 cksum += *(u_int16_t *) &sc->tulip_enaddr[4];
2754 if (cksum >= 65535) cksum -= 65535;
2755
2756 rom_cksum = *(u_int16_t *) &sc->tulip_rombuf[6];
2757
2758 if (cksum != rom_cksum)
2759 return (-1);
2760
2761 check_oui:
2762 /*
2763 * Check for various boards based on OUI. Did I say braindead?
2764 */
2765 for (idx = 0; tulip_vendors[idx].vendor_identify_nic != NULL; idx++) {
2766 if (bcmp((caddr_t) sc->tulip_enaddr,
2767 (caddr_t) tulip_vendors[idx].vendor_oui, 3) == 0) {
2768 (*tulip_vendors[idx].vendor_identify_nic)(sc);
2769 break;
2770 }
2771 }
2772
2773 sc->tulip_features |= TULIP_HAVE_OKROM;
2774 return (0);
2775 }
2776
2777 void
tulip_ifmedia_add(tulip_softc_t * const sc)2778 tulip_ifmedia_add(tulip_softc_t * const sc)
2779 {
2780 tulip_media_t media;
2781 int medias = 0;
2782
2783 for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
2784 if (sc->tulip_mediums[media] != NULL) {
2785 ifmedia_add(&sc->tulip_ifmedia, tulip_media_to_ifmedia[media],
2786 0, 0);
2787 medias++;
2788 }
2789 }
2790 if (medias == 0) {
2791 sc->tulip_features |= TULIP_HAVE_NOMEDIA;
2792 ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE, 0, 0);
2793 ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE);
2794 } else if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
2795 ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO, 0, 0);
2796 ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO);
2797 } else {
2798 ifmedia_set(&sc->tulip_ifmedia, tulip_media_to_ifmedia[sc->tulip_media]);
2799 sc->tulip_flags |= TULIP_PRINTMEDIA;
2800 tulip_linkup(sc, sc->tulip_media);
2801 }
2802 }
2803
2804 int
tulip_ifmedia_change(struct ifnet * const ifp)2805 tulip_ifmedia_change(struct ifnet * const ifp)
2806 {
2807 tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
2808
2809 sc->tulip_flags |= TULIP_NEEDRESET;
2810 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
2811 sc->tulip_media = TULIP_MEDIA_UNKNOWN;
2812 if (IFM_SUBTYPE(sc->tulip_ifmedia.ifm_media) != IFM_AUTO) {
2813 tulip_media_t media;
2814 for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
2815 if (sc->tulip_mediums[media] != NULL
2816 && sc->tulip_ifmedia.ifm_media == tulip_media_to_ifmedia[media]) {
2817 sc->tulip_flags |= TULIP_PRINTMEDIA;
2818 sc->tulip_flags &= ~TULIP_DIDNWAY;
2819 tulip_linkup(sc, media);
2820 return (0);
2821 }
2822 }
2823 }
2824 sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_WANTRXACT);
2825 tulip_reset(sc);
2826 tulip_init(sc);
2827 return (0);
2828 }
2829
2830 /*
2831 * Media status callback
2832 */
2833 void
tulip_ifmedia_status(struct ifnet * const ifp,struct ifmediareq * req)2834 tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req)
2835 {
2836 tulip_softc_t *sc = TULIP_IFP_TO_SOFTC(ifp);
2837
2838 if (sc->tulip_media == TULIP_MEDIA_UNKNOWN)
2839 return;
2840
2841 req->ifm_status = IFM_AVALID;
2842 if (sc->tulip_flags & TULIP_LINKUP)
2843 req->ifm_status |= IFM_ACTIVE;
2844
2845 req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media];
2846 }
2847
2848 bus_dmamap_t
tulip_alloc_rxmap(tulip_softc_t * sc)2849 tulip_alloc_rxmap(tulip_softc_t *sc)
2850 {
2851 return (sc->tulip_free_rxmaps[--sc->tulip_num_free_rxmaps]);
2852 }
2853
2854 void
tulip_free_rxmap(tulip_softc_t * sc,bus_dmamap_t map)2855 tulip_free_rxmap(tulip_softc_t *sc, bus_dmamap_t map)
2856 {
2857 sc->tulip_free_rxmaps[sc->tulip_num_free_rxmaps++] = map;
2858 }
2859
2860 bus_dmamap_t
tulip_alloc_txmap(tulip_softc_t * sc)2861 tulip_alloc_txmap(tulip_softc_t *sc)
2862 {
2863 return (sc->tulip_free_txmaps[--sc->tulip_num_free_txmaps]);
2864 }
2865
2866 void
tulip_free_txmap(tulip_softc_t * sc,bus_dmamap_t map)2867 tulip_free_txmap(tulip_softc_t *sc, bus_dmamap_t map)
2868 {
2869 sc->tulip_free_txmaps[sc->tulip_num_free_txmaps++] = map;
2870 }
2871
2872 void
tulip_addr_filter(tulip_softc_t * const sc)2873 tulip_addr_filter(tulip_softc_t * const sc)
2874 {
2875 struct arpcom *ac = &sc->tulip_ac;
2876 struct ether_multistep step;
2877 struct ether_multi *enm;
2878
2879 sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI);
2880 sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART;
2881 sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
2882 sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
2883 sc->tulip_if.if_flags &= ~IFF_ALLMULTI;
2884 if (sc->tulip_multicnt > 14) {
2885 u_int32_t *sp = sc->tulip_setupdata;
2886 unsigned hash;
2887 /*
2888 * Some early passes of the 21140 have broken implementations of
2889 * hash-perfect mode. When we get too many multicasts for perfect
2890 * filtering with these chips, we need to switch into hash-only
2891 * mode (this is better than all-multicast on network with lots
2892 * of multicast traffic).
2893 */
2894 if (sc->tulip_features & TULIP_HAVE_BROKEN_HASH)
2895 sc->tulip_flags |= TULIP_WANTHASHONLY;
2896 else
2897 sc->tulip_flags |= TULIP_WANTHASHPERFECT;
2898 /*
2899 * If we have more than 14 multicasts, we have
2900 * go into hash perfect mode (512 bit multicast
2901 * hash and one perfect hardware).
2902 */
2903 bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
2904 if (ac->ac_multirangecnt > 0) {
2905 sc->tulip_flags |= TULIP_ALLMULTI;
2906 sc->tulip_flags &= ~(TULIP_WANTHASHONLY|TULIP_WANTHASHPERFECT);
2907 } else {
2908 ETHER_FIRST_MULTI(step, ac, enm);
2909 while (enm != NULL) {
2910 hash = tulip_mchash(enm->enm_addrlo);
2911 #if BYTE_ORDER == BIG_ENDIAN
2912 sp[hash >> 4] |= swap32(1 << (hash & 0xF));
2913 #else
2914 sp[hash >> 4] |= 1 << (hash & 0xF);
2915 #endif
2916 ETHER_NEXT_MULTI(step, enm);
2917 }
2918 }
2919 /*
2920 * No reason to use a hash if we are going to be
2921 * receiving every multicast.
2922 */
2923 if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
2924 hash = tulip_mchash(etherbroadcastaddr);
2925 #if BYTE_ORDER == BIG_ENDIAN
2926 sp[hash >> 4] |= swap32(1 << (hash & 0xF));
2927 #else
2928 sp[hash >> 4] |= 1 << (hash & 0xF);
2929 #endif
2930 if (sc->tulip_flags & TULIP_WANTHASHONLY) {
2931 hash = tulip_mchash(sc->tulip_enaddr);
2932 #if BYTE_ORDER == BIG_ENDIAN
2933 sp[hash >> 4] |= swap32(1 << (hash & 0xF));
2934 #else
2935 sp[hash >> 4] |= 1 << (hash & 0xF);
2936 #endif
2937 } else {
2938 #if BYTE_ORDER == BIG_ENDIAN
2939 sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0] << 16;
2940 sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1] << 16;
2941 sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2] << 16;
2942 #else
2943 sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0];
2944 sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1];
2945 sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2];
2946 #endif
2947 }
2948 }
2949 }
2950 if ((sc->tulip_flags & (TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY)) == 0) {
2951 u_int32_t *sp = sc->tulip_setupdata;
2952 int idx = 0;
2953 if (ac->ac_multirangecnt > 0)
2954 sc->tulip_flags |= TULIP_ALLMULTI;
2955
2956 if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
2957 /*
2958 * Else can get perfect filtering for 16 addresses.
2959 */
2960 ETHER_FIRST_MULTI(step, ac, enm);
2961 for (; enm != NULL; idx++) {
2962 #if BYTE_ORDER == BIG_ENDIAN
2963 *sp++ = ((u_int16_t *) enm->enm_addrlo)[0] << 16;
2964 *sp++ = ((u_int16_t *) enm->enm_addrlo)[1] << 16;
2965 *sp++ = ((u_int16_t *) enm->enm_addrlo)[2] << 16;
2966 #else
2967 *sp++ = ((u_int16_t *) enm->enm_addrlo)[0];
2968 *sp++ = ((u_int16_t *) enm->enm_addrlo)[1];
2969 *sp++ = ((u_int16_t *) enm->enm_addrlo)[2];
2970 #endif
2971 ETHER_NEXT_MULTI(step, enm);
2972 }
2973 /*
2974 * Add the broadcast address.
2975 */
2976 idx++;
2977 #if BYTE_ORDER == BIG_ENDIAN
2978 *sp++ = 0xFFFF << 16;
2979 *sp++ = 0xFFFF << 16;
2980 *sp++ = 0xFFFF << 16;
2981 #else
2982 *sp++ = 0xFFFF;
2983 *sp++ = 0xFFFF;
2984 *sp++ = 0xFFFF;
2985 #endif
2986 }
2987 /*
2988 * Pad the rest with our hardware address
2989 */
2990 for (; idx < 16; idx++) {
2991 #if BYTE_ORDER == BIG_ENDIAN
2992 *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0] << 16;
2993 *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1] << 16;
2994 *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2] << 16;
2995 #else
2996 *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0];
2997 *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1];
2998 *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2];
2999 #endif
3000 }
3001 }
3002 if (sc->tulip_flags & TULIP_ALLMULTI)
3003 sc->tulip_if.if_flags |= IFF_ALLMULTI;
3004 }
3005
3006 void
tulip_reset(tulip_softc_t * const sc)3007 tulip_reset(tulip_softc_t * const sc)
3008 {
3009 tulip_ringinfo_t *ri;
3010 tulip_desc_t *di;
3011 u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET);
3012
3013 /*
3014 * Brilliant. Simply brilliant. When switching modes/speeds
3015 * on a 2114*, you need to set the appropriate MII/PCS/SCL/PS
3016 * bits in CSR6 and then do a software reset to get the 21140
3017 * to properly reset its internal pathways to the right places.
3018 * Grrrr.
3019 */
3020 if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0
3021 && sc->tulip_boardsw->bd_media_preset != NULL)
3022 (*sc->tulip_boardsw->bd_media_preset)(sc);
3023
3024 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
3025 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
3026 33MHz that comes to two microseconds but wait a
3027 bit longer anyways) */
3028
3029 if (!inreset) {
3030 sc->tulip_flags |= TULIP_INRESET;
3031 sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW);
3032 ifq_clr_oactive(&sc->tulip_if.if_snd);
3033 }
3034
3035 TULIP_CSR_WRITE(sc, csr_txlist, sc->tulip_txdescmap->dm_segs[0].ds_addr);
3036 TULIP_CSR_WRITE(sc, csr_rxlist, sc->tulip_rxdescmap->dm_segs[0].ds_addr);
3037 TULIP_CSR_WRITE(sc, csr_busmode,
3038 (1 << (TULIP_BURSTSIZE(sc->tulip_unit) + 8))
3039 |TULIP_BUSMODE_CACHE_ALIGN8
3040 |TULIP_BUSMODE_READMULTIPLE
3041 |(BYTE_ORDER != LITTLE_ENDIAN ?
3042 TULIP_BUSMODE_DESC_BIGENDIAN : 0));
3043
3044 sc->tulip_txtimer = 0;
3045 /*
3046 * Free all the mbufs that were on the transmit ring.
3047 */
3048 for (;;) {
3049 bus_dmamap_t map;
3050 struct mbuf *m;
3051 m = ml_dequeue(&sc->tulip_txq);
3052 if (m == NULL)
3053 break;
3054 map = TULIP_GETCTX(m, bus_dmamap_t);
3055 bus_dmamap_unload(sc->tulip_dmatag, map);
3056 tulip_free_txmap(sc, map);
3057 m_freem(m);
3058 }
3059
3060 ri = &sc->tulip_txinfo;
3061 ri->ri_nextin = ri->ri_nextout = ri->ri_first;
3062 ri->ri_free = ri->ri_max;
3063 for (di = ri->ri_first; di < ri->ri_last; di++)
3064 di->d_status = 0;
3065 bus_dmamap_sync(sc->tulip_dmatag, sc->tulip_txdescmap,
3066 0, sc->tulip_txdescmap->dm_mapsize,
3067 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3068
3069 /*
3070 * We need to collect all the mbufs were on the
3071 * receive ring before we reinit it either to put
3072 * them back on or to know if we have to allocate
3073 * more.
3074 */
3075 ri = &sc->tulip_rxinfo;
3076 ri->ri_nextin = ri->ri_nextout = ri->ri_first;
3077 ri->ri_free = ri->ri_max;
3078 for (di = ri->ri_first; di < ri->ri_last; di++) {
3079 di->d_status = 0;
3080 di->d_length1 = 0; di->d_addr1 = 0;
3081 di->d_length2 = 0; di->d_addr2 = 0;
3082 }
3083 bus_dmamap_sync(sc->tulip_dmatag, sc->tulip_rxdescmap,
3084 0, sc->tulip_rxdescmap->dm_mapsize,
3085 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3086 for (;;) {
3087 bus_dmamap_t map;
3088 struct mbuf *m;
3089 m = ml_dequeue(&sc->tulip_rxq);
3090 if (m == NULL)
3091 break;
3092 map = TULIP_GETCTX(m, bus_dmamap_t);
3093 bus_dmamap_unload(sc->tulip_dmatag, map);
3094 tulip_free_rxmap(sc, map);
3095 m_freem(m);
3096 }
3097
3098 /*
3099 * If tulip_reset is being called recursively, exit quickly knowing
3100 * that when the outer tulip_reset returns all the right stuff will
3101 * have happened.
3102 */
3103 if (inreset)
3104 return;
3105
3106 sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
3107 |TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
3108 |TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE
3109 |TULIP_STS_RXSTOPPED;
3110
3111 if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0)
3112 (*sc->tulip_boardsw->bd_media_select)(sc);
3113 #if defined(TULIP_DEBUG)
3114 if ((sc->tulip_flags & TULIP_NEEDRESET) == TULIP_NEEDRESET)
3115 printf(TULIP_PRINTF_FMT ": tulip_reset: additional reset needed?!?\n",
3116 TULIP_PRINTF_ARGS);
3117 #endif
3118 tulip_media_print(sc);
3119 if (sc->tulip_features & TULIP_HAVE_DUALSENSE)
3120 TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
3121
3122 sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
3123 |TULIP_RXACT);
3124 tulip_addr_filter(sc);
3125 }
3126
3127 void
tulip_init(tulip_softc_t * const sc)3128 tulip_init(tulip_softc_t * const sc)
3129 {
3130 if (sc->tulip_if.if_flags & IFF_UP) {
3131 if ((sc->tulip_if.if_flags & IFF_RUNNING) == 0) {
3132 /* initialize the media */
3133 tulip_reset(sc);
3134 }
3135 sc->tulip_if.if_flags |= IFF_RUNNING;
3136 if (sc->tulip_if.if_flags & IFF_PROMISC) {
3137 sc->tulip_flags |= TULIP_PROMISC;
3138 sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS;
3139 sc->tulip_intrmask |= TULIP_STS_TXINTR;
3140 } else {
3141 sc->tulip_flags &= ~TULIP_PROMISC;
3142 sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS;
3143 if (sc->tulip_flags & TULIP_ALLMULTI)
3144 sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI;
3145 else
3146 sc->tulip_cmdmode &= ~TULIP_CMD_ALLMULTI;
3147 }
3148 sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
3149 if ((sc->tulip_flags & (TULIP_TXPROBE_ACTIVE|TULIP_WANTSETUP)) == 0) {
3150 tulip_rx_intr(sc);
3151 sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
3152 sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
3153 } else {
3154 ifq_set_oactive(&sc->tulip_if.if_snd);
3155 sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
3156 sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
3157 }
3158 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3159 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3160 if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
3161 tulip_txput_setup(sc);
3162 } else {
3163 sc->tulip_if.if_flags &= ~IFF_RUNNING;
3164 tulip_reset(sc);
3165 }
3166 }
3167
3168 void
tulip_rx_intr(tulip_softc_t * const sc)3169 tulip_rx_intr(tulip_softc_t * const sc)
3170 {
3171 TULIP_PERFSTART(rxintr)
3172 tulip_ringinfo_t * const ri = &sc->tulip_rxinfo;
3173 struct ifnet * const ifp = &sc->tulip_if;
3174 struct mbuf_list ml = MBUF_LIST_INITIALIZER();
3175 int fillok = 1;
3176 #if defined(TULIP_DEBUG)
3177 int cnt = 0;
3178 #endif
3179
3180 for (;;) {
3181 TULIP_PERFSTART(rxget)
3182 tulip_desc_t *eop = ri->ri_nextin;
3183 int total_len = 0, last_offset = 0;
3184 struct mbuf *ms = NULL, *me = NULL;
3185 int accept = 0;
3186 bus_dmamap_t map;
3187 int error;
3188
3189 if (fillok && ml_len(&sc->tulip_rxq) < TULIP_RXQ_TARGET)
3190 goto queue_mbuf;
3191
3192 #if defined(TULIP_DEBUG)
3193 if (cnt == ri->ri_max)
3194 break;
3195 #endif
3196 /*
3197 * If the TULIP has no descriptors, there can't be any receive
3198 * descriptors to process.
3199 */
3200 if (eop == ri->ri_nextout)
3201 break;
3202
3203 /*
3204 * 90% of the packets will fit in one descriptor. So we optimize
3205 * for that case.
3206 */
3207 TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
3208 if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
3209 #ifdef DIAGNOSTIC
3210 if (ml_empty(&sc->tulip_rxq))
3211 panic("%s: tulip_rxq empty", sc->tulip_if.if_xname);
3212 #endif
3213 ms = ml_dequeue(&sc->tulip_rxq);
3214 me = ms;
3215 } else {
3216 /*
3217 * If still owned by the TULIP, don't touch it.
3218 */
3219 if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER)
3220 break;
3221
3222 /*
3223 * It is possible (though improbable unless MCLBYTES < 1518) for
3224 * a received packet to cross more than one receive descriptor.
3225 */
3226 while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) {
3227 if (++eop == ri->ri_last)
3228 eop = ri->ri_first;
3229 TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
3230 if (eop == ri->ri_nextout || ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER))) {
3231 TULIP_PERFEND(rxget);
3232 goto out;
3233 }
3234 total_len++;
3235 }
3236
3237 /*
3238 * Dequeue the first buffer for the start of the packet. Hopefully
3239 * this will be the only one we need to dequeue. However, if the
3240 * packet consumed multiple descriptors, then we need to dequeue
3241 * those buffers and chain to the starting mbuf. All buffers but
3242 * the last buffer have the same length so we can set that now.
3243 * (we add to last_offset instead of multiplying since we normally
3244 * won't go into the loop and thereby saving a ourselves from
3245 * doing a multiplication by 0 in the normal case).
3246 */
3247 ms = ml_dequeue(&sc->tulip_rxq);
3248 for (me = ms; total_len > 0; total_len--) {
3249 map = TULIP_GETCTX(me, bus_dmamap_t);
3250 TULIP_RXMAP_POSTSYNC(sc, map);
3251 bus_dmamap_unload(sc->tulip_dmatag, map);
3252 tulip_free_rxmap(sc, map);
3253 me->m_len = TULIP_RX_BUFLEN;
3254 last_offset += TULIP_RX_BUFLEN;
3255 me->m_next = ml_dequeue(&sc->tulip_rxq);
3256 me = me->m_next;
3257 }
3258 }
3259
3260 /*
3261 * Now get the size of received packet (minus the CRC).
3262 */
3263 total_len = ((eop->d_status >> 16) & 0x7FFF) - 4;
3264 if ((sc->tulip_flags & TULIP_RXIGNORE) == 0
3265 && ((eop->d_status & TULIP_DSTS_ERRSUM) == 0)) {
3266 me->m_len = total_len - last_offset;
3267
3268 map = TULIP_GETCTX(me, bus_dmamap_t);
3269 bus_dmamap_sync(sc->tulip_dmatag, map, 0, me->m_len,
3270 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3271 bus_dmamap_unload(sc->tulip_dmatag, map);
3272 tulip_free_rxmap(sc, map);
3273 sc->tulip_flags |= TULIP_RXACT;
3274 accept = 1;
3275 } else {
3276 ifp->if_ierrors++;
3277 if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG))
3278 sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
3279 else {
3280 #ifdef TULIP_DEBUG
3281 const char *error = NULL;
3282 if (eop->d_status & TULIP_DSTS_RxTOOLONG) {
3283 sc->tulip_dot3stats.dot3StatsFrameTooLongs++;
3284 error = "frame too long";
3285 }
3286 if (eop->d_status & TULIP_DSTS_RxBADCRC) {
3287 if (eop->d_status & TULIP_DSTS_RxDRBBLBIT) {
3288 sc->tulip_dot3stats.dot3StatsAlignmentErrors++;
3289 error = "alignment error";
3290 } else {
3291 sc->tulip_dot3stats.dot3StatsFCSErrors++;
3292 error = "bad crc";
3293 }
3294 }
3295 if (error != NULL && (sc->tulip_flags & TULIP_NOMESSAGES) == 0) {
3296 printf(TULIP_PRINTF_FMT ": receive: %s: %s\n",
3297 TULIP_PRINTF_ARGS,
3298 ether_sprintf(mtod(ms, u_char *) + 6),
3299 error);
3300 sc->tulip_flags |= TULIP_NOMESSAGES;
3301 }
3302 #endif
3303 }
3304
3305 map = TULIP_GETCTX(me, bus_dmamap_t);
3306 bus_dmamap_unload(sc->tulip_dmatag, map);
3307 tulip_free_rxmap(sc, map);
3308 }
3309 #if defined(TULIP_DEBUG)
3310 cnt++;
3311 #endif
3312 if (++eop == ri->ri_last)
3313 eop = ri->ri_first;
3314 ri->ri_nextin = eop;
3315 queue_mbuf:
3316 /*
3317 * Either we are priming the TULIP with mbufs (m == NULL)
3318 * or we are about to accept an mbuf for the upper layers
3319 * so we need to allocate an mbuf to replace it. If we
3320 * can't replace it, send up it anyways. This may cause
3321 * us to drop packets in the future but that's better than
3322 * being caught in livelock.
3323 *
3324 * Note that if this packet crossed multiple descriptors
3325 * we don't even try to reallocate all the mbufs here.
3326 * Instead we rely on the test of the beginning of
3327 * the loop to refill for the extra consumed mbufs.
3328 */
3329 if (accept || ms == NULL) {
3330 struct mbuf *m0;
3331 MGETHDR(m0, M_DONTWAIT, MT_DATA);
3332 if (m0 != NULL) {
3333 #if defined(TULIP_COPY_RXDATA)
3334 if (!accept || total_len >= (MHLEN - 2)) {
3335 #endif
3336 MCLGET(m0, M_DONTWAIT);
3337 if ((m0->m_flags & M_EXT) == 0) {
3338 m_freem(m0);
3339 m0 = NULL;
3340 }
3341 #if defined(TULIP_COPY_RXDATA)
3342 }
3343 #endif
3344 }
3345 if (accept
3346 #if defined(TULIP_COPY_RXDATA)
3347 && m0 != NULL
3348 #endif
3349 ) {
3350 #if !defined(TULIP_COPY_RXDATA)
3351 ms->m_pkthdr.len = total_len;
3352 ml_enqueue(&ml, ms);
3353 #else
3354 m0->m_data += 2; /* align data after header */
3355 m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
3356 m0->m_len = m0->m_pkthdr.len = total_len;
3357 ml_enqueue(&ml, m0);
3358 m0 = ms;
3359 #endif
3360 }
3361 ms = m0;
3362 }
3363 if (ms == NULL) {
3364 /*
3365 * Couldn't allocate a new buffer. Don't bother
3366 * trying to replenish the receive queue.
3367 */
3368 fillok = 0;
3369 sc->tulip_flags |= TULIP_RXBUFSLOW;
3370 #if defined(TULIP_DEBUG)
3371 sc->tulip_dbg.dbg_rxlowbufs++;
3372 #endif
3373 TULIP_PERFEND(rxget);
3374 continue;
3375 }
3376 /*
3377 * Now give the buffer(s) to the TULIP and save in our
3378 * receive queue.
3379 */
3380 do {
3381 tulip_desc_t * const nextout = ri->ri_nextout;
3382 if (sc->tulip_num_free_rxmaps > 0) {
3383 map = tulip_alloc_rxmap(sc);
3384 } else {
3385 m_freem(ms);
3386 sc->tulip_flags |= TULIP_RXBUFSLOW;
3387 #if defined(TULIP_DEBUG)
3388 sc->tulip_dbg.dbg_rxlowbufs++;
3389 #endif
3390 break;
3391 }
3392 TULIP_SETCTX(ms, map);
3393 error = bus_dmamap_load(sc->tulip_dmatag, map, mtod(ms, void *),
3394 TULIP_RX_BUFLEN, NULL, BUS_DMA_NOWAIT);
3395 if (error) {
3396 printf(TULIP_PRINTF_FMT ": unable to load rx map, "
3397 "error = %d\n", TULIP_PRINTF_ARGS, error);
3398 panic("tulip_rx_intr"); /* XXX */
3399 }
3400 nextout->d_addr1 = map->dm_segs[0].ds_addr;
3401 nextout->d_length1 = map->dm_segs[0].ds_len;
3402 if (map->dm_nsegs == 2) {
3403 nextout->d_addr2 = map->dm_segs[1].ds_addr;
3404 nextout->d_length2 = map->dm_segs[1].ds_len;
3405 } else {
3406 nextout->d_addr2 = 0;
3407 nextout->d_length2 = 0;
3408 }
3409 TULIP_RXDESC_POSTSYNC(sc, nextout, sizeof(*nextout));
3410 nextout->d_status = TULIP_DSTS_OWNER;
3411 TULIP_RXDESC_POSTSYNC(sc, nextout, sizeof(u_int32_t));
3412 if (++ri->ri_nextout == ri->ri_last)
3413 ri->ri_nextout = ri->ri_first;
3414 me = ms->m_next;
3415 ms->m_next = NULL;
3416 ml_enqueue(&sc->tulip_rxq, ms);
3417 } while ((ms = me) != NULL);
3418
3419 if (ml_len(&sc->tulip_rxq) >= TULIP_RXQ_TARGET)
3420 sc->tulip_flags &= ~TULIP_RXBUFSLOW;
3421 TULIP_PERFEND(rxget);
3422 }
3423 out:
3424 if_input(ifp, &ml);
3425
3426 #if defined(TULIP_DEBUG)
3427 sc->tulip_dbg.dbg_rxintrs++;
3428 sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
3429 #endif
3430 TULIP_PERFEND(rxintr);
3431 }
3432
3433 int
tulip_tx_intr(tulip_softc_t * const sc)3434 tulip_tx_intr(tulip_softc_t * const sc)
3435 {
3436 TULIP_PERFSTART(txintr)
3437 tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
3438 struct mbuf *m;
3439 int xmits = 0;
3440 int descs = 0;
3441
3442 while (ri->ri_free < ri->ri_max) {
3443 u_int32_t d_flag;
3444
3445 TULIP_TXDESC_POSTSYNC(sc, ri->ri_nextin, sizeof(*ri->ri_nextin));
3446 if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER)
3447 break;
3448
3449 ri->ri_free++;
3450 descs++;
3451 d_flag = ri->ri_nextin->d_flag;
3452 if (d_flag & TULIP_DFLAG_TxLASTSEG) {
3453 if (d_flag & TULIP_DFLAG_TxSETUPPKT) {
3454 /*
3455 * We've just finished processing a setup packet.
3456 * Mark that we finished it. If there's not
3457 * another pending, startup the TULIP receiver.
3458 * Make sure we ack the RXSTOPPED so we won't get
3459 * an abnormal interrupt indication.
3460 */
3461 TULIP_TXMAP_POSTSYNC(sc, sc->tulip_setupmap);
3462 sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_HASHONLY);
3463 if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxINVRSFILT)
3464 sc->tulip_flags |= TULIP_HASHONLY;
3465 if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == 0) {
3466 tulip_rx_intr(sc);
3467 sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
3468 sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
3469 TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
3470 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3471 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3472 }
3473 } else {
3474 const u_int32_t d_status = ri->ri_nextin->d_status;
3475 m = ml_dequeue(&sc->tulip_txq);
3476 if (m != NULL) {
3477 bus_dmamap_t map = TULIP_GETCTX(m, bus_dmamap_t);
3478 TULIP_TXMAP_POSTSYNC(sc, map);
3479 tulip_free_txmap(sc, map);
3480 #if NBPFILTER > 0
3481 if (sc->tulip_bpf != NULL)
3482 bpf_mtap(sc->tulip_if.if_bpf, m, BPF_DIRECTION_OUT);
3483 #endif
3484 m_freem(m);
3485 }
3486 if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
3487 tulip_mediapoll_event_t event = TULIP_MEDIAPOLL_TXPROBE_OK;
3488 if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxEXCCOLL)) {
3489 #if defined(TULIP_DEBUG)
3490 if (d_status & TULIP_DSTS_TxNOCARR)
3491 sc->tulip_dbg.dbg_txprobe_nocarr++;
3492 if (d_status & TULIP_DSTS_TxEXCCOLL)
3493 sc->tulip_dbg.dbg_txprobe_exccoll++;
3494 #endif
3495 event = TULIP_MEDIAPOLL_TXPROBE_FAILED;
3496 }
3497 (*sc->tulip_boardsw->bd_media_poll)(sc, event);
3498 /*
3499 * Escape from the loop before media poll has reset the TULIP!
3500 */
3501 break;
3502 } else {
3503 xmits++;
3504 if (d_status & TULIP_DSTS_ERRSUM) {
3505 sc->tulip_if.if_oerrors++;
3506 if (d_status & TULIP_DSTS_TxEXCCOLL)
3507 sc->tulip_dot3stats.dot3StatsExcessiveCollisions++;
3508 if (d_status & TULIP_DSTS_TxLATECOLL)
3509 sc->tulip_dot3stats.dot3StatsLateCollisions++;
3510 if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxCARRLOSS))
3511 sc->tulip_dot3stats.dot3StatsCarrierSenseErrors++;
3512 if (d_status & (TULIP_DSTS_TxUNDERFLOW|TULIP_DSTS_TxBABBLE))
3513 sc->tulip_dot3stats.dot3StatsInternalMacTransmitErrors++;
3514 if (d_status & TULIP_DSTS_TxUNDERFLOW)
3515 sc->tulip_dot3stats.dot3StatsInternalTransmitUnderflows++;
3516 if (d_status & TULIP_DSTS_TxBABBLE)
3517 sc->tulip_dot3stats.dot3StatsInternalTransmitBabbles++;
3518 } else {
3519 u_int32_t collisions =
3520 (d_status & TULIP_DSTS_TxCOLLMASK)
3521 >> TULIP_DSTS_V_TxCOLLCNT;
3522 sc->tulip_if.if_collisions += collisions;
3523 if (collisions == 1)
3524 sc->tulip_dot3stats.dot3StatsSingleCollisionFrames++;
3525 else if (collisions > 1)
3526 sc->tulip_dot3stats.dot3StatsMultipleCollisionFrames++;
3527 else if (d_status & TULIP_DSTS_TxDEFERRED)
3528 sc->tulip_dot3stats.dot3StatsDeferredTransmissions++;
3529 /*
3530 * SQE is only valid for 10baseT/BNC/AUI when not
3531 * running in full-duplex. In order to speed up the
3532 * test, the corresponding bit in tulip_flags needs to
3533 * set as well to get us to count SQE Test Errors.
3534 */
3535 if (d_status & TULIP_DSTS_TxNOHRTBT & sc->tulip_flags)
3536 sc->tulip_dot3stats.dot3StatsSQETestErrors++;
3537 }
3538 }
3539 }
3540 }
3541
3542 if (++ri->ri_nextin == ri->ri_last)
3543 ri->ri_nextin = ri->ri_first;
3544
3545 if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
3546 ifq_clr_oactive(&sc->tulip_if.if_snd);
3547 }
3548 /*
3549 * If nothing left to transmit, disable the timer.
3550 * Else if progress, reset the timer back to 2 ticks.
3551 */
3552 if (ri->ri_free == ri->ri_max || (sc->tulip_flags & TULIP_TXPROBE_ACTIVE))
3553 sc->tulip_txtimer = 0;
3554 else if (xmits > 0)
3555 sc->tulip_txtimer = TULIP_TXTIMER;
3556 TULIP_PERFEND(txintr);
3557 return (descs);
3558 }
3559
3560 void
tulip_print_abnormal_interrupt(tulip_softc_t * const sc,u_int32_t csr)3561 tulip_print_abnormal_interrupt(tulip_softc_t * const sc, u_int32_t csr)
3562 {
3563 #ifdef TULIP_DEBUG
3564 const char * const *msgp = tulip_status_bits;
3565 const char *sep;
3566 u_int32_t mask;
3567 const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024\0";
3568
3569 csr &= (1 << (nitems(tulip_status_bits))) - 1;
3570 printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS);
3571 for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) {
3572 if ((csr & mask) && *msgp != NULL) {
3573 printf("%s%s", sep, *msgp);
3574 if (mask == TULIP_STS_TXUNDERFLOW && (sc->tulip_flags & TULIP_NEWTXTHRESH)) {
3575 sc->tulip_flags &= ~TULIP_NEWTXTHRESH;
3576 if (sc->tulip_cmdmode & TULIP_CMD_STOREFWD)
3577 printf(" (switching to store-and-forward mode)");
3578 else {
3579 printf(" (raising TX threshold to %s)",
3580 &thrsh[9 * ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) >> 14)]);
3581 }
3582 }
3583 sep = ", ";
3584 }
3585 }
3586 printf("\n");
3587 #endif
3588 }
3589
3590 void
tulip_intr_handler(tulip_softc_t * const sc,int * progress_p)3591 tulip_intr_handler(tulip_softc_t * const sc, int *progress_p)
3592 {
3593 TULIP_PERFSTART(intr)
3594 u_int32_t csr;
3595
3596 while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) {
3597 *progress_p = 1;
3598 TULIP_CSR_WRITE(sc, csr_status, csr);
3599
3600 if (csr & TULIP_STS_SYSERROR) {
3601 sc->tulip_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
3602 if (sc->tulip_flags & TULIP_NOMESSAGES)
3603 sc->tulip_flags |= TULIP_SYSTEMERROR;
3604 else {
3605 #if defined(TULIP_DEBUG)
3606 printf(TULIP_PRINTF_FMT ": system error: %s\n",
3607 TULIP_PRINTF_ARGS,
3608 tulip_system_errors[sc->tulip_last_system_error]);
3609 #endif
3610 }
3611 sc->tulip_flags |= TULIP_NEEDRESET;
3612 sc->tulip_system_errors++;
3613 break;
3614 }
3615 if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL) & sc->tulip_intrmask) {
3616 #if defined(TULIP_DEBUG)
3617 sc->tulip_dbg.dbg_link_intrs++;
3618 #endif
3619 if (sc->tulip_boardsw->bd_media_poll != NULL) {
3620 (*sc->tulip_boardsw->bd_media_poll)(sc, csr & TULIP_STS_LINKFAIL
3621 ? TULIP_MEDIAPOLL_LINKFAIL
3622 : TULIP_MEDIAPOLL_LINKPASS);
3623 csr &= ~TULIP_STS_ABNRMLINTR;
3624 }
3625 tulip_media_print(sc);
3626 }
3627 if (csr & (TULIP_STS_RXINTR|TULIP_STS_RXNOBUF)) {
3628 u_int32_t misses = TULIP_CSR_READ(sc, csr_missed_frames);
3629 if (csr & TULIP_STS_RXNOBUF)
3630 sc->tulip_dot3stats.dot3StatsMissedFrames += misses & 0xFFFF;
3631 /*
3632 * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
3633 * on receive overflows.
3634 */
3635 if ((misses & 0x0FFE0000) && (sc->tulip_features & TULIP_HAVE_RXBADOVRFLW)) {
3636 sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
3637 /*
3638 * Stop the receiver process and spin until it's stopped.
3639 * Tell rx_intr to drop the packets it dequeues.
3640 */
3641 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode & ~TULIP_CMD_RXRUN);
3642 while ((TULIP_CSR_READ(sc, csr_status) & TULIP_STS_RXSTOPPED) == 0)
3643 ;
3644 TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
3645 sc->tulip_flags |= TULIP_RXIGNORE;
3646 }
3647 tulip_rx_intr(sc);
3648 if (sc->tulip_flags & TULIP_RXIGNORE) {
3649 /*
3650 * Restart the receiver.
3651 */
3652 sc->tulip_flags &= ~TULIP_RXIGNORE;
3653 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3654 }
3655 }
3656 if (csr & TULIP_STS_ABNRMLINTR) {
3657 u_int32_t tmp = csr & sc->tulip_intrmask
3658 & ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
3659 if (csr & TULIP_STS_TXUNDERFLOW) {
3660 #if defined(TULIP_DEBUG)
3661 printf ("Underflow interrupt\n");
3662 #endif
3663 if ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) != TULIP_CMD_THRSHLD160) {
3664 sc->tulip_cmdmode += TULIP_CMD_THRSHLD96;
3665 sc->tulip_flags |= TULIP_NEWTXTHRESH;
3666 } else if (sc->tulip_features & TULIP_HAVE_STOREFWD) {
3667 sc->tulip_cmdmode |= TULIP_CMD_STOREFWD;
3668 sc->tulip_flags |= TULIP_NEWTXTHRESH;
3669 }
3670 }
3671 if (sc->tulip_flags & TULIP_NOMESSAGES)
3672 sc->tulip_statusbits |= tmp;
3673 else {
3674 tulip_print_abnormal_interrupt(sc, tmp);
3675 sc->tulip_flags |= TULIP_NOMESSAGES;
3676 }
3677 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3678 }
3679 if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_TXPROBE_ACTIVE|TULIP_DOINGSETUP|TULIP_PROMISC)) {
3680 tulip_tx_intr(sc);
3681 if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
3682 tulip_ifstart(&sc->tulip_if);
3683 }
3684 }
3685 if (sc->tulip_flags & TULIP_NEEDRESET) {
3686 tulip_reset(sc);
3687 tulip_init(sc);
3688 }
3689 TULIP_PERFEND(intr);
3690 }
3691
3692 int
tulip_intr_shared(void * arg)3693 tulip_intr_shared(void *arg)
3694 {
3695 tulip_softc_t * sc = arg;
3696 int progress = 0;
3697
3698 for (; sc != NULL; sc = sc->tulip_slaves) {
3699 #if defined(TULIP_DEBUG)
3700 sc->tulip_dbg.dbg_intrs++;
3701 #endif
3702 tulip_intr_handler(sc, &progress);
3703 }
3704 return (progress);
3705 }
3706
3707 int
tulip_intr_normal(void * arg)3708 tulip_intr_normal(void *arg)
3709 {
3710 tulip_softc_t * sc = (tulip_softc_t *) arg;
3711 int progress = 0;
3712
3713 #if defined(TULIP_DEBUG)
3714 sc->tulip_dbg.dbg_intrs++;
3715 #endif
3716 tulip_intr_handler(sc, &progress);
3717
3718 return (progress);
3719 }
3720
3721 struct mbuf *
tulip_txput(tulip_softc_t * const sc,struct mbuf * m,int notonqueue)3722 tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue)
3723 {
3724 TULIP_PERFSTART(txput)
3725 tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
3726 tulip_desc_t *eop, *nextout;
3727 int segcnt, freedescs;
3728 u_int32_t d_status;
3729 bus_dmamap_t map;
3730 struct ifnet *ifp = &sc->tulip_if;
3731 void (*set_oactive)(struct ifqueue *) =
3732 notonqueue ? ifq_set_oactive : ifq_deq_set_oactive;
3733
3734 #if defined(TULIP_DEBUG)
3735 if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
3736 printf(TULIP_PRINTF_FMT ": txput%s: tx not running\n",
3737 TULIP_PRINTF_ARGS,
3738 (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : "");
3739 sc->tulip_flags |= TULIP_WANTTXSTART;
3740 sc->tulip_dbg.dbg_txput_finishes[0]++;
3741 goto finish;
3742 }
3743 #endif
3744
3745 /*
3746 * Now we try to fill in our transmit descriptors. This is
3747 * a bit reminiscent of going on the Ark two by two
3748 * since each descriptor for the TULIP can describe
3749 * two buffers. So we advance through packet filling
3750 * each of the two entries at a time to fill each
3751 * descriptor. Clear the first and last segment bits
3752 * in each descriptor (actually just clear everything
3753 * but the end-of-ring or chain bits) to make sure
3754 * we don't get messed up by previously sent packets.
3755 *
3756 * We may fail to put the entire packet on the ring if
3757 * there is either not enough ring entries free or if the
3758 * packet has more than MAX_TXSEG segments. In the former
3759 * case we will just wait for the ring to empty. In the
3760 * latter case we have to recopy.
3761 */
3762 d_status = 0;
3763 eop = nextout = ri->ri_nextout;
3764 segcnt = 0;
3765 freedescs = ri->ri_free;
3766
3767 /*
3768 * Reclaim some DMA maps from if we are out.
3769 */
3770 if (sc->tulip_num_free_txmaps == 0) {
3771 #if defined(TULIP_DEBUG)
3772 sc->tulip_dbg.dbg_no_txmaps++;
3773 #endif
3774 freedescs += tulip_tx_intr(sc);
3775 }
3776 if (sc->tulip_num_free_txmaps > 0)
3777 map = tulip_alloc_txmap(sc);
3778 else {
3779 sc->tulip_flags |= TULIP_WANTTXSTART;
3780 #if defined(TULIP_DEBUG)
3781 sc->tulip_dbg.dbg_txput_finishes[1]++;
3782 #endif
3783 goto finish;
3784 }
3785 switch (bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT)) {
3786 case 0:
3787 break;
3788 case EFBIG:
3789 /*
3790 * The packet exceeds the number of transmit buffer
3791 * entries that we can use for one packet, so we have
3792 * to recopy it into one mbuf and then try again.
3793 */
3794 if (m_defrag(m, M_DONTWAIT) == 0 &&
3795 bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT) == 0)
3796 break;
3797 /* FALLTHROUGH */
3798 default:
3799 tulip_free_txmap(sc, map);
3800 goto finish;
3801 }
3802
3803 if ((freedescs -= (map->dm_nsegs + 1) / 2) <= 0
3804 /*
3805 * See if there's any unclaimed space in the transmit ring.
3806 */
3807 && (freedescs += tulip_tx_intr(sc)) <= 0) {
3808 /*
3809 * There's no more room but since nothing
3810 * has been committed at this point, just
3811 * show output is active, put back the
3812 * mbuf and return.
3813 */
3814 sc->tulip_flags |= TULIP_WANTTXSTART;
3815 #if defined(TULIP_DEBUG)
3816 sc->tulip_dbg.dbg_txput_finishes[4]++;
3817 #endif
3818 bus_dmamap_unload(sc->tulip_dmatag, map);
3819 tulip_free_txmap(sc, map);
3820 goto finish;
3821 }
3822 for (; map->dm_nsegs - segcnt > 1; segcnt += 2) {
3823 eop = nextout;
3824 eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
3825 eop->d_status = d_status;
3826 eop->d_addr1 = map->dm_segs[segcnt].ds_addr;
3827 eop->d_length1 = map->dm_segs[segcnt].ds_len;
3828 eop->d_addr2 = map->dm_segs[segcnt+1].ds_addr;
3829 eop->d_length2 = map->dm_segs[segcnt+1].ds_len;
3830 d_status = TULIP_DSTS_OWNER;
3831 if (++nextout == ri->ri_last)
3832 nextout = ri->ri_first;
3833 }
3834 if (segcnt < map->dm_nsegs) {
3835 eop = nextout;
3836 eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
3837 eop->d_status = d_status;
3838 eop->d_addr1 = map->dm_segs[segcnt].ds_addr;
3839 eop->d_length1 = map->dm_segs[segcnt].ds_len;
3840 eop->d_addr2 = 0;
3841 eop->d_length2 = 0;
3842 if (++nextout == ri->ri_last)
3843 nextout = ri->ri_first;
3844 }
3845 TULIP_TXMAP_PRESYNC(sc, map);
3846
3847 /*
3848 * The descriptors have been filled in. Now get ready
3849 * to transmit.
3850 */
3851 if (!notonqueue) {
3852 ifq_deq_commit(&ifp->if_snd, m);
3853 set_oactive = ifq_set_oactive;
3854 }
3855
3856 TULIP_SETCTX(m, map);
3857 map = NULL;
3858
3859 ml_enqueue(&sc->tulip_txq, m);
3860 m = NULL;
3861
3862 /*
3863 * Make sure the next descriptor after this packet is owned
3864 * by us since it may have been set up above if we ran out
3865 * of room in the ring.
3866 */
3867 nextout->d_status = 0;
3868 TULIP_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
3869
3870 /*
3871 * Mark the last and first segments, indicate we want a transmit
3872 * complete interrupt, and tell it to transmit!
3873 */
3874 eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR;
3875
3876 /*
3877 * Note that ri->ri_nextout is still the start of the packet
3878 * and until we set the OWNER bit, we can still back out of
3879 * everything we have done.
3880 */
3881 ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
3882 if (eop < ri->ri_nextout) {
3883 TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout,
3884 (caddr_t) ri->ri_last - (caddr_t) ri->ri_nextout);
3885 TULIP_TXDESC_PRESYNC(sc, ri->ri_first,
3886 (caddr_t) (eop + 1) - (caddr_t) ri->ri_first);
3887 } else {
3888 TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout,
3889 (caddr_t) (eop + 1) - (caddr_t) ri->ri_nextout);
3890 }
3891 ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
3892 TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
3893
3894 /*
3895 * This advances the ring for us.
3896 */
3897 ri->ri_nextout = nextout;
3898 ri->ri_free = freedescs;
3899
3900 TULIP_PERFEND(txput);
3901
3902 if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
3903 TULIP_CSR_WRITE(sc, csr_txpoll, 1);
3904 (*set_oactive)(&sc->tulip_if.if_snd);
3905 TULIP_PERFEND(txput);
3906 return (NULL);
3907 }
3908
3909 /*
3910 * switch back to the single queueing ifstart.
3911 */
3912 sc->tulip_flags &= ~TULIP_WANTTXSTART;
3913 if (sc->tulip_txtimer == 0)
3914 sc->tulip_txtimer = TULIP_TXTIMER;
3915 #if defined(TULIP_DEBUG)
3916 sc->tulip_dbg.dbg_txput_finishes[5]++;
3917 #endif
3918
3919 /*
3920 * If we want a txstart, there must be not enough space in the
3921 * transmit ring. So we want to enable transmit done interrupts
3922 * so we can immediately reclaim some space. When the transmit
3923 * interrupt is posted, the interrupt handler will call tx_intr
3924 * to reclaim space and then txstart (since WANTTXSTART is set).
3925 * txstart will move the packet into the transmit ring and clear
3926 * WANTTXSTART thereby causing TXINTR to be cleared.
3927 */
3928 finish:
3929 #if defined(TULIP_DEBUG)
3930 sc->tulip_dbg.dbg_txput_finishes[6]++;
3931 #endif
3932 if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) {
3933 (*set_oactive)(&sc->tulip_if.if_snd);
3934 if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
3935 sc->tulip_intrmask |= TULIP_STS_TXINTR;
3936 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3937 }
3938 } else if ((sc->tulip_flags & TULIP_PROMISC) == 0) {
3939 if (sc->tulip_intrmask & TULIP_STS_TXINTR) {
3940 sc->tulip_intrmask &= ~TULIP_STS_TXINTR;
3941 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3942 }
3943 }
3944 TULIP_CSR_WRITE(sc, csr_txpoll, 1);
3945 TULIP_PERFEND(txput);
3946 return (m);
3947 }
3948
3949 void
tulip_txput_setup(tulip_softc_t * const sc)3950 tulip_txput_setup(tulip_softc_t * const sc)
3951 {
3952 tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
3953 tulip_desc_t *nextout;
3954
3955 /*
3956 * We will transmit, at most, one setup packet per call to ifstart.
3957 */
3958
3959 #if defined(TULIP_DEBUG)
3960 if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
3961 printf(TULIP_PRINTF_FMT ": txput_setup: tx not running\n",
3962 TULIP_PRINTF_ARGS);
3963 sc->tulip_flags |= TULIP_WANTTXSTART;
3964 return;
3965 }
3966 #endif
3967 /*
3968 * Try to reclaim some free descriptors..
3969 */
3970 if (ri->ri_free < 2)
3971 tulip_tx_intr(sc);
3972 if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) {
3973 sc->tulip_flags |= TULIP_WANTTXSTART;
3974 return;
3975 }
3976 bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
3977 sizeof(sc->tulip_setupdata));
3978 /*
3979 * Clear WANTSETUP and set DOINGSETUP. Set know that WANTSETUP is
3980 * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
3981 */
3982 sc->tulip_flags ^= TULIP_WANTSETUP|TULIP_DOINGSETUP;
3983 ri->ri_free--;
3984 nextout = ri->ri_nextout;
3985 nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
3986 nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG
3987 |TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR;
3988 if (sc->tulip_flags & TULIP_WANTHASHPERFECT)
3989 nextout->d_flag |= TULIP_DFLAG_TxHASHFILT;
3990 else if (sc->tulip_flags & TULIP_WANTHASHONLY)
3991 nextout->d_flag |= TULIP_DFLAG_TxHASHFILT|TULIP_DFLAG_TxINVRSFILT;
3992
3993 nextout->d_length2 = 0;
3994 nextout->d_addr2 = 0;
3995 nextout->d_length1 = sc->tulip_setupmap->dm_segs[0].ds_len;
3996 nextout->d_addr1 = sc->tulip_setupmap->dm_segs[0].ds_addr;
3997 if (sc->tulip_setupmap->dm_nsegs == 2) {
3998 nextout->d_length2 = sc->tulip_setupmap->dm_segs[1].ds_len;
3999 nextout->d_addr2 = sc->tulip_setupmap->dm_segs[1].ds_addr;
4000 }
4001 TULIP_TXMAP_PRESYNC(sc, sc->tulip_setupmap);
4002 TULIP_TXDESC_PRESYNC(sc, nextout, sizeof(*nextout));
4003
4004 /*
4005 * Advance the ring for the next transmit packet.
4006 */
4007 if (++ri->ri_nextout == ri->ri_last)
4008 ri->ri_nextout = ri->ri_first;
4009
4010 /*
4011 * Make sure the next descriptor is owned by us since it
4012 * may have been set up above if we ran out of room in the
4013 * ring.
4014 */
4015 ri->ri_nextout->d_status = 0;
4016 TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
4017 nextout->d_status = TULIP_DSTS_OWNER;
4018 /*
4019 * Flush the ownership of the current descriptor
4020 */
4021 TULIP_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
4022 TULIP_CSR_WRITE(sc, csr_txpoll, 1);
4023 if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
4024 sc->tulip_intrmask |= TULIP_STS_TXINTR;
4025 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4026 }
4027 }
4028
4029 /*
4030 * This routine is entered at splnet().
4031 */
4032 int
tulip_ifioctl(struct ifnet * ifp,u_long cmd,caddr_t data)4033 tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data)
4034 {
4035 TULIP_PERFSTART(ifioctl)
4036 tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
4037 struct ifreq *ifr = (struct ifreq *) data;
4038 int s;
4039 int error = 0;
4040
4041 s = splnet();
4042
4043 switch (cmd) {
4044 case SIOCSIFADDR: {
4045 ifp->if_flags |= IFF_UP;
4046 tulip_init(sc);
4047 break;
4048 }
4049
4050 case SIOCSIFFLAGS: {
4051 tulip_init(sc);
4052 break;
4053 }
4054
4055 case SIOCSIFMEDIA:
4056 case SIOCGIFMEDIA: {
4057 error = ifmedia_ioctl(ifp, ifr, &sc->tulip_ifmedia, cmd);
4058 break;
4059 }
4060
4061 default:
4062 error = ether_ioctl(ifp, &sc->tulip_ac, cmd, data);
4063 }
4064
4065 if (error == ENETRESET) {
4066 if (ifp->if_flags & IFF_RUNNING) {
4067 tulip_addr_filter(sc); /* reset multicast filtering */
4068 tulip_init(sc);
4069 }
4070 error = 0;
4071 }
4072
4073 splx(s);
4074 TULIP_PERFEND(ifioctl);
4075 return (error);
4076 }
4077
4078 /*
4079 * the original dequeueing policy is dequeue-and-prepend if something
4080 * goes wrong.
4081 * the modification becomes a bit complicated since tulip_txput() might
4082 * copy and modify the mbuf passed.
4083 */
4084
4085 void
tulip_ifstart(struct ifnet * const ifp)4086 tulip_ifstart(struct ifnet * const ifp)
4087 {
4088 TULIP_PERFSTART(ifstart)
4089 tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
4090 struct mbuf *m, *m0;
4091
4092 if (sc->tulip_if.if_flags & IFF_RUNNING) {
4093
4094 if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
4095 tulip_txput_setup(sc);
4096
4097 for (;;) {
4098 m = ifq_deq_begin(&sc->tulip_if.if_snd);
4099 if (m == NULL)
4100 break;
4101 m0 = tulip_txput(sc, m, 0);
4102 if (m0 != NULL) {
4103 KASSERT(m == m0);
4104 ifq_deq_rollback(&sc->tulip_if.if_snd, m);
4105 break;
4106 }
4107 }
4108 }
4109
4110 TULIP_PERFEND(ifstart);
4111 }
4112
4113 void
tulip_ifwatchdog(struct ifnet * ifp)4114 tulip_ifwatchdog(struct ifnet *ifp)
4115 {
4116 TULIP_PERFSTART(ifwatchdog)
4117 tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
4118
4119 #if defined(TULIP_DEBUG)
4120 u_int32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
4121 if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz)
4122 sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs;
4123 sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs;
4124 #endif /* TULIP_DEBUG */
4125
4126 sc->tulip_if.if_timer = 1;
4127 /*
4128 * These should be rare so do a bulk test up front so we can just skip
4129 * them if needed.
4130 */
4131 if (sc->tulip_flags & (TULIP_SYSTEMERROR|TULIP_RXBUFSLOW|TULIP_NOMESSAGES)) {
4132 /*
4133 * If the number of receive buffer is low, try to refill
4134 */
4135 if (sc->tulip_flags & TULIP_RXBUFSLOW)
4136 tulip_rx_intr(sc);
4137
4138 #if defined(TULIP_DEBUG)
4139 if (sc->tulip_flags & TULIP_SYSTEMERROR) {
4140 printf(TULIP_PRINTF_FMT ": %d system errors: last was %s\n",
4141 TULIP_PRINTF_ARGS, sc->tulip_system_errors,
4142 tulip_system_errors[sc->tulip_last_system_error]);
4143 }
4144 #endif
4145 if (sc->tulip_statusbits) {
4146 tulip_print_abnormal_interrupt(sc, sc->tulip_statusbits);
4147 sc->tulip_statusbits = 0;
4148 }
4149
4150 sc->tulip_flags &= ~(TULIP_NOMESSAGES|TULIP_SYSTEMERROR);
4151 }
4152
4153 if (sc->tulip_txtimer)
4154 tulip_tx_intr(sc);
4155 if (sc->tulip_txtimer && --sc->tulip_txtimer == 0) {
4156 printf(TULIP_PRINTF_FMT ": transmission timeout\n", TULIP_PRINTF_ARGS);
4157 if (TULIP_DO_AUTOSENSE(sc)) {
4158 sc->tulip_media = TULIP_MEDIA_UNKNOWN;
4159 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
4160 sc->tulip_flags &= ~(TULIP_WANTRXACT|TULIP_LINKUP);
4161 }
4162 tulip_reset(sc);
4163 tulip_init(sc);
4164 }
4165
4166 TULIP_PERFEND(ifwatchdog);
4167 TULIP_PERFMERGE(sc, perf_intr_cycles);
4168 TULIP_PERFMERGE(sc, perf_ifstart_cycles);
4169 TULIP_PERFMERGE(sc, perf_ifioctl_cycles);
4170 TULIP_PERFMERGE(sc, perf_ifwatchdog_cycles);
4171 TULIP_PERFMERGE(sc, perf_timeout_cycles);
4172 TULIP_PERFMERGE(sc, perf_ifstart_one_cycles);
4173 TULIP_PERFMERGE(sc, perf_txput_cycles);
4174 TULIP_PERFMERGE(sc, perf_txintr_cycles);
4175 TULIP_PERFMERGE(sc, perf_rxintr_cycles);
4176 TULIP_PERFMERGE(sc, perf_rxget_cycles);
4177 TULIP_PERFMERGE(sc, perf_intr);
4178 TULIP_PERFMERGE(sc, perf_ifstart);
4179 TULIP_PERFMERGE(sc, perf_ifioctl);
4180 TULIP_PERFMERGE(sc, perf_ifwatchdog);
4181 TULIP_PERFMERGE(sc, perf_timeout);
4182 TULIP_PERFMERGE(sc, perf_ifstart_one);
4183 TULIP_PERFMERGE(sc, perf_txput);
4184 TULIP_PERFMERGE(sc, perf_txintr);
4185 TULIP_PERFMERGE(sc, perf_rxintr);
4186 TULIP_PERFMERGE(sc, perf_rxget);
4187 }
4188
4189 /*
4190 * All printf's are real as of now!
4191 */
4192 #ifdef printf
4193 #undef printf
4194 #endif
4195
4196 int
tulip_busdma_allocmem(tulip_softc_t * const sc,size_t size,bus_dmamap_t * map_p,tulip_desc_t ** desc_p)4197 tulip_busdma_allocmem(tulip_softc_t * const sc, size_t size,
4198 bus_dmamap_t *map_p, tulip_desc_t **desc_p)
4199 {
4200 bus_dma_segment_t segs[1];
4201 int nsegs, error;
4202 error = bus_dmamem_alloc(sc->tulip_dmatag, size, 1, PAGE_SIZE,
4203 segs, sizeof(segs)/sizeof(segs[0]),
4204 &nsegs, BUS_DMA_NOWAIT);
4205 if (error == 0) {
4206 void *desc;
4207 error = bus_dmamem_map(sc->tulip_dmatag, segs, nsegs, size,
4208 (void *) &desc, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
4209 if (error == 0) {
4210 bus_dmamap_t map;
4211 error = bus_dmamap_create(sc->tulip_dmatag, size, 1, size, 0,
4212 BUS_DMA_NOWAIT, &map);
4213 if (error == 0) {
4214 error = bus_dmamap_load(sc->tulip_dmatag, map, desc,
4215 size, NULL, BUS_DMA_NOWAIT);
4216 if (error)
4217 bus_dmamap_destroy(sc->tulip_dmatag, map);
4218 else
4219 *map_p = map;
4220 }
4221 if (error)
4222 bus_dmamem_unmap(sc->tulip_dmatag, desc, size);
4223 }
4224 if (error)
4225 bus_dmamem_free(sc->tulip_dmatag, segs, nsegs);
4226 else
4227 *desc_p = desc;
4228 }
4229 return (error);
4230 }
4231
4232 int
tulip_busdma_init(tulip_softc_t * const sc)4233 tulip_busdma_init(tulip_softc_t * const sc)
4234 {
4235 int error = 0;
4236
4237 /*
4238 * Allocate space and dmamap for setup descriptor
4239 */
4240 error = tulip_busdma_allocmem(sc, sizeof(sc->tulip_setupdata),
4241 &sc->tulip_setupmap, &sc->tulip_setupbuf);
4242
4243 /*
4244 * Allocate space and dmamap for transmit ring
4245 */
4246 if (error == 0) {
4247 error = tulip_busdma_allocmem(sc, sizeof(tulip_desc_t) * TULIP_TXDESCS,
4248 &sc->tulip_txdescmap,
4249 &sc->tulip_txdescs);
4250 }
4251
4252 /*
4253 * Allocate dmamaps for each transmit descriptor, and place on the
4254 * free list.
4255 */
4256 if (error == 0) {
4257 while (error == 0 && sc->tulip_num_free_txmaps < TULIP_TXDESCS) {
4258 bus_dmamap_t map;
4259 if ((error = TULIP_TXMAP_CREATE(sc, &map)) == 0)
4260 tulip_free_txmap(sc, map);
4261 }
4262 if (error) {
4263 while (sc->tulip_num_free_txmaps > 0)
4264 bus_dmamap_destroy(sc->tulip_dmatag, tulip_alloc_txmap(sc));
4265 }
4266 }
4267
4268 /*
4269 * Allocate space and dmamap for receive ring
4270 */
4271 if (error == 0) {
4272 error = tulip_busdma_allocmem(sc, sizeof(tulip_desc_t) * TULIP_RXDESCS,
4273 &sc->tulip_rxdescmap,
4274 &sc->tulip_rxdescs);
4275 }
4276
4277 /*
4278 * Allocate dmamaps for each receive descriptor, and place on the
4279 * free list.
4280 */
4281 if (error == 0) {
4282 while (error == 0 && sc->tulip_num_free_rxmaps < TULIP_RXDESCS) {
4283 bus_dmamap_t map;
4284 if ((error = TULIP_RXMAP_CREATE(sc, &map)) == 0)
4285 tulip_free_rxmap(sc, map);
4286 }
4287 if (error) {
4288 while (sc->tulip_num_free_rxmaps > 0)
4289 bus_dmamap_destroy(sc->tulip_dmatag, tulip_alloc_rxmap(sc));
4290 }
4291 }
4292 return (error);
4293 }
4294
4295 void
tulip_initcsrs(tulip_softc_t * const sc,bus_addr_t csr_base,size_t csr_size)4296 tulip_initcsrs(tulip_softc_t * const sc, bus_addr_t csr_base, size_t csr_size)
4297 {
4298 sc->tulip_csrs.csr_busmode = csr_base + 0 * csr_size;
4299 sc->tulip_csrs.csr_txpoll = csr_base + 1 * csr_size;
4300 sc->tulip_csrs.csr_rxpoll = csr_base + 2 * csr_size;
4301 sc->tulip_csrs.csr_rxlist = csr_base + 3 * csr_size;
4302 sc->tulip_csrs.csr_txlist = csr_base + 4 * csr_size;
4303 sc->tulip_csrs.csr_status = csr_base + 5 * csr_size;
4304 sc->tulip_csrs.csr_command = csr_base + 6 * csr_size;
4305 sc->tulip_csrs.csr_intr = csr_base + 7 * csr_size;
4306 sc->tulip_csrs.csr_missed_frames = csr_base + 8 * csr_size;
4307 sc->tulip_csrs.csr_9 = csr_base + 9 * csr_size;
4308 sc->tulip_csrs.csr_10 = csr_base + 10 * csr_size;
4309 sc->tulip_csrs.csr_11 = csr_base + 11 * csr_size;
4310 sc->tulip_csrs.csr_12 = csr_base + 12 * csr_size;
4311 sc->tulip_csrs.csr_13 = csr_base + 13 * csr_size;
4312 sc->tulip_csrs.csr_14 = csr_base + 14 * csr_size;
4313 sc->tulip_csrs.csr_15 = csr_base + 15 * csr_size;
4314 }
4315
4316 void
tulip_initring(tulip_softc_t * const sc,tulip_ringinfo_t * const ri,tulip_desc_t * descs,int ndescs)4317 tulip_initring(tulip_softc_t * const sc, tulip_ringinfo_t * const ri,
4318 tulip_desc_t *descs, int ndescs)
4319 {
4320 ri->ri_max = ndescs;
4321 ri->ri_first = descs;
4322 ri->ri_last = ri->ri_first + ri->ri_max;
4323 bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
4324 ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
4325 }
4326
4327 int
tulip_probe(struct device * parent,void * match,void * aux)4328 tulip_probe(struct device *parent, void *match, void *aux)
4329 {
4330 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
4331
4332 if (PCI_VENDORID(pa->pa_id) != DEC_VENDORID)
4333 return (0);
4334 if (PCI_CHIPID(pa->pa_id) == CHIPID_21040
4335 || PCI_CHIPID(pa->pa_id) == CHIPID_21041
4336 || PCI_CHIPID(pa->pa_id) == CHIPID_21140
4337 || PCI_CHIPID(pa->pa_id) == CHIPID_21142)
4338 return (2);
4339
4340 return (0);
4341 }
4342
4343 void
tulip_attach(struct device * const parent,struct device * const self,void * const aux)4344 tulip_attach(struct device * const parent, struct device * const self, void * const aux)
4345 {
4346 tulip_softc_t * const sc = (tulip_softc_t *) self;
4347 struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
4348 struct ifnet * const ifp = &sc->tulip_if;
4349 const int unit = sc->tulip_dev.dv_unit;
4350 int retval, idx;
4351 u_int32_t revinfo, cfdainfo, id;
4352 unsigned csroffset = TULIP_PCI_CSROFFSET;
4353 unsigned csrsize = TULIP_PCI_CSRSIZE;
4354 bus_addr_t csr_base;
4355 tulip_chipid_t chipid = TULIP_CHIPID_UNKNOWN;
4356
4357 if (unit >= TULIP_MAX_DEVICES) {
4358 printf(": not configured; limit of %d reached or exceeded\n",
4359 TULIP_MAX_DEVICES);
4360 return;
4361 }
4362
4363 ml_init(&sc->tulip_txq);
4364 ml_init(&sc->tulip_rxq);
4365
4366 revinfo = PCI_CONF_READ(PCI_CFRV) & 0xFF;
4367 id = PCI_CONF_READ(PCI_CFID);
4368 cfdainfo = PCI_CONF_READ(PCI_CFDA);
4369
4370 if (PCI_VENDORID(id) == DEC_VENDORID) {
4371 if (PCI_CHIPID(id) == CHIPID_21040)
4372 chipid = TULIP_21040;
4373 else if (PCI_CHIPID(id) == CHIPID_21041)
4374 chipid = TULIP_21041;
4375 else if (PCI_CHIPID(id) == CHIPID_21140)
4376 chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140;
4377 else if (PCI_CHIPID(id) == CHIPID_21142)
4378 chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142;
4379 }
4380
4381 if (chipid == TULIP_CHIPID_UNKNOWN)
4382 return;
4383
4384 if ((chipid == TULIP_21040 || chipid == TULIP_DE425) && revinfo < 0x20) {
4385 printf(": not configured; 21040 pass 2.0 required (%d.%d found)\n",
4386 revinfo >> 4, revinfo & 0x0f);
4387 return;
4388 } else if (chipid == TULIP_21140 && revinfo < 0x11) {
4389 printf(": not configured; 21140 pass 1.1 required (%d.%d found)\n",
4390 revinfo >> 4, revinfo & 0x0f);
4391 return;
4392 }
4393
4394 PCI_GETBUSDEVINFO(sc);
4395 sc->tulip_chipid = chipid;
4396 sc->tulip_flags |= TULIP_DEVICEPROBE;
4397 if (chipid == TULIP_21140 || chipid == TULIP_21140A)
4398 sc->tulip_features |= TULIP_HAVE_GPR|TULIP_HAVE_STOREFWD;
4399 if (chipid == TULIP_21140A && revinfo <= 0x22)
4400 sc->tulip_features |= TULIP_HAVE_RXBADOVRFLW;
4401 if (chipid == TULIP_21140)
4402 sc->tulip_features |= TULIP_HAVE_BROKEN_HASH;
4403 if (chipid != TULIP_21040 && chipid != TULIP_DE425 && chipid != TULIP_21140)
4404 sc->tulip_features |= TULIP_HAVE_POWERMGMT;
4405 if (chipid == TULIP_21041 || chipid == TULIP_21142 || chipid == TULIP_21143) {
4406 sc->tulip_features |= TULIP_HAVE_DUALSENSE;
4407 if (chipid != TULIP_21041 || revinfo >= 0x20)
4408 sc->tulip_features |= TULIP_HAVE_SIANWAY;
4409 if (chipid != TULIP_21041)
4410 sc->tulip_features |= TULIP_HAVE_SIAGP|TULIP_HAVE_RXBADOVRFLW|TULIP_HAVE_STOREFWD;
4411 if (chipid != TULIP_21041 && revinfo >= 0x20)
4412 sc->tulip_features |= TULIP_HAVE_SIA100;
4413 }
4414
4415 if (sc->tulip_features & TULIP_HAVE_POWERMGMT
4416 && (cfdainfo & (TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE))) {
4417 cfdainfo &= ~(TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE);
4418 PCI_CONF_WRITE(PCI_CFDA, cfdainfo);
4419 DELAY(11*1000);
4420 }
4421
4422 if (sc->tulip_features & TULIP_HAVE_STOREFWD)
4423 sc->tulip_cmdmode |= TULIP_CMD_STOREFWD;
4424
4425 bcopy(self->dv_xname, sc->tulip_if.if_xname, IFNAMSIZ);
4426 sc->tulip_if.if_softc = sc;
4427 sc->tulip_pc = pa->pa_pc;
4428 sc->tulip_dmatag = pa->pa_dmat;
4429 sc->tulip_revinfo = revinfo;
4430
4431 timeout_set(&sc->tulip_stmo, tulip_timeout_callback, sc);
4432
4433 csr_base = 0;
4434 {
4435 bus_space_tag_t iot, memt;
4436 bus_space_handle_t ioh, memh;
4437 int ioh_valid, memh_valid;
4438
4439 ioh_valid = (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
4440 &iot, &ioh, NULL, NULL, 0) == 0);
4441 memh_valid = (pci_mapreg_map(pa, PCI_CBMA,
4442 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
4443 &memt, &memh, NULL, NULL, 0) == 0);
4444
4445 if (memh_valid) {
4446 sc->tulip_bustag = memt;
4447 sc->tulip_bushandle = memh;
4448 } else if (ioh_valid) {
4449 sc->tulip_bustag = iot;
4450 sc->tulip_bushandle = ioh;
4451 } else {
4452 printf(": unable to map device registers\n");
4453 return;
4454 }
4455 }
4456
4457 tulip_initcsrs(sc, csr_base + csroffset, csrsize);
4458
4459 if ((retval = tulip_busdma_init(sc)) != 0) {
4460 printf(": error initing bus_dma: %d\n", retval);
4461 return;
4462 }
4463
4464 tulip_initring(sc, &sc->tulip_rxinfo, sc->tulip_rxdescs, TULIP_RXDESCS);
4465 tulip_initring(sc, &sc->tulip_txinfo, sc->tulip_txdescs, TULIP_TXDESCS);
4466
4467 /*
4468 * Make sure there won't be any interrupts or such...
4469 */
4470 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
4471 DELAY(100); /* Wait 10 microseconds (actually 50 PCI cycles but at
4472 33MHz that comes to two microseconds but wait a
4473 bit longer anyways) */
4474
4475 if ((retval = tulip_read_macaddr(sc)) < 0) {
4476 printf(", %s%s pass %d.%d", sc->tulip_boardid,
4477 tulip_chipdescs[sc->tulip_chipid],
4478 (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F);
4479 printf(": can't read ENET ROM (why=%d) (", retval);
4480 for (idx = 0; idx < 32; idx++)
4481 printf("%02x", sc->tulip_rombuf[idx]);
4482 printf(", address unknown\n");
4483 } else {
4484 int (*intr_rtn)(void *) = tulip_intr_normal;
4485
4486 if (sc->tulip_features & TULIP_HAVE_SHAREDINTR)
4487 intr_rtn = tulip_intr_shared;
4488
4489 if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
4490 pci_intr_handle_t intrhandle;
4491 const char *intrstr;
4492
4493 if (pci_intr_map(pa, &intrhandle)) {
4494 printf(": couldn't map interrupt\n");
4495 return;
4496 }
4497
4498 intrstr = pci_intr_string(pa->pa_pc, intrhandle);
4499 sc->tulip_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
4500 intr_rtn, sc, self->dv_xname);
4501 if (sc->tulip_ih == NULL) {
4502 printf(": couldn't establish interrupt");
4503 if (intrstr != NULL)
4504 printf(" at %s", intrstr);
4505 printf("\n");
4506 return;
4507 }
4508
4509 printf(", %s%s pass %d.%d%s: %s, address %s\n",
4510 sc->tulip_boardid,
4511 tulip_chipdescs[sc->tulip_chipid],
4512 (sc->tulip_revinfo & 0xF0) >> 4,
4513 sc->tulip_revinfo & 0x0F,
4514 (sc->tulip_features & (TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM))
4515 == TULIP_HAVE_ISVSROM ? " (invalid EESPROM checksum)" : "",
4516 intrstr, ether_sprintf(sc->tulip_enaddr));
4517 }
4518
4519 ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
4520 ifp->if_ioctl = tulip_ifioctl;
4521 ifp->if_start = tulip_ifstart;
4522 ifp->if_watchdog = tulip_ifwatchdog;
4523 ifp->if_timer = 1;
4524
4525 (*sc->tulip_boardsw->bd_media_probe)(sc);
4526 ifmedia_init(&sc->tulip_ifmedia, 0,
4527 tulip_ifmedia_change, tulip_ifmedia_status);
4528 sc->tulip_flags &= ~TULIP_DEVICEPROBE;
4529 tulip_ifmedia_add(sc);
4530
4531 tulip_reset(sc);
4532
4533 if_attach(ifp);
4534 ether_ifattach(ifp);
4535 }
4536 }
4537