Bug Summary

File:dev/pci/if_de.c
Warning:line 1617, column 15
Value stored to 'cmdmode' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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