Bug Summary

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