mb86960.c revision 1.23 1 1.23 mycroft /* $NetBSD: mb86960.c,v 1.23 1998/03/29 22:34:28 mycroft Exp $ */
2 1.19 perry
3 1.1 mycroft /*
4 1.1 mycroft * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
5 1.1 mycroft *
6 1.1 mycroft * This software may be used, modified, copied, distributed, and sold, in
7 1.1 mycroft * both source and binary form provided that the above copyright, these
8 1.1 mycroft * terms and the following disclaimer are retained. The name of the author
9 1.1 mycroft * and/or the contributor may not be used to endorse or promote products
10 1.1 mycroft * derived from this software without specific prior written permission.
11 1.1 mycroft *
12 1.1 mycroft * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
13 1.1 mycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 1.1 mycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15 1.1 mycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
16 1.1 mycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 1.1 mycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18 1.1 mycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
19 1.1 mycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 1.1 mycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21 1.1 mycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22 1.1 mycroft * SUCH DAMAGE.
23 1.1 mycroft */
24 1.1 mycroft
25 1.1 mycroft /*
26 1.1 mycroft * Portions copyright (C) 1993, David Greenman. This software may be used,
27 1.1 mycroft * modified, copied, distributed, and sold, in both source and binary form
28 1.1 mycroft * provided that the above copyright and these terms are retained. Under no
29 1.1 mycroft * circumstances is the author responsible for the proper functioning of this
30 1.1 mycroft * software, nor does the author assume any responsibility for damages
31 1.1 mycroft * incurred with its use.
32 1.1 mycroft */
33 1.1 mycroft
34 1.1 mycroft #define FE_VERSION "if_fe.c ver. 0.8"
35 1.1 mycroft
36 1.1 mycroft /*
37 1.1 mycroft * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
38 1.1 mycroft * Contributed by M.S. <seki (at) sysrap.cs.fujitsu.co.jp>
39 1.1 mycroft *
40 1.1 mycroft * This version is intended to be a generic template for various
41 1.1 mycroft * MB86960A/MB86965A based Ethernet cards. It currently supports
42 1.1 mycroft * Fujitsu FMV-180 series (i.e., FMV-181 and FMV-182) and Allied-
43 1.1 mycroft * Telesis AT1700 series and RE2000 series. There are some
44 1.1 mycroft * unnecessary hooks embedded, which are primarily intended to support
45 1.1 mycroft * other types of Ethernet cards, but the author is not sure whether
46 1.1 mycroft * they are useful.
47 1.1 mycroft */
48 1.1 mycroft
49 1.1 mycroft #include "bpfilter.h"
50 1.18 explorer #include "rnd.h"
51 1.1 mycroft
52 1.1 mycroft #include <sys/param.h>
53 1.1 mycroft #include <sys/systm.h>
54 1.1 mycroft #include <sys/errno.h>
55 1.1 mycroft #include <sys/ioctl.h>
56 1.1 mycroft #include <sys/mbuf.h>
57 1.1 mycroft #include <sys/socket.h>
58 1.1 mycroft #include <sys/syslog.h>
59 1.1 mycroft #include <sys/device.h>
60 1.18 explorer #if NRND > 0
61 1.18 explorer #include <sys/rnd.h>
62 1.18 explorer #endif
63 1.1 mycroft
64 1.1 mycroft #include <net/if.h>
65 1.1 mycroft #include <net/if_dl.h>
66 1.1 mycroft #include <net/if_types.h>
67 1.21 enami #include <net/if_media.h>
68 1.17 is #include <net/if_ether.h>
69 1.1 mycroft
70 1.1 mycroft #ifdef INET
71 1.1 mycroft #include <netinet/in.h>
72 1.1 mycroft #include <netinet/in_systm.h>
73 1.1 mycroft #include <netinet/in_var.h>
74 1.1 mycroft #include <netinet/ip.h>
75 1.17 is #include <netinet/if_inarp.h>
76 1.1 mycroft #endif
77 1.1 mycroft
78 1.1 mycroft #ifdef NS
79 1.1 mycroft #include <netns/ns.h>
80 1.1 mycroft #include <netns/ns_if.h>
81 1.1 mycroft #endif
82 1.1 mycroft
83 1.1 mycroft #if NBPFILTER > 0
84 1.1 mycroft #include <net/bpf.h>
85 1.1 mycroft #include <net/bpfdesc.h>
86 1.1 mycroft #endif
87 1.1 mycroft
88 1.21 enami #include <machine/bus.h>
89 1.1 mycroft
90 1.3 cgd #include <dev/ic/mb86960reg.h>
91 1.21 enami #include <dev/ic/mb86960var.h>
92 1.1 mycroft
93 1.1 mycroft /* Standard driver entry points. These can be static. */
94 1.21 enami void mb86960_init __P((struct mb86960_softc *));
95 1.21 enami int mb86960_ioctl __P((struct ifnet *, u_long, caddr_t));
96 1.21 enami void mb86960_start __P((struct ifnet *));
97 1.21 enami void mb86960_reset __P((struct mb86960_softc *));
98 1.21 enami void mb86960_watchdog __P((struct ifnet *));
99 1.1 mycroft
100 1.1 mycroft /* Local functions. Order of declaration is confused. FIXME. */
101 1.21 enami int mb86960_get_packet __P((struct mb86960_softc *, int));
102 1.21 enami void mb86960_stop __P((struct mb86960_softc *));
103 1.21 enami void mb86960_tint __P((struct mb86960_softc *, u_char));
104 1.21 enami void mb86960_rint __P((struct mb86960_softc *, u_char));
105 1.21 enami static __inline__
106 1.21 enami void mb86960_xmit __P((struct mb86960_softc *));
107 1.21 enami void mb86960_write_mbufs __P((struct mb86960_softc *, struct mbuf *));
108 1.21 enami static __inline__
109 1.21 enami void mb86960_droppacket __P((struct mb86960_softc *));
110 1.21 enami void mb86960_getmcaf __P((struct ethercom *, u_char *));
111 1.21 enami void mb86960_setmode __P((struct mb86960_softc *));
112 1.21 enami void mb86960_loadmar __P((struct mb86960_softc *));
113 1.1 mycroft
114 1.21 enami int mb86960_enable __P((struct mb86960_softc *));
115 1.21 enami void mb86960_disable __P((struct mb86960_softc *));
116 1.1 mycroft
117 1.21 enami int mb86960_mediachange __P((struct ifnet *));
118 1.21 enami void mb86960_mediastatus __P((struct ifnet *, struct ifmediareq *));
119 1.1 mycroft
120 1.21 enami #if FE_DEBUG >= 1
121 1.21 enami void mb86960_dump __P((int, struct mb86960_softc *));
122 1.1 mycroft #endif
123 1.1 mycroft
124 1.1 mycroft void
125 1.21 enami mb86960_attach(sc, type, myea)
126 1.21 enami struct mb86960_softc *sc;
127 1.21 enami enum mb86960_type type;
128 1.21 enami u_int8_t *myea;
129 1.1 mycroft {
130 1.21 enami bus_space_tag_t bst = sc->sc_bst;
131 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
132 1.1 mycroft
133 1.21 enami sc->type = type;
134 1.1 mycroft
135 1.21 enami /* Register values which depend on board design. */
136 1.21 enami sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL;
137 1.21 enami sc->proto_dlcr5 = 0;
138 1.21 enami sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
139 1.1 mycroft
140 1.21 enami switch (sc->type) {
141 1.21 enami case MB86960_TYPE_86960:
142 1.21 enami sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
143 1.1 mycroft break;
144 1.21 enami case MB86960_TYPE_86965:
145 1.21 enami sc->proto_dlcr7 = FE_D7_BYTSWP_LH;
146 1.1 mycroft break;
147 1.1 mycroft }
148 1.1 mycroft
149 1.1 mycroft /*
150 1.1 mycroft * Program the 86960 as follows:
151 1.1 mycroft * SRAM: 32KB, 100ns, byte-wide access.
152 1.1 mycroft * Transmission buffer: 4KB x 2.
153 1.1 mycroft * System bus interface: 16 bits.
154 1.1 mycroft * We cannot change these values but TXBSIZE, because they
155 1.1 mycroft * are hard-wired on the board. Modifying TXBSIZE will affect
156 1.1 mycroft * the driver performance.
157 1.1 mycroft */
158 1.21 enami sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB |
159 1.21 enami FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
160 1.1 mycroft
161 1.1 mycroft /*
162 1.1 mycroft * Minimum initialization of the hardware.
163 1.1 mycroft * We write into registers; hope I/O ports have no
164 1.1 mycroft * overlap with other boards.
165 1.1 mycroft */
166 1.1 mycroft
167 1.1 mycroft /* Initialize 86960. */
168 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
169 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
170 1.1 mycroft delay(200);
171 1.1 mycroft
172 1.21 enami #ifdef DIAGNOSTIC
173 1.21 enami if (myea == NULL) {
174 1.21 enami printf("%s: ethernet address shouldn't be NULL\n",
175 1.21 enami sc->sc_dev.dv_xname);
176 1.21 enami panic("NULL ethernet address");
177 1.1 mycroft }
178 1.1 mycroft #endif
179 1.21 enami bcopy(myea, sc->sc_enaddr, sizeof(sc->sc_enaddr));
180 1.1 mycroft
181 1.1 mycroft /* Disable all interrupts. */
182 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0);
183 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0);
184 1.1 mycroft }
185 1.1 mycroft
186 1.1 mycroft /*
187 1.1 mycroft * Install interface into kernel networking data structures
188 1.1 mycroft */
189 1.1 mycroft void
190 1.21 enami mb86960_config(sc, media, nmedia, defmedia)
191 1.21 enami struct mb86960_softc *sc;
192 1.21 enami int *media, nmedia, defmedia;
193 1.1 mycroft {
194 1.1 mycroft struct cfdata *cf = sc->sc_dev.dv_cfdata;
195 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
196 1.21 enami int i;
197 1.1 mycroft
198 1.1 mycroft /* Stop the 86960. */
199 1.21 enami mb86960_stop(sc);
200 1.1 mycroft
201 1.1 mycroft /* Initialize ifnet structure. */
202 1.12 thorpej bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
203 1.12 thorpej ifp->if_softc = sc;
204 1.21 enami ifp->if_start = mb86960_start;
205 1.21 enami ifp->if_ioctl = mb86960_ioctl;
206 1.21 enami ifp->if_watchdog = mb86960_watchdog;
207 1.6 mycroft ifp->if_flags =
208 1.6 mycroft IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
209 1.1 mycroft
210 1.1 mycroft #if FE_DEBUG >= 3
211 1.21 enami log(LOG_INFO, "%s: mb86960_config()\n", sc->sc_dev.dv_xname);
212 1.21 enami mb86960_dump(LOG_INFO, sc);
213 1.1 mycroft #endif
214 1.1 mycroft
215 1.1 mycroft #if FE_SINGLE_TRANSMISSION
216 1.1 mycroft /* Override txb config to allocate minimum. */
217 1.1 mycroft sc->proto_dlcr6 &= ~FE_D6_TXBSIZ
218 1.1 mycroft sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
219 1.1 mycroft #endif
220 1.1 mycroft
221 1.1 mycroft /* Modify hardware config if it is requested. */
222 1.1 mycroft if ((cf->cf_flags & FE_FLAGS_OVERRIDE_DLCR6) != 0)
223 1.1 mycroft sc->proto_dlcr6 = cf->cf_flags & FE_FLAGS_DLCR6_VALUE;
224 1.1 mycroft
225 1.1 mycroft /* Find TX buffer size, based on the hardware dependent proto. */
226 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) {
227 1.1 mycroft case FE_D6_TXBSIZ_2x2KB:
228 1.1 mycroft sc->txb_size = 2048;
229 1.1 mycroft break;
230 1.1 mycroft case FE_D6_TXBSIZ_2x4KB:
231 1.1 mycroft sc->txb_size = 4096;
232 1.1 mycroft break;
233 1.1 mycroft case FE_D6_TXBSIZ_2x8KB:
234 1.1 mycroft sc->txb_size = 8192;
235 1.1 mycroft break;
236 1.1 mycroft default:
237 1.1 mycroft /* Oops, we can't work with single buffer configuration. */
238 1.1 mycroft #if FE_DEBUG >= 2
239 1.1 mycroft log(LOG_WARNING, "%s: strange TXBSIZ config; fixing\n",
240 1.1 mycroft sc->sc_dev.dv_xname);
241 1.1 mycroft #endif
242 1.1 mycroft sc->proto_dlcr6 &= ~FE_D6_TXBSIZ;
243 1.1 mycroft sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
244 1.1 mycroft sc->txb_size = 2048;
245 1.1 mycroft break;
246 1.1 mycroft }
247 1.1 mycroft
248 1.21 enami /* Initialize media goo. */
249 1.21 enami ifmedia_init(&sc->sc_media, 0, mb86960_mediachange,
250 1.21 enami mb86960_mediastatus);
251 1.21 enami if (media != NULL) {
252 1.21 enami for (i = 0; i < nmedia; i++)
253 1.21 enami ifmedia_add(&sc->sc_media, media[i], 0, NULL);
254 1.21 enami ifmedia_set(&sc->sc_media, defmedia);
255 1.21 enami } else {
256 1.21 enami ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
257 1.21 enami ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
258 1.21 enami }
259 1.21 enami
260 1.1 mycroft /* Attach the interface. */
261 1.1 mycroft if_attach(ifp);
262 1.17 is ether_ifattach(ifp, sc->sc_enaddr);
263 1.1 mycroft
264 1.21 enami #if NBPFILTER > 0
265 1.21 enami /* If BPF is in the kernel, call the attach for it. */
266 1.21 enami bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
267 1.21 enami #endif
268 1.21 enami #if NRND > 0
269 1.21 enami rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
270 1.21 enami RND_TYPE_NET);
271 1.21 enami #endif
272 1.1 mycroft /* Print additional info when attached. */
273 1.21 enami printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
274 1.21 enami ether_sprintf(sc->sc_enaddr));
275 1.21 enami
276 1.1 mycroft #if FE_DEBUG >= 3
277 1.1 mycroft {
278 1.1 mycroft int buf, txb, bbw, sbw, ram;
279 1.1 mycroft
280 1.1 mycroft buf = txb = bbw = sbw = ram = -1;
281 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_BUFSIZ) {
282 1.1 mycroft case FE_D6_BUFSIZ_8KB:
283 1.1 mycroft buf = 8;
284 1.1 mycroft break;
285 1.1 mycroft case FE_D6_BUFSIZ_16KB:
286 1.1 mycroft buf = 16;
287 1.1 mycroft break;
288 1.1 mycroft case FE_D6_BUFSIZ_32KB:
289 1.1 mycroft buf = 32;
290 1.1 mycroft break;
291 1.1 mycroft case FE_D6_BUFSIZ_64KB:
292 1.1 mycroft buf = 64;
293 1.1 mycroft break;
294 1.1 mycroft }
295 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) {
296 1.1 mycroft case FE_D6_TXBSIZ_2x2KB:
297 1.1 mycroft txb = 2;
298 1.1 mycroft break;
299 1.1 mycroft case FE_D6_TXBSIZ_2x4KB:
300 1.1 mycroft txb = 4;
301 1.1 mycroft break;
302 1.1 mycroft case FE_D6_TXBSIZ_2x8KB:
303 1.1 mycroft txb = 8;
304 1.1 mycroft break;
305 1.1 mycroft }
306 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_BBW) {
307 1.1 mycroft case FE_D6_BBW_BYTE:
308 1.1 mycroft bbw = 8;
309 1.1 mycroft break;
310 1.1 mycroft case FE_D6_BBW_WORD:
311 1.1 mycroft bbw = 16;
312 1.1 mycroft break;
313 1.1 mycroft }
314 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_SBW) {
315 1.1 mycroft case FE_D6_SBW_BYTE:
316 1.1 mycroft sbw = 8;
317 1.1 mycroft break;
318 1.1 mycroft case FE_D6_SBW_WORD:
319 1.1 mycroft sbw = 16;
320 1.1 mycroft break;
321 1.1 mycroft }
322 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_SRAM) {
323 1.1 mycroft case FE_D6_SRAM_100ns:
324 1.1 mycroft ram = 100;
325 1.1 mycroft break;
326 1.1 mycroft case FE_D6_SRAM_150ns:
327 1.1 mycroft ram = 150;
328 1.1 mycroft break;
329 1.1 mycroft }
330 1.15 christos printf("%s: SRAM %dKB %dbit %dns, TXB %dKBx2, %dbit I/O\n",
331 1.1 mycroft sc->sc_dev.dv_xname, buf, bbw, ram, txb, sbw);
332 1.1 mycroft }
333 1.1 mycroft #endif
334 1.21 enami }
335 1.21 enami
336 1.21 enami /*
337 1.21 enami * Media change callback.
338 1.21 enami */
339 1.21 enami int
340 1.21 enami mb86960_mediachange(ifp)
341 1.21 enami struct ifnet *ifp;
342 1.21 enami {
343 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
344 1.1 mycroft
345 1.21 enami if (sc->sc_mediachange)
346 1.21 enami return ((*sc->sc_mediachange)(sc));
347 1.21 enami return (EINVAL);
348 1.21 enami }
349 1.1 mycroft
350 1.21 enami /*
351 1.21 enami * Media status callback.
352 1.21 enami */
353 1.21 enami void
354 1.21 enami mb86960_mediastatus(ifp, ifmr)
355 1.21 enami struct ifnet *ifp;
356 1.21 enami struct ifmediareq *ifmr;
357 1.21 enami {
358 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
359 1.18 explorer
360 1.21 enami if (sc->sc_enabled == 0) {
361 1.21 enami ifmr->ifm_active = IFM_ETHER | IFM_NONE;
362 1.21 enami ifmr->ifm_status = 0;
363 1.21 enami return;
364 1.21 enami }
365 1.21 enami
366 1.21 enami if (sc->sc_mediastatus)
367 1.21 enami (*sc->sc_mediastatus)(sc, ifmr);
368 1.1 mycroft }
369 1.1 mycroft
370 1.1 mycroft /*
371 1.1 mycroft * Reset interface.
372 1.1 mycroft */
373 1.1 mycroft void
374 1.21 enami mb86960_reset(sc)
375 1.21 enami struct mb86960_softc *sc;
376 1.1 mycroft {
377 1.1 mycroft int s;
378 1.1 mycroft
379 1.8 mycroft s = splnet();
380 1.21 enami mb86960_stop(sc);
381 1.21 enami mb86960_init(sc);
382 1.1 mycroft splx(s);
383 1.1 mycroft }
384 1.1 mycroft
385 1.1 mycroft /*
386 1.1 mycroft * Stop everything on the interface.
387 1.1 mycroft *
388 1.1 mycroft * All buffered packets, both transmitting and receiving,
389 1.1 mycroft * if any, will be lost by stopping the interface.
390 1.1 mycroft */
391 1.1 mycroft void
392 1.21 enami mb86960_stop(sc)
393 1.21 enami struct mb86960_softc *sc;
394 1.1 mycroft {
395 1.21 enami bus_space_tag_t bst = sc->sc_bst;
396 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
397 1.1 mycroft
398 1.1 mycroft #if FE_DEBUG >= 3
399 1.21 enami log(LOG_INFO, "%s: top of mb86960_stop()\n", sc->sc_dev.dv_xname);
400 1.21 enami mb86960_dump(LOG_INFO, sc);
401 1.1 mycroft #endif
402 1.1 mycroft
403 1.1 mycroft /* Disable interrupts. */
404 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0x00);
405 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0x00);
406 1.1 mycroft
407 1.1 mycroft /* Stop interface hardware. */
408 1.1 mycroft delay(200);
409 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
410 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
411 1.1 mycroft delay(200);
412 1.1 mycroft
413 1.1 mycroft /* Clear all interrupt status. */
414 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF);
415 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF);
416 1.1 mycroft
417 1.1 mycroft /* Put the chip in stand-by mode. */
418 1.1 mycroft delay(200);
419 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
420 1.21 enami sc->proto_dlcr7 | FE_D7_POWER_DOWN);
421 1.1 mycroft delay(200);
422 1.1 mycroft
423 1.1 mycroft /* MAR loading can be delayed. */
424 1.1 mycroft sc->filter_change = 0;
425 1.1 mycroft
426 1.1 mycroft /* Call a hook. */
427 1.21 enami if (sc->stop_card)
428 1.21 enami (*sc->stop_card)(sc);
429 1.1 mycroft
430 1.1 mycroft #if DEBUG >= 3
431 1.21 enami log(LOG_INFO, "%s: end of mb86960_stop()\n", sc->sc_dev.dv_xname);
432 1.21 enami mb86960_dump(LOG_INFO, sc);
433 1.1 mycroft #endif
434 1.1 mycroft }
435 1.1 mycroft
436 1.1 mycroft /*
437 1.1 mycroft * Device timeout/watchdog routine. Entered if the device neglects to
438 1.1 mycroft * generate an interrupt after a transmit has been started on it.
439 1.1 mycroft */
440 1.1 mycroft void
441 1.21 enami mb86960_watchdog(ifp)
442 1.12 thorpej struct ifnet *ifp;
443 1.1 mycroft {
444 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
445 1.1 mycroft
446 1.1 mycroft log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
447 1.1 mycroft #if FE_DEBUG >= 3
448 1.21 enami mb86960_dump(LOG_INFO, sc);
449 1.1 mycroft #endif
450 1.1 mycroft
451 1.1 mycroft /* Record how many packets are lost by this accident. */
452 1.21 enami sc->sc_ec.ec_if.if_oerrors += sc->txb_sched + sc->txb_count;
453 1.1 mycroft
454 1.21 enami mb86960_reset(sc);
455 1.1 mycroft }
456 1.1 mycroft
457 1.1 mycroft /*
458 1.6 mycroft * Drop (skip) a packet from receive buffer in 86960 memory.
459 1.6 mycroft */
460 1.21 enami static __inline__ void
461 1.21 enami mb86960_droppacket(sc)
462 1.21 enami struct mb86960_softc *sc;
463 1.6 mycroft {
464 1.21 enami bus_space_tag_t bst = sc->sc_bst;
465 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
466 1.6 mycroft
467 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR14, FE_B14_FILTER | FE_B14_SKIP);
468 1.6 mycroft }
469 1.6 mycroft
470 1.6 mycroft /*
471 1.1 mycroft * Initialize device.
472 1.1 mycroft */
473 1.1 mycroft void
474 1.21 enami mb86960_init(sc)
475 1.21 enami struct mb86960_softc *sc;
476 1.1 mycroft {
477 1.21 enami bus_space_tag_t bst = sc->sc_bst;
478 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
479 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
480 1.5 mycroft int i;
481 1.1 mycroft
482 1.1 mycroft #if FE_DEBUG >= 3
483 1.21 enami log(LOG_INFO, "%s: top of mb86960_init()\n", sc->sc_dev.dv_xname);
484 1.21 enami mb86960_dump(LOG_INFO, sc);
485 1.1 mycroft #endif
486 1.1 mycroft
487 1.1 mycroft /* Reset transmitter flags. */
488 1.1 mycroft ifp->if_flags &= ~IFF_OACTIVE;
489 1.1 mycroft ifp->if_timer = 0;
490 1.1 mycroft
491 1.1 mycroft sc->txb_free = sc->txb_size;
492 1.1 mycroft sc->txb_count = 0;
493 1.1 mycroft sc->txb_sched = 0;
494 1.1 mycroft
495 1.21 enami /* Do any card-specific initialization, if applicable. */
496 1.21 enami if (sc->init_card)
497 1.21 enami (*sc->init_card)(sc);
498 1.1 mycroft
499 1.1 mycroft #if FE_DEBUG >= 3
500 1.1 mycroft log(LOG_INFO, "%s: after init hook\n", sc->sc_dev.dv_xname);
501 1.21 enami mb86960_dump(LOG_INFO, sc);
502 1.1 mycroft #endif
503 1.1 mycroft
504 1.1 mycroft /*
505 1.1 mycroft * Make sure to disable the chip, also.
506 1.1 mycroft * This may also help re-programming the chip after
507 1.1 mycroft * hot insertion of PCMCIAs.
508 1.1 mycroft */
509 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
510 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
511 1.21 enami delay(200);
512 1.1 mycroft
513 1.1 mycroft /* Power up the chip and select register bank for DLCRs. */
514 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
515 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_DLCR | FE_D7_POWER_UP);
516 1.1 mycroft delay(200);
517 1.1 mycroft
518 1.1 mycroft /* Feed the station address. */
519 1.21 enami bus_space_write_region_1(bst, bsh, FE_DLCR8,
520 1.21 enami sc->sc_enaddr, ETHER_ADDR_LEN);
521 1.1 mycroft
522 1.1 mycroft /* Select the BMPR bank for runtime register access. */
523 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
524 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP);
525 1.1 mycroft
526 1.1 mycroft /* Initialize registers. */
527 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF); /* Clear all bits. */
528 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF); /* ditto. */
529 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0x00);
530 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0x00);
531 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR4, sc->proto_dlcr4);
532 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR5, sc->proto_dlcr5);
533 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR10, 0x00);
534 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR11, FE_B11_CTRL_SKIP);
535 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR12, 0x00);
536 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR13, sc->proto_bmpr13);
537 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR14, FE_B14_FILTER);
538 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR15, 0x00);
539 1.1 mycroft
540 1.1 mycroft #if FE_DEBUG >= 3
541 1.1 mycroft log(LOG_INFO, "%s: just before enabling DLC\n", sc->sc_dev.dv_xname);
542 1.21 enami mb86960_dump(LOG_INFO, sc);
543 1.1 mycroft #endif
544 1.1 mycroft
545 1.1 mycroft /* Enable interrupts. */
546 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, FE_TMASK);
547 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, FE_RMASK);
548 1.1 mycroft
549 1.1 mycroft /* Enable transmitter and receiver. */
550 1.1 mycroft delay(200);
551 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
552 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_ENABLE);
553 1.1 mycroft delay(200);
554 1.1 mycroft
555 1.1 mycroft #if FE_DEBUG >= 3
556 1.1 mycroft log(LOG_INFO, "%s: just after enabling DLC\n", sc->sc_dev.dv_xname);
557 1.21 enami mb86960_dump(LOG_INFO, sc);
558 1.1 mycroft #endif
559 1.1 mycroft
560 1.1 mycroft /*
561 1.1 mycroft * Make sure to empty the receive buffer.
562 1.1 mycroft *
563 1.1 mycroft * This may be redundant, but *if* the receive buffer were full
564 1.1 mycroft * at this point, the driver would hang. I have experienced
565 1.1 mycroft * some strange hangups just after UP. I hope the following
566 1.1 mycroft * code solve the problem.
567 1.1 mycroft *
568 1.1 mycroft * I have changed the order of hardware initialization.
569 1.1 mycroft * I think the receive buffer cannot have any packets at this
570 1.1 mycroft * point in this version. The following code *must* be
571 1.1 mycroft * redundant now. FIXME.
572 1.1 mycroft */
573 1.1 mycroft for (i = 0; i < FE_MAX_RECV_COUNT; i++) {
574 1.21 enami if (bus_space_read_1(bst, bsh, FE_DLCR5) & FE_D5_BUFEMP)
575 1.1 mycroft break;
576 1.21 enami mb86960_droppacket(sc);
577 1.1 mycroft }
578 1.1 mycroft #if FE_DEBUG >= 1
579 1.21 enami if (i >= FE_MAX_RECV_COUNT)
580 1.1 mycroft log(LOG_ERR, "%s: cannot empty receive buffer\n",
581 1.1 mycroft sc->sc_dev.dv_xname);
582 1.1 mycroft #endif
583 1.1 mycroft #if FE_DEBUG >= 3
584 1.21 enami if (i < FE_MAX_RECV_COUNT)
585 1.1 mycroft log(LOG_INFO, "%s: receive buffer emptied (%d)\n",
586 1.1 mycroft sc->sc_dev.dv_xname, i);
587 1.1 mycroft #endif
588 1.1 mycroft
589 1.1 mycroft #if FE_DEBUG >= 3
590 1.1 mycroft log(LOG_INFO, "%s: after ERB loop\n", sc->sc_dev.dv_xname);
591 1.21 enami mb86960_dump(LOG_INFO, sc);
592 1.1 mycroft #endif
593 1.1 mycroft
594 1.1 mycroft /* Do we need this here? */
595 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF); /* Clear all bits. */
596 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF); /* ditto. */
597 1.1 mycroft
598 1.1 mycroft #if FE_DEBUG >= 3
599 1.1 mycroft log(LOG_INFO, "%s: after FIXME\n", sc->sc_dev.dv_xname);
600 1.21 enami mb86960_dump(LOG_INFO, sc);
601 1.1 mycroft #endif
602 1.1 mycroft
603 1.1 mycroft /* Set 'running' flag. */
604 1.1 mycroft ifp->if_flags |= IFF_RUNNING;
605 1.1 mycroft
606 1.1 mycroft /*
607 1.1 mycroft * At this point, the interface is runnung properly,
608 1.1 mycroft * except that it receives *no* packets. we then call
609 1.21 enami * mb86960_setmode() to tell the chip what packets to be
610 1.1 mycroft * received, based on the if_flags and multicast group
611 1.1 mycroft * list. It completes the initialization process.
612 1.1 mycroft */
613 1.21 enami mb86960_setmode(sc);
614 1.1 mycroft
615 1.1 mycroft #if FE_DEBUG >= 3
616 1.1 mycroft log(LOG_INFO, "%s: after setmode\n", sc->sc_dev.dv_xname);
617 1.21 enami mb86960_dump(LOG_INFO, sc);
618 1.1 mycroft #endif
619 1.1 mycroft
620 1.1 mycroft /* ...and attempt to start output. */
621 1.21 enami mb86960_start(ifp);
622 1.1 mycroft
623 1.1 mycroft #if FE_DEBUG >= 3
624 1.21 enami log(LOG_INFO, "%s: end of mb86960_init()\n", sc->sc_dev.dv_xname);
625 1.21 enami mb86960_dump(LOG_INFO, sc);
626 1.1 mycroft #endif
627 1.1 mycroft }
628 1.1 mycroft
629 1.1 mycroft /*
630 1.1 mycroft * This routine actually starts the transmission on the interface
631 1.1 mycroft */
632 1.21 enami static __inline__ void
633 1.21 enami mb86960_xmit(sc)
634 1.21 enami struct mb86960_softc *sc;
635 1.1 mycroft {
636 1.21 enami bus_space_tag_t bst = sc->sc_bst;
637 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
638 1.1 mycroft
639 1.1 mycroft /*
640 1.1 mycroft * Set a timer just in case we never hear from the board again.
641 1.1 mycroft * We use longer timeout for multiple packet transmission.
642 1.1 mycroft * I'm not sure this timer value is appropriate. FIXME.
643 1.1 mycroft */
644 1.21 enami sc->sc_ec.ec_if.if_timer = 1 + sc->txb_count;
645 1.1 mycroft
646 1.1 mycroft /* Update txb variables. */
647 1.1 mycroft sc->txb_sched = sc->txb_count;
648 1.1 mycroft sc->txb_count = 0;
649 1.1 mycroft sc->txb_free = sc->txb_size;
650 1.1 mycroft
651 1.1 mycroft #if FE_DELAYED_PADDING
652 1.1 mycroft /* Omit the postponed padding process. */
653 1.1 mycroft sc->txb_padding = 0;
654 1.1 mycroft #endif
655 1.1 mycroft
656 1.1 mycroft /* Start transmitter, passing packets in TX buffer. */
657 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR10, sc->txb_sched | FE_B10_START);
658 1.1 mycroft }
659 1.1 mycroft
660 1.1 mycroft /*
661 1.1 mycroft * Start output on interface.
662 1.1 mycroft * We make two assumptions here:
663 1.8 mycroft * 1) that the current priority is set to splnet _before_ this code
664 1.1 mycroft * is called *and* is returned to the appropriate priority after
665 1.1 mycroft * return
666 1.1 mycroft * 2) that the IFF_OACTIVE flag is checked before this code is called
667 1.1 mycroft * (i.e. that the output part of the interface is idle)
668 1.1 mycroft */
669 1.1 mycroft void
670 1.21 enami mb86960_start(ifp)
671 1.1 mycroft struct ifnet *ifp;
672 1.1 mycroft {
673 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
674 1.1 mycroft struct mbuf *m;
675 1.1 mycroft
676 1.1 mycroft #if FE_DEBUG >= 1
677 1.1 mycroft /* Just a sanity check. */
678 1.1 mycroft if ((sc->txb_count == 0) != (sc->txb_free == sc->txb_size)) {
679 1.1 mycroft /*
680 1.1 mycroft * Txb_count and txb_free co-works to manage the
681 1.1 mycroft * transmission buffer. Txb_count keeps track of the
682 1.1 mycroft * used potion of the buffer, while txb_free does unused
683 1.1 mycroft * potion. So, as long as the driver runs properly,
684 1.1 mycroft * txb_count is zero if and only if txb_free is same
685 1.1 mycroft * as txb_size (which represents whole buffer.)
686 1.1 mycroft */
687 1.1 mycroft log(LOG_ERR, "%s: inconsistent txb variables (%d, %d)\n",
688 1.1 mycroft sc->sc_dev.dv_xname, sc->txb_count, sc->txb_free);
689 1.1 mycroft /*
690 1.1 mycroft * So, what should I do, then?
691 1.1 mycroft *
692 1.1 mycroft * We now know txb_count and txb_free contradicts. We
693 1.1 mycroft * cannot, however, tell which is wrong. More
694 1.1 mycroft * over, we cannot peek 86960 transmission buffer or
695 1.1 mycroft * reset the transmission buffer. (In fact, we can
696 1.1 mycroft * reset the entire interface. I don't want to do it.)
697 1.1 mycroft *
698 1.1 mycroft * If txb_count is incorrect, leaving it as is will cause
699 1.1 mycroft * sending of gabages after next interrupt. We have to
700 1.1 mycroft * avoid it. Hence, we reset the txb_count here. If
701 1.1 mycroft * txb_free was incorrect, resetting txb_count just loose
702 1.1 mycroft * some packets. We can live with it.
703 1.1 mycroft */
704 1.1 mycroft sc->txb_count = 0;
705 1.1 mycroft }
706 1.1 mycroft #endif
707 1.1 mycroft
708 1.1 mycroft #if FE_DEBUG >= 1
709 1.1 mycroft /*
710 1.1 mycroft * First, see if there are buffered packets and an idle
711 1.1 mycroft * transmitter - should never happen at this point.
712 1.1 mycroft */
713 1.1 mycroft if ((sc->txb_count > 0) && (sc->txb_sched == 0)) {
714 1.1 mycroft log(LOG_ERR, "%s: transmitter idle with %d buffered packets\n",
715 1.1 mycroft sc->sc_dev.dv_xname, sc->txb_count);
716 1.21 enami mb86960_xmit(sc);
717 1.1 mycroft }
718 1.1 mycroft #endif
719 1.1 mycroft
720 1.1 mycroft /*
721 1.1 mycroft * Stop accepting more transmission packets temporarily, when
722 1.1 mycroft * a filter change request is delayed. Updating the MARs on
723 1.1 mycroft * 86960 flushes the transmisstion buffer, so it is delayed
724 1.1 mycroft * until all buffered transmission packets have been sent
725 1.1 mycroft * out.
726 1.1 mycroft */
727 1.1 mycroft if (sc->filter_change) {
728 1.1 mycroft /*
729 1.1 mycroft * Filter change requst is delayed only when the DLC is
730 1.1 mycroft * working. DLC soon raise an interrupt after finishing
731 1.1 mycroft * the work.
732 1.1 mycroft */
733 1.1 mycroft goto indicate_active;
734 1.1 mycroft }
735 1.1 mycroft
736 1.1 mycroft for (;;) {
737 1.1 mycroft /*
738 1.1 mycroft * See if there is room to put another packet in the buffer.
739 1.1 mycroft * We *could* do better job by peeking the send queue to
740 1.1 mycroft * know the length of the next packet. Current version just
741 1.1 mycroft * tests against the worst case (i.e., longest packet). FIXME.
742 1.1 mycroft *
743 1.1 mycroft * When adding the packet-peek feature, don't forget adding a
744 1.1 mycroft * test on txb_count against QUEUEING_MAX.
745 1.1 mycroft * There is a little chance the packet count exceeds
746 1.1 mycroft * the limit. Assume transmission buffer is 8KB (2x8KB
747 1.1 mycroft * configuration) and an application sends a bunch of small
748 1.1 mycroft * (i.e., minimum packet sized) packets rapidly. An 8KB
749 1.1 mycroft * buffer can hold 130 blocks of 62 bytes long...
750 1.1 mycroft */
751 1.1 mycroft if (sc->txb_free < ETHER_MAX_LEN + FE_DATA_LEN_LEN) {
752 1.1 mycroft /* No room. */
753 1.1 mycroft goto indicate_active;
754 1.1 mycroft }
755 1.1 mycroft
756 1.1 mycroft #if FE_SINGLE_TRANSMISSION
757 1.1 mycroft if (sc->txb_count > 0) {
758 1.1 mycroft /* Just one packet per a transmission buffer. */
759 1.1 mycroft goto indicate_active;
760 1.1 mycroft }
761 1.1 mycroft #endif
762 1.1 mycroft
763 1.1 mycroft /*
764 1.1 mycroft * Get the next mbuf chain for a packet to send.
765 1.1 mycroft */
766 1.1 mycroft IF_DEQUEUE(&ifp->if_snd, m);
767 1.1 mycroft if (m == 0) {
768 1.1 mycroft /* No more packets to send. */
769 1.1 mycroft goto indicate_inactive;
770 1.1 mycroft }
771 1.1 mycroft
772 1.6 mycroft #if NBPFILTER > 0
773 1.6 mycroft /* Tap off here if there is a BPF listener. */
774 1.6 mycroft if (ifp->if_bpf)
775 1.6 mycroft bpf_mtap(ifp->if_bpf, m);
776 1.6 mycroft #endif
777 1.6 mycroft
778 1.1 mycroft /*
779 1.1 mycroft * Copy the mbuf chain into the transmission buffer.
780 1.1 mycroft * txb_* variables are updated as necessary.
781 1.1 mycroft */
782 1.21 enami mb86960_write_mbufs(sc, m);
783 1.1 mycroft
784 1.6 mycroft m_freem(m);
785 1.6 mycroft
786 1.1 mycroft /* Start transmitter if it's idle. */
787 1.1 mycroft if (sc->txb_sched == 0)
788 1.21 enami mb86960_xmit(sc);
789 1.1 mycroft }
790 1.1 mycroft
791 1.1 mycroft indicate_inactive:
792 1.1 mycroft /*
793 1.1 mycroft * We are using the !OACTIVE flag to indicate to
794 1.1 mycroft * the outside world that we can accept an
795 1.1 mycroft * additional packet rather than that the
796 1.1 mycroft * transmitter is _actually_ active. Indeed, the
797 1.1 mycroft * transmitter may be active, but if we haven't
798 1.1 mycroft * filled all the buffers with data then we still
799 1.1 mycroft * want to accept more.
800 1.1 mycroft */
801 1.1 mycroft ifp->if_flags &= ~IFF_OACTIVE;
802 1.1 mycroft return;
803 1.1 mycroft
804 1.1 mycroft indicate_active:
805 1.1 mycroft /*
806 1.1 mycroft * The transmitter is active, and there are no room for
807 1.1 mycroft * more outgoing packets in the transmission buffer.
808 1.1 mycroft */
809 1.1 mycroft ifp->if_flags |= IFF_OACTIVE;
810 1.1 mycroft return;
811 1.1 mycroft }
812 1.1 mycroft
813 1.1 mycroft /*
814 1.1 mycroft * Transmission interrupt handler
815 1.1 mycroft * The control flow of this function looks silly. FIXME.
816 1.1 mycroft */
817 1.1 mycroft void
818 1.21 enami mb86960_tint(sc, tstat)
819 1.21 enami struct mb86960_softc *sc;
820 1.1 mycroft u_char tstat;
821 1.1 mycroft {
822 1.21 enami bus_space_tag_t bst = sc->sc_bst;
823 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
824 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
825 1.1 mycroft int left;
826 1.1 mycroft int col;
827 1.1 mycroft
828 1.1 mycroft /*
829 1.1 mycroft * Handle "excessive collision" interrupt.
830 1.1 mycroft */
831 1.1 mycroft if (tstat & FE_D0_COLL16) {
832 1.1 mycroft /*
833 1.1 mycroft * Find how many packets (including this collided one)
834 1.1 mycroft * are left unsent in transmission buffer.
835 1.1 mycroft */
836 1.21 enami left = bus_space_read_1(bst, bsh, FE_BMPR10);
837 1.1 mycroft
838 1.1 mycroft #if FE_DEBUG >= 2
839 1.1 mycroft log(LOG_WARNING, "%s: excessive collision (%d/%d)\n",
840 1.1 mycroft sc->sc_dev.dv_xname, left, sc->txb_sched);
841 1.1 mycroft #endif
842 1.1 mycroft #if FE_DEBUG >= 3
843 1.21 enami mb86960_dump(LOG_INFO, sc);
844 1.1 mycroft #endif
845 1.1 mycroft
846 1.1 mycroft /*
847 1.1 mycroft * Update statistics.
848 1.1 mycroft */
849 1.1 mycroft ifp->if_collisions += 16;
850 1.1 mycroft ifp->if_oerrors++;
851 1.1 mycroft ifp->if_opackets += sc->txb_sched - left;
852 1.1 mycroft
853 1.1 mycroft /*
854 1.1 mycroft * Collision statistics has been updated.
855 1.1 mycroft * Clear the collision flag on 86960 now to avoid confusion.
856 1.1 mycroft */
857 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, FE_D0_COLLID);
858 1.1 mycroft
859 1.1 mycroft /*
860 1.1 mycroft * Restart transmitter, skipping the
861 1.1 mycroft * collided packet.
862 1.1 mycroft *
863 1.1 mycroft * We *must* skip the packet to keep network running
864 1.1 mycroft * properly. Excessive collision error is an
865 1.1 mycroft * indication of the network overload. If we
866 1.1 mycroft * tried sending the same packet after excessive
867 1.1 mycroft * collision, the network would be filled with
868 1.1 mycroft * out-of-time packets. Packets belonging
869 1.1 mycroft * to reliable transport (such as TCP) are resent
870 1.1 mycroft * by some upper layer.
871 1.1 mycroft */
872 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR11,
873 1.1 mycroft FE_B11_CTRL_SKIP | FE_B11_MODE1);
874 1.1 mycroft sc->txb_sched = left - 1;
875 1.1 mycroft }
876 1.1 mycroft
877 1.1 mycroft /*
878 1.1 mycroft * Handle "transmission complete" interrupt.
879 1.1 mycroft */
880 1.1 mycroft if (tstat & FE_D0_TXDONE) {
881 1.1 mycroft /*
882 1.1 mycroft * Add in total number of collisions on last
883 1.1 mycroft * transmission. We also clear "collision occurred" flag
884 1.1 mycroft * here.
885 1.1 mycroft *
886 1.1 mycroft * 86960 has a design flow on collision count on multiple
887 1.1 mycroft * packet transmission. When we send two or more packets
888 1.1 mycroft * with one start command (that's what we do when the
889 1.1 mycroft * transmission queue is clauded), 86960 informs us number
890 1.1 mycroft * of collisions occured on the last packet on the
891 1.1 mycroft * transmission only. Number of collisions on previous
892 1.1 mycroft * packets are lost. I have told that the fact is clearly
893 1.1 mycroft * stated in the Fujitsu document.
894 1.1 mycroft *
895 1.1 mycroft * I considered not to mind it seriously. Collision
896 1.1 mycroft * count is not so important, anyway. Any comments? FIXME.
897 1.1 mycroft */
898 1.1 mycroft
899 1.21 enami if (bus_space_read_1(bst, bsh, FE_DLCR0) & FE_D0_COLLID) {
900 1.1 mycroft /* Clear collision flag. */
901 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, FE_D0_COLLID);
902 1.1 mycroft
903 1.1 mycroft /* Extract collision count from 86960. */
904 1.21 enami col = bus_space_read_1(bst, bsh, FE_DLCR4) & FE_D4_COL;
905 1.1 mycroft if (col == 0) {
906 1.1 mycroft /*
907 1.1 mycroft * Status register indicates collisions,
908 1.1 mycroft * while the collision count is zero.
909 1.1 mycroft * This can happen after multiple packet
910 1.1 mycroft * transmission, indicating that one or more
911 1.1 mycroft * previous packet(s) had been collided.
912 1.1 mycroft *
913 1.1 mycroft * Since the accurate number of collisions
914 1.1 mycroft * has been lost, we just guess it as 1;
915 1.1 mycroft * Am I too optimistic? FIXME.
916 1.1 mycroft */
917 1.1 mycroft col = 1;
918 1.1 mycroft } else
919 1.1 mycroft col >>= FE_D4_COL_SHIFT;
920 1.1 mycroft ifp->if_collisions += col;
921 1.1 mycroft #if FE_DEBUG >= 4
922 1.1 mycroft log(LOG_WARNING, "%s: %d collision%s (%d)\n",
923 1.1 mycroft sc->sc_dev.dv_xname, col, col == 1 ? "" : "s",
924 1.1 mycroft sc->txb_sched);
925 1.1 mycroft #endif
926 1.1 mycroft }
927 1.1 mycroft
928 1.1 mycroft /*
929 1.1 mycroft * Update total number of successfully
930 1.1 mycroft * transmitted packets.
931 1.1 mycroft */
932 1.1 mycroft ifp->if_opackets += sc->txb_sched;
933 1.1 mycroft sc->txb_sched = 0;
934 1.10 mycroft }
935 1.1 mycroft
936 1.10 mycroft if (sc->txb_sched == 0) {
937 1.1 mycroft /*
938 1.1 mycroft * The transmitter is no more active.
939 1.1 mycroft * Reset output active flag and watchdog timer.
940 1.1 mycroft */
941 1.1 mycroft ifp->if_flags &= ~IFF_OACTIVE;
942 1.1 mycroft ifp->if_timer = 0;
943 1.1 mycroft
944 1.1 mycroft /*
945 1.1 mycroft * If more data is ready to transmit in the buffer, start
946 1.1 mycroft * transmitting them. Otherwise keep transmitter idle,
947 1.1 mycroft * even if more data is queued. This gives receive
948 1.1 mycroft * process a slight priority.
949 1.1 mycroft */
950 1.1 mycroft if (sc->txb_count > 0)
951 1.21 enami mb86960_xmit(sc);
952 1.1 mycroft }
953 1.1 mycroft }
954 1.1 mycroft
955 1.1 mycroft /*
956 1.1 mycroft * Ethernet interface receiver interrupt.
957 1.1 mycroft */
958 1.1 mycroft void
959 1.21 enami mb86960_rint(sc, rstat)
960 1.21 enami struct mb86960_softc *sc;
961 1.1 mycroft u_char rstat;
962 1.1 mycroft {
963 1.21 enami bus_space_tag_t bst = sc->sc_bst;
964 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
965 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
966 1.1 mycroft int len;
967 1.1 mycroft u_char status;
968 1.1 mycroft int i;
969 1.1 mycroft
970 1.1 mycroft /*
971 1.1 mycroft * Update statistics if this interrupt is caused by an error.
972 1.1 mycroft */
973 1.21 enami if (rstat & (FE_D1_OVRFLO | FE_D1_CRCERR | FE_D1_ALGERR |
974 1.21 enami FE_D1_SRTPKT)) {
975 1.1 mycroft #if FE_DEBUG >= 3
976 1.1 mycroft log(LOG_WARNING, "%s: receive error: %b\n",
977 1.1 mycroft sc->sc_dev.dv_xname, rstat, FE_D1_ERRBITS);
978 1.1 mycroft #endif
979 1.1 mycroft ifp->if_ierrors++;
980 1.1 mycroft }
981 1.1 mycroft
982 1.1 mycroft /*
983 1.1 mycroft * MB86960 has a flag indicating "receive queue empty."
984 1.1 mycroft * We just loop cheking the flag to pull out all received
985 1.1 mycroft * packets.
986 1.1 mycroft *
987 1.1 mycroft * We limit the number of iterrations to avoid infinite loop.
988 1.1 mycroft * It can be caused by a very slow CPU (some broken
989 1.1 mycroft * peripheral may insert incredible number of wait cycles)
990 1.1 mycroft * or, worse, by a broken MB86960 chip.
991 1.1 mycroft */
992 1.1 mycroft for (i = 0; i < FE_MAX_RECV_COUNT; i++) {
993 1.1 mycroft /* Stop the iterration if 86960 indicates no packets. */
994 1.21 enami if (bus_space_read_1(bst, bsh, FE_DLCR5) & FE_D5_BUFEMP)
995 1.1 mycroft break;
996 1.1 mycroft
997 1.1 mycroft /*
998 1.1 mycroft * Extract A receive status byte.
999 1.1 mycroft * As our 86960 is in 16 bit bus access mode, we have to
1000 1.1 mycroft * use inw() to get the status byte. The significant
1001 1.1 mycroft * value is returned in lower 8 bits.
1002 1.1 mycroft */
1003 1.21 enami status = (u_char)bus_space_read_2(bst, bsh, FE_BMPR8);
1004 1.1 mycroft #if FE_DEBUG >= 4
1005 1.1 mycroft log(LOG_INFO, "%s: receive status = %02x\n",
1006 1.1 mycroft sc->sc_dev.dv_xname, status);
1007 1.1 mycroft #endif
1008 1.1 mycroft
1009 1.1 mycroft /*
1010 1.1 mycroft * If there was an error, update statistics and drop
1011 1.1 mycroft * the packet, unless the interface is in promiscuous
1012 1.1 mycroft * mode.
1013 1.1 mycroft */
1014 1.1 mycroft if ((status & 0xF0) != 0x20) { /* XXXX ? */
1015 1.1 mycroft if ((ifp->if_flags & IFF_PROMISC) == 0) {
1016 1.1 mycroft ifp->if_ierrors++;
1017 1.21 enami mb86960_droppacket(sc);
1018 1.1 mycroft continue;
1019 1.1 mycroft }
1020 1.1 mycroft }
1021 1.1 mycroft
1022 1.1 mycroft /*
1023 1.1 mycroft * Extract the packet length.
1024 1.1 mycroft * It is a sum of a header (14 bytes) and a payload.
1025 1.1 mycroft * CRC has been stripped off by the 86960.
1026 1.1 mycroft */
1027 1.21 enami len = bus_space_read_2(bst, bsh, FE_BMPR8);
1028 1.1 mycroft
1029 1.1 mycroft /*
1030 1.1 mycroft * MB86965 checks the packet length and drop big packet
1031 1.1 mycroft * before passing it to us. There are no chance we can
1032 1.1 mycroft * get [crufty] packets. Hence, if the length exceeds
1033 1.1 mycroft * the specified limit, it means some serious failure,
1034 1.1 mycroft * such as out-of-sync on receive buffer management.
1035 1.1 mycroft *
1036 1.1 mycroft * Is this statement true? FIXME.
1037 1.1 mycroft */
1038 1.1 mycroft if (len > ETHER_MAX_LEN || len < ETHER_HDR_SIZE) {
1039 1.1 mycroft #if FE_DEBUG >= 2
1040 1.1 mycroft log(LOG_WARNING,
1041 1.1 mycroft "%s: received a %s packet? (%u bytes)\n",
1042 1.1 mycroft sc->sc_dev.dv_xname,
1043 1.1 mycroft len < ETHER_HDR_SIZE ? "partial" : "big", len);
1044 1.1 mycroft #endif
1045 1.1 mycroft ifp->if_ierrors++;
1046 1.21 enami mb86960_droppacket(sc);
1047 1.1 mycroft continue;
1048 1.1 mycroft }
1049 1.1 mycroft
1050 1.1 mycroft /*
1051 1.1 mycroft * Check for a short (RUNT) packet. We *do* check
1052 1.1 mycroft * but do nothing other than print a message.
1053 1.1 mycroft * Short packets are illegal, but does nothing bad
1054 1.1 mycroft * if it carries data for upper layer.
1055 1.1 mycroft */
1056 1.1 mycroft #if FE_DEBUG >= 2
1057 1.1 mycroft if (len < ETHER_MIN_LEN) {
1058 1.1 mycroft log(LOG_WARNING,
1059 1.21 enami "%s: received a short packet? (%u bytes)\n",
1060 1.21 enami sc->sc_dev.dv_xname, len);
1061 1.1 mycroft }
1062 1.1 mycroft #endif
1063 1.1 mycroft
1064 1.1 mycroft /*
1065 1.1 mycroft * Go get a packet.
1066 1.1 mycroft */
1067 1.21 enami if (!mb86960_get_packet(sc, len)) {
1068 1.1 mycroft /* Skip a packet, updating statistics. */
1069 1.1 mycroft #if FE_DEBUG >= 2
1070 1.1 mycroft log(LOG_WARNING,
1071 1.1 mycroft "%s: out of mbufs; dropping packet (%u bytes)\n",
1072 1.1 mycroft sc->sc_dev.dv_xname, len);
1073 1.1 mycroft #endif
1074 1.1 mycroft ifp->if_ierrors++;
1075 1.21 enami mb86960_droppacket(sc);
1076 1.1 mycroft
1077 1.1 mycroft /*
1078 1.1 mycroft * We stop receiving packets, even if there are
1079 1.1 mycroft * more in the buffer. We hope we can get more
1080 1.1 mycroft * mbufs next time.
1081 1.1 mycroft */
1082 1.1 mycroft return;
1083 1.1 mycroft }
1084 1.1 mycroft
1085 1.1 mycroft /* Successfully received a packet. Update stat. */
1086 1.1 mycroft ifp->if_ipackets++;
1087 1.1 mycroft }
1088 1.1 mycroft }
1089 1.1 mycroft
1090 1.1 mycroft /*
1091 1.1 mycroft * Ethernet interface interrupt processor
1092 1.1 mycroft */
1093 1.1 mycroft int
1094 1.21 enami mb86960_intr(arg)
1095 1.1 mycroft void *arg;
1096 1.1 mycroft {
1097 1.21 enami struct mb86960_softc *sc = arg;
1098 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1099 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1100 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
1101 1.1 mycroft u_char tstat, rstat;
1102 1.1 mycroft
1103 1.21 enami if (sc->sc_enabled == 0)
1104 1.21 enami return (0);
1105 1.21 enami
1106 1.1 mycroft #if FE_DEBUG >= 4
1107 1.21 enami log(LOG_INFO, "%s: mb86960_intr()\n", sc->sc_dev.dv_xname);
1108 1.21 enami mb86960_dump(LOG_INFO, sc);
1109 1.1 mycroft #endif
1110 1.1 mycroft
1111 1.1 mycroft /*
1112 1.1 mycroft * Get interrupt conditions, masking unneeded flags.
1113 1.1 mycroft */
1114 1.21 enami tstat = bus_space_read_1(bst, bsh, FE_DLCR0) & FE_TMASK;
1115 1.21 enami rstat = bus_space_read_1(bst, bsh, FE_DLCR1) & FE_RMASK;
1116 1.1 mycroft if (tstat == 0 && rstat == 0)
1117 1.1 mycroft return (0);
1118 1.1 mycroft
1119 1.1 mycroft /*
1120 1.1 mycroft * Loop until there are no more new interrupt conditions.
1121 1.1 mycroft */
1122 1.1 mycroft for (;;) {
1123 1.1 mycroft /*
1124 1.1 mycroft * Reset the conditions we are acknowledging.
1125 1.1 mycroft */
1126 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, tstat);
1127 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, rstat);
1128 1.1 mycroft
1129 1.1 mycroft /*
1130 1.1 mycroft * Handle transmitter interrupts. Handle these first because
1131 1.1 mycroft * the receiver will reset the board under some conditions.
1132 1.1 mycroft */
1133 1.1 mycroft if (tstat != 0)
1134 1.21 enami mb86960_tint(sc, tstat);
1135 1.1 mycroft
1136 1.1 mycroft /*
1137 1.1 mycroft * Handle receiver interrupts.
1138 1.1 mycroft */
1139 1.1 mycroft if (rstat != 0)
1140 1.21 enami mb86960_rint(sc, rstat);
1141 1.1 mycroft
1142 1.1 mycroft /*
1143 1.1 mycroft * Update the multicast address filter if it is
1144 1.1 mycroft * needed and possible. We do it now, because
1145 1.1 mycroft * we can make sure the transmission buffer is empty,
1146 1.1 mycroft * and there is a good chance that the receive queue
1147 1.1 mycroft * is empty. It will minimize the possibility of
1148 1.1 mycroft * packet lossage.
1149 1.1 mycroft */
1150 1.1 mycroft if (sc->filter_change &&
1151 1.1 mycroft sc->txb_count == 0 && sc->txb_sched == 0) {
1152 1.21 enami mb86960_loadmar(sc);
1153 1.21 enami ifp->if_flags &= ~IFF_OACTIVE;
1154 1.1 mycroft }
1155 1.1 mycroft
1156 1.1 mycroft /*
1157 1.1 mycroft * If it looks like the transmitter can take more data,
1158 1.1 mycroft * attempt to start output on the interface. This is done
1159 1.1 mycroft * after handling the receiver interrupt to give the
1160 1.1 mycroft * receive operation priority.
1161 1.1 mycroft */
1162 1.21 enami if ((ifp->if_flags & IFF_OACTIVE) == 0)
1163 1.21 enami mb86960_start(ifp);
1164 1.18 explorer
1165 1.18 explorer #if NRND > 0
1166 1.18 explorer if (rstat != 0 || tstat != 0)
1167 1.18 explorer rnd_add_uint32(&sc->rnd_source, rstat + tstat);
1168 1.18 explorer #endif
1169 1.1 mycroft
1170 1.1 mycroft /*
1171 1.1 mycroft * Get interrupt conditions, masking unneeded flags.
1172 1.1 mycroft */
1173 1.21 enami tstat = bus_space_read_1(bst, bsh, FE_DLCR0) & FE_TMASK;
1174 1.21 enami rstat = bus_space_read_1(bst, bsh, FE_DLCR1) & FE_RMASK;
1175 1.1 mycroft if (tstat == 0 && rstat == 0)
1176 1.1 mycroft return (1);
1177 1.1 mycroft }
1178 1.1 mycroft }
1179 1.1 mycroft
1180 1.1 mycroft /*
1181 1.1 mycroft * Process an ioctl request. This code needs some work - it looks pretty ugly.
1182 1.1 mycroft */
1183 1.1 mycroft int
1184 1.21 enami mb86960_ioctl(ifp, cmd, data)
1185 1.21 enami struct ifnet *ifp;
1186 1.21 enami u_long cmd;
1187 1.1 mycroft caddr_t data;
1188 1.1 mycroft {
1189 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
1190 1.21 enami struct ifaddr *ifa = (struct ifaddr *)data;
1191 1.1 mycroft struct ifreq *ifr = (struct ifreq *)data;
1192 1.1 mycroft int s, error = 0;
1193 1.1 mycroft
1194 1.1 mycroft #if FE_DEBUG >= 3
1195 1.21 enami log(LOG_INFO, "%s: ioctl(%lx)\n", sc->sc_dev.dv_xname, cmd);
1196 1.1 mycroft #endif
1197 1.1 mycroft
1198 1.8 mycroft s = splnet();
1199 1.1 mycroft
1200 1.21 enami switch (cmd) {
1201 1.1 mycroft case SIOCSIFADDR:
1202 1.21 enami if ((error = mb86960_enable(sc)) != 0)
1203 1.21 enami break;
1204 1.1 mycroft ifp->if_flags |= IFF_UP;
1205 1.1 mycroft
1206 1.1 mycroft switch (ifa->ifa_addr->sa_family) {
1207 1.1 mycroft #ifdef INET
1208 1.1 mycroft case AF_INET:
1209 1.21 enami mb86960_init(sc);
1210 1.17 is arp_ifinit(ifp, ifa);
1211 1.1 mycroft break;
1212 1.1 mycroft #endif
1213 1.1 mycroft #ifdef NS
1214 1.1 mycroft case AF_NS:
1215 1.1 mycroft {
1216 1.21 enami struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1217 1.1 mycroft
1218 1.1 mycroft if (ns_nullhost(*ina))
1219 1.1 mycroft ina->x_host =
1220 1.21 enami *(union ns_host *)LLADDR(ifp->if_sadl);
1221 1.17 is else {
1222 1.17 is bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
1223 1.17 is ETHER_ADDR_LEN);
1224 1.17 is }
1225 1.1 mycroft /* Set new address. */
1226 1.21 enami mb86960_init(sc);
1227 1.1 mycroft break;
1228 1.1 mycroft }
1229 1.1 mycroft #endif
1230 1.1 mycroft default:
1231 1.21 enami mb86960_init(sc);
1232 1.1 mycroft break;
1233 1.1 mycroft }
1234 1.1 mycroft break;
1235 1.1 mycroft
1236 1.1 mycroft case SIOCSIFFLAGS:
1237 1.1 mycroft if ((ifp->if_flags & IFF_UP) == 0 &&
1238 1.1 mycroft (ifp->if_flags & IFF_RUNNING) != 0) {
1239 1.1 mycroft /*
1240 1.1 mycroft * If interface is marked down and it is running, then
1241 1.1 mycroft * stop it.
1242 1.1 mycroft */
1243 1.21 enami mb86960_stop(sc);
1244 1.1 mycroft ifp->if_flags &= ~IFF_RUNNING;
1245 1.21 enami mb86960_disable(sc);
1246 1.1 mycroft } else if ((ifp->if_flags & IFF_UP) != 0 &&
1247 1.21 enami (ifp->if_flags & IFF_RUNNING) == 0) {
1248 1.1 mycroft /*
1249 1.1 mycroft * If interface is marked up and it is stopped, then
1250 1.1 mycroft * start it.
1251 1.1 mycroft */
1252 1.21 enami if ((error = mb86960_enable(sc)) != 0)
1253 1.21 enami break;
1254 1.21 enami mb86960_init(sc);
1255 1.21 enami } else if (sc->sc_enabled) {
1256 1.1 mycroft /*
1257 1.1 mycroft * Reset the interface to pick up changes in any other
1258 1.1 mycroft * flags that affect hardware registers.
1259 1.1 mycroft */
1260 1.21 enami mb86960_setmode(sc);
1261 1.1 mycroft }
1262 1.1 mycroft #if DEBUG >= 1
1263 1.1 mycroft /* "ifconfig fe0 debug" to print register dump. */
1264 1.1 mycroft if (ifp->if_flags & IFF_DEBUG) {
1265 1.21 enami log(LOG_INFO, "%s: SIOCSIFFLAGS(DEBUG)\n",
1266 1.21 enami sc->sc_dev.dv_xname);
1267 1.21 enami mb86960_dump(LOG_DEBUG, sc);
1268 1.1 mycroft }
1269 1.1 mycroft #endif
1270 1.1 mycroft break;
1271 1.1 mycroft
1272 1.1 mycroft case SIOCADDMULTI:
1273 1.1 mycroft case SIOCDELMULTI:
1274 1.21 enami if (sc->sc_enabled == 0) {
1275 1.21 enami error = EIO;
1276 1.21 enami break;
1277 1.21 enami }
1278 1.21 enami
1279 1.1 mycroft /* Update our multicast list. */
1280 1.21 enami error = (cmd == SIOCADDMULTI) ?
1281 1.21 enami ether_addmulti(ifr, &sc->sc_ec) :
1282 1.21 enami ether_delmulti(ifr, &sc->sc_ec);
1283 1.1 mycroft
1284 1.1 mycroft if (error == ENETRESET) {
1285 1.1 mycroft /*
1286 1.1 mycroft * Multicast list has changed; set the hardware filter
1287 1.1 mycroft * accordingly.
1288 1.1 mycroft */
1289 1.21 enami mb86960_setmode(sc);
1290 1.1 mycroft error = 0;
1291 1.1 mycroft }
1292 1.1 mycroft break;
1293 1.1 mycroft
1294 1.21 enami case SIOCGIFMEDIA:
1295 1.21 enami case SIOCSIFMEDIA:
1296 1.21 enami error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1297 1.21 enami break;
1298 1.21 enami
1299 1.1 mycroft default:
1300 1.1 mycroft error = EINVAL;
1301 1.21 enami break;
1302 1.1 mycroft }
1303 1.1 mycroft
1304 1.1 mycroft splx(s);
1305 1.1 mycroft return (error);
1306 1.1 mycroft }
1307 1.1 mycroft
1308 1.1 mycroft /*
1309 1.1 mycroft * Retreive packet from receive buffer and send to the next level up via
1310 1.1 mycroft * ether_input(). If there is a BPF listener, give a copy to BPF, too.
1311 1.1 mycroft * Returns 0 if success, -1 if error (i.e., mbuf allocation failure).
1312 1.1 mycroft */
1313 1.1 mycroft int
1314 1.21 enami mb86960_get_packet(sc, len)
1315 1.21 enami struct mb86960_softc *sc;
1316 1.1 mycroft int len;
1317 1.1 mycroft {
1318 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1319 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1320 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
1321 1.1 mycroft struct ether_header *eh;
1322 1.1 mycroft struct mbuf *m;
1323 1.1 mycroft
1324 1.1 mycroft /* Allocate a header mbuf. */
1325 1.1 mycroft MGETHDR(m, M_DONTWAIT, MT_DATA);
1326 1.1 mycroft if (m == 0)
1327 1.1 mycroft return (0);
1328 1.1 mycroft m->m_pkthdr.rcvif = ifp;
1329 1.1 mycroft m->m_pkthdr.len = len;
1330 1.1 mycroft
1331 1.1 mycroft /* The following silliness is to make NFS happy. */
1332 1.1 mycroft #define EROUND ((sizeof(struct ether_header) + 3) & ~3)
1333 1.1 mycroft #define EOFF (EROUND - sizeof(struct ether_header))
1334 1.1 mycroft
1335 1.1 mycroft /*
1336 1.1 mycroft * Our strategy has one more problem. There is a policy on
1337 1.1 mycroft * mbuf cluster allocation. It says that we must have at
1338 1.6 mycroft * least MINCLSIZE (208 bytes) to allocate a cluster. For a
1339 1.6 mycroft * packet of a size between (MHLEN - 2) to (MINCLSIZE - 2),
1340 1.6 mycroft * our code violates the rule...
1341 1.1 mycroft * On the other hand, the current code is short, simle,
1342 1.1 mycroft * and fast, however. It does no harmful thing, just waists
1343 1.1 mycroft * some memory. Any comments? FIXME.
1344 1.1 mycroft */
1345 1.1 mycroft
1346 1.1 mycroft /* Attach a cluster if this packet doesn't fit in a normal mbuf. */
1347 1.1 mycroft if (len > MHLEN - EOFF) {
1348 1.1 mycroft MCLGET(m, M_DONTWAIT);
1349 1.1 mycroft if ((m->m_flags & M_EXT) == 0) {
1350 1.1 mycroft m_freem(m);
1351 1.1 mycroft return (0);
1352 1.1 mycroft }
1353 1.1 mycroft }
1354 1.1 mycroft
1355 1.1 mycroft /*
1356 1.1 mycroft * The following assumes there is room for the ether header in the
1357 1.1 mycroft * header mbuf.
1358 1.1 mycroft */
1359 1.1 mycroft m->m_data += EOFF;
1360 1.1 mycroft eh = mtod(m, struct ether_header *);
1361 1.1 mycroft
1362 1.1 mycroft /* Set the length of this packet. */
1363 1.1 mycroft m->m_len = len;
1364 1.1 mycroft
1365 1.1 mycroft /* Get a packet. */
1366 1.21 enami bus_space_read_multi_2(bst, bsh, FE_BMPR8, m->m_data, (len + 1) >> 1);
1367 1.1 mycroft
1368 1.1 mycroft #if NBPFILTER > 0
1369 1.1 mycroft /*
1370 1.1 mycroft * Check if there's a BPF listener on this interface. If so, hand off
1371 1.1 mycroft * the raw packet to bpf.
1372 1.1 mycroft */
1373 1.1 mycroft if (ifp->if_bpf) {
1374 1.1 mycroft bpf_mtap(ifp->if_bpf, m);
1375 1.1 mycroft
1376 1.1 mycroft /*
1377 1.1 mycroft * Note that the interface cannot be in promiscuous mode if
1378 1.1 mycroft * there are no BPF listeners. And if we are in promiscuous
1379 1.1 mycroft * mode, we have to check if this packet is really ours.
1380 1.1 mycroft */
1381 1.1 mycroft if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1382 1.1 mycroft (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
1383 1.17 is bcmp(eh->ether_dhost, sc->sc_enaddr,
1384 1.21 enami sizeof(eh->ether_dhost)) != 0) {
1385 1.1 mycroft m_freem(m);
1386 1.1 mycroft return (1);
1387 1.1 mycroft }
1388 1.1 mycroft }
1389 1.1 mycroft #endif
1390 1.1 mycroft
1391 1.1 mycroft /* Fix up data start offset in mbuf to point past ether header. */
1392 1.1 mycroft m_adj(m, sizeof(struct ether_header));
1393 1.1 mycroft ether_input(ifp, eh, m);
1394 1.1 mycroft return (1);
1395 1.1 mycroft }
1396 1.1 mycroft
1397 1.1 mycroft /*
1398 1.1 mycroft * Write an mbuf chain to the transmission buffer memory using 16 bit PIO.
1399 1.1 mycroft * Returns number of bytes actually written, including length word.
1400 1.1 mycroft *
1401 1.1 mycroft * If an mbuf chain is too long for an Ethernet frame, it is not sent.
1402 1.1 mycroft * Packets shorter than Ethernet minimum are legal, and we pad them
1403 1.1 mycroft * before sending out. An exception is "partial" packets which are
1404 1.1 mycroft * shorter than mandatory Ethernet header.
1405 1.1 mycroft *
1406 1.1 mycroft * I wrote a code for an experimental "delayed padding" technique.
1407 1.1 mycroft * When employed, it postpones the padding process for short packets.
1408 1.1 mycroft * If xmit() occured at the moment, the padding process is omitted, and
1409 1.1 mycroft * garbages are sent as pad data. If next packet is stored in the
1410 1.1 mycroft * transmission buffer before xmit(), write_mbuf() pads the previous
1411 1.1 mycroft * packet before transmitting new packet. This *may* gain the
1412 1.1 mycroft * system performance (slightly).
1413 1.1 mycroft */
1414 1.1 mycroft void
1415 1.21 enami mb86960_write_mbufs(sc, m)
1416 1.21 enami struct mb86960_softc *sc;
1417 1.1 mycroft struct mbuf *m;
1418 1.1 mycroft {
1419 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1420 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1421 1.1 mycroft u_char *data;
1422 1.1 mycroft u_short savebyte; /* WARNING: Architecture dependent! */
1423 1.1 mycroft int totlen, len, wantbyte;
1424 1.21 enami #if FE_DEBUG >= 2
1425 1.21 enami struct mbuf *mp;
1426 1.21 enami #endif
1427 1.16 thorpej
1428 1.16 thorpej /* XXX thorpej 960116 - quiet bogus compiler warning. */
1429 1.16 thorpej savebyte = 0;
1430 1.1 mycroft
1431 1.1 mycroft #if FE_DELAYED_PADDING
1432 1.1 mycroft /* Do the "delayed padding." */
1433 1.1 mycroft len = sc->txb_padding >> 1;
1434 1.1 mycroft if (len > 0) {
1435 1.1 mycroft while (--len >= 0)
1436 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, 0);
1437 1.1 mycroft sc->txb_padding = 0;
1438 1.1 mycroft }
1439 1.1 mycroft #endif
1440 1.1 mycroft
1441 1.4 mycroft /* We need to use m->m_pkthdr.len, so require the header */
1442 1.4 mycroft if ((m->m_flags & M_PKTHDR) == 0)
1443 1.21 enami panic("mb86960_write_mbufs: no header mbuf");
1444 1.4 mycroft
1445 1.1 mycroft #if FE_DEBUG >= 2
1446 1.1 mycroft /* First, count up the total number of bytes to copy. */
1447 1.1 mycroft for (totlen = 0, mp = m; mp != 0; mp = mp->m_next)
1448 1.1 mycroft totlen += mp->m_len;
1449 1.1 mycroft /* Check if this matches the one in the packet header. */
1450 1.1 mycroft if (totlen != m->m_pkthdr.len)
1451 1.1 mycroft log(LOG_WARNING, "%s: packet length mismatch? (%d/%d)\n",
1452 1.1 mycroft sc->sc_dev.dv_xname, totlen, m->m_pkthdr.len);
1453 1.1 mycroft #else
1454 1.1 mycroft /* Just use the length value in the packet header. */
1455 1.1 mycroft totlen = m->m_pkthdr.len;
1456 1.1 mycroft #endif
1457 1.1 mycroft
1458 1.1 mycroft #if FE_DEBUG >= 1
1459 1.1 mycroft /*
1460 1.1 mycroft * Should never send big packets. If such a packet is passed,
1461 1.1 mycroft * it should be a bug of upper layer. We just ignore it.
1462 1.1 mycroft * ... Partial (too short) packets, neither.
1463 1.1 mycroft */
1464 1.1 mycroft if (totlen > ETHER_MAX_LEN || totlen < ETHER_HDR_SIZE) {
1465 1.1 mycroft log(LOG_ERR, "%s: got a %s packet (%u bytes) to send\n",
1466 1.1 mycroft sc->sc_dev.dv_xname,
1467 1.1 mycroft totlen < ETHER_HDR_SIZE ? "partial" : "big", totlen);
1468 1.21 enami sc->sc_ec.ec_if.if_oerrors++;
1469 1.1 mycroft return;
1470 1.1 mycroft }
1471 1.1 mycroft #endif
1472 1.1 mycroft
1473 1.1 mycroft /*
1474 1.1 mycroft * Put the length word for this frame.
1475 1.1 mycroft * Does 86960 accept odd length? -- Yes.
1476 1.1 mycroft * Do we need to pad the length to minimum size by ourselves?
1477 1.1 mycroft * -- Generally yes. But for (or will be) the last
1478 1.1 mycroft * packet in the transmission buffer, we can skip the
1479 1.1 mycroft * padding process. It may gain performance slightly. FIXME.
1480 1.1 mycroft */
1481 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, max(totlen, ETHER_MIN_LEN));
1482 1.1 mycroft
1483 1.1 mycroft /*
1484 1.1 mycroft * Update buffer status now.
1485 1.1 mycroft * Truncate the length up to an even number, since we use outw().
1486 1.1 mycroft */
1487 1.1 mycroft totlen = (totlen + 1) & ~1;
1488 1.1 mycroft sc->txb_free -= FE_DATA_LEN_LEN + max(totlen, ETHER_MIN_LEN);
1489 1.1 mycroft sc->txb_count++;
1490 1.1 mycroft
1491 1.1 mycroft #if FE_DELAYED_PADDING
1492 1.1 mycroft /* Postpone the packet padding if necessary. */
1493 1.1 mycroft if (totlen < ETHER_MIN_LEN)
1494 1.1 mycroft sc->txb_padding = ETHER_MIN_LEN - totlen;
1495 1.1 mycroft #endif
1496 1.1 mycroft
1497 1.1 mycroft /*
1498 1.1 mycroft * Transfer the data from mbuf chain to the transmission buffer.
1499 1.1 mycroft * MB86960 seems to require that data be transferred as words, and
1500 1.1 mycroft * only words. So that we require some extra code to patch
1501 1.1 mycroft * over odd-length mbufs.
1502 1.1 mycroft */
1503 1.1 mycroft wantbyte = 0;
1504 1.1 mycroft for (; m != 0; m = m->m_next) {
1505 1.1 mycroft /* Ignore empty mbuf. */
1506 1.1 mycroft len = m->m_len;
1507 1.1 mycroft if (len == 0)
1508 1.1 mycroft continue;
1509 1.1 mycroft
1510 1.1 mycroft /* Find the actual data to send. */
1511 1.1 mycroft data = mtod(m, caddr_t);
1512 1.1 mycroft
1513 1.1 mycroft /* Finish the last byte. */
1514 1.1 mycroft if (wantbyte) {
1515 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8,
1516 1.21 enami savebyte | (*data << 8));
1517 1.1 mycroft data++;
1518 1.1 mycroft len--;
1519 1.1 mycroft wantbyte = 0;
1520 1.1 mycroft }
1521 1.1 mycroft
1522 1.1 mycroft /* Output contiguous words. */
1523 1.1 mycroft if (len > 1)
1524 1.21 enami bus_space_write_multi_2(bst, bsh, FE_BMPR8, data,
1525 1.21 enami len >> 1);
1526 1.1 mycroft
1527 1.1 mycroft /* Save remaining byte, if there is one. */
1528 1.1 mycroft if (len & 1) {
1529 1.1 mycroft data += len & ~1;
1530 1.1 mycroft savebyte = *data;
1531 1.1 mycroft wantbyte = 1;
1532 1.1 mycroft }
1533 1.1 mycroft }
1534 1.1 mycroft
1535 1.1 mycroft /* Spit the last byte, if the length is odd. */
1536 1.1 mycroft if (wantbyte)
1537 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, savebyte);
1538 1.1 mycroft
1539 1.1 mycroft #if ! FE_DELAYED_PADDING
1540 1.1 mycroft /*
1541 1.1 mycroft * Pad the packet to the minimum length if necessary.
1542 1.1 mycroft */
1543 1.1 mycroft len = (ETHER_MIN_LEN >> 1) - (totlen >> 1);
1544 1.1 mycroft while (--len >= 0)
1545 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, 0);
1546 1.1 mycroft #endif
1547 1.1 mycroft }
1548 1.1 mycroft
1549 1.1 mycroft /*
1550 1.1 mycroft * Compute the multicast address filter from the
1551 1.1 mycroft * list of multicast addresses we need to listen to.
1552 1.1 mycroft */
1553 1.1 mycroft void
1554 1.21 enami mb86960_getmcaf(ec, af)
1555 1.17 is struct ethercom *ec;
1556 1.1 mycroft u_char *af;
1557 1.1 mycroft {
1558 1.17 is struct ifnet *ifp = &ec->ec_if;
1559 1.1 mycroft struct ether_multi *enm;
1560 1.22 mycroft register u_char *cp;
1561 1.23 mycroft register u_int32_t crc;
1562 1.23 mycroft static u_int32_t crctab[] = {
1563 1.23 mycroft 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
1564 1.23 mycroft 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
1565 1.23 mycroft 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
1566 1.23 mycroft 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
1567 1.23 mycroft };
1568 1.23 mycroft register int len;
1569 1.1 mycroft struct ether_multistep step;
1570 1.1 mycroft
1571 1.1 mycroft /*
1572 1.1 mycroft * Set up multicast address filter by passing all multicast addresses
1573 1.1 mycroft * through a crc generator, and then using the high order 6 bits as an
1574 1.1 mycroft * index into the 64 bit logical address filter. The high order bit
1575 1.1 mycroft * selects the word, while the rest of the bits select the bit within
1576 1.1 mycroft * the word.
1577 1.1 mycroft */
1578 1.1 mycroft
1579 1.1 mycroft if ((ifp->if_flags & IFF_PROMISC) != 0)
1580 1.1 mycroft goto allmulti;
1581 1.1 mycroft
1582 1.1 mycroft af[0] = af[1] = af[2] = af[3] = af[4] = af[5] = af[6] = af[7] = 0x00;
1583 1.17 is ETHER_FIRST_MULTI(step, ec, enm);
1584 1.1 mycroft while (enm != NULL) {
1585 1.1 mycroft if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
1586 1.1 mycroft sizeof(enm->enm_addrlo)) != 0) {
1587 1.1 mycroft /*
1588 1.1 mycroft * We must listen to a range of multicast addresses.
1589 1.1 mycroft * For now, just accept all multicasts, rather than
1590 1.1 mycroft * trying to set only those filter bits needed to match
1591 1.1 mycroft * the range. (At this time, the only use of address
1592 1.1 mycroft * ranges is for IP multicast routing, for which the
1593 1.1 mycroft * range is big enough to require all bits set.)
1594 1.1 mycroft */
1595 1.1 mycroft goto allmulti;
1596 1.1 mycroft }
1597 1.1 mycroft
1598 1.1 mycroft cp = enm->enm_addrlo;
1599 1.1 mycroft crc = 0xffffffff;
1600 1.1 mycroft for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
1601 1.23 mycroft crc ^= *cp++;
1602 1.23 mycroft crc = (crc >> 4) ^ crctab[crc & 0xf];
1603 1.23 mycroft crc = (crc >> 4) ^ crctab[crc & 0xf];
1604 1.1 mycroft }
1605 1.1 mycroft /* Just want the 6 most significant bits. */
1606 1.1 mycroft crc >>= 26;
1607 1.1 mycroft
1608 1.1 mycroft /* Turn on the corresponding bit in the filter. */
1609 1.1 mycroft af[crc >> 3] |= 1 << (crc & 7);
1610 1.1 mycroft
1611 1.1 mycroft ETHER_NEXT_MULTI(step, enm);
1612 1.1 mycroft }
1613 1.1 mycroft ifp->if_flags &= ~IFF_ALLMULTI;
1614 1.1 mycroft return;
1615 1.1 mycroft
1616 1.1 mycroft allmulti:
1617 1.1 mycroft ifp->if_flags |= IFF_ALLMULTI;
1618 1.1 mycroft af[0] = af[1] = af[2] = af[3] = af[4] = af[5] = af[6] = af[7] = 0xff;
1619 1.1 mycroft }
1620 1.1 mycroft
1621 1.1 mycroft /*
1622 1.1 mycroft * Calculate a new "multicast packet filter" and put the 86960
1623 1.1 mycroft * receiver in appropriate mode.
1624 1.1 mycroft */
1625 1.1 mycroft void
1626 1.21 enami mb86960_setmode(sc)
1627 1.21 enami struct mb86960_softc *sc;
1628 1.1 mycroft {
1629 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1630 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1631 1.21 enami int flags = sc->sc_ec.ec_if.if_flags;
1632 1.1 mycroft
1633 1.1 mycroft /*
1634 1.1 mycroft * If the interface is not running, we postpone the update
1635 1.1 mycroft * process for receive modes and multicast address filter
1636 1.1 mycroft * until the interface is restarted. It reduces some
1637 1.1 mycroft * complicated job on maintaining chip states. (Earlier versions
1638 1.1 mycroft * of this driver had a bug on that point...)
1639 1.1 mycroft *
1640 1.21 enami * To complete the trick, mb86960_init() calls mb86960_setmode() after
1641 1.1 mycroft * restarting the interface.
1642 1.1 mycroft */
1643 1.1 mycroft if ((flags & IFF_RUNNING) == 0)
1644 1.1 mycroft return;
1645 1.1 mycroft
1646 1.1 mycroft /*
1647 1.1 mycroft * Promiscuous mode is handled separately.
1648 1.1 mycroft */
1649 1.1 mycroft if ((flags & IFF_PROMISC) != 0) {
1650 1.1 mycroft /*
1651 1.1 mycroft * Program 86960 to receive all packets on the segment
1652 1.1 mycroft * including those directed to other stations.
1653 1.1 mycroft * Multicast filter stored in MARs are ignored
1654 1.1 mycroft * under this setting, so we don't need to update it.
1655 1.1 mycroft *
1656 1.6 mycroft * Promiscuous mode is used solely by BPF, and BPF only
1657 1.6 mycroft * listens to valid (no error) packets. So, we ignore
1658 1.6 mycroft * errornous ones even in this mode.
1659 1.1 mycroft */
1660 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR5,
1661 1.1 mycroft sc->proto_dlcr5 | FE_D5_AFM0 | FE_D5_AFM1);
1662 1.1 mycroft sc->filter_change = 0;
1663 1.1 mycroft
1664 1.1 mycroft #if FE_DEBUG >= 3
1665 1.1 mycroft log(LOG_INFO, "%s: promiscuous mode\n", sc->sc_dev.dv_xname);
1666 1.1 mycroft #endif
1667 1.1 mycroft return;
1668 1.1 mycroft }
1669 1.1 mycroft
1670 1.1 mycroft /*
1671 1.1 mycroft * Turn the chip to the normal (non-promiscuous) mode.
1672 1.1 mycroft */
1673 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR5, sc->proto_dlcr5 | FE_D5_AFM1);
1674 1.1 mycroft
1675 1.1 mycroft /*
1676 1.1 mycroft * Find the new multicast filter value.
1677 1.1 mycroft */
1678 1.21 enami mb86960_getmcaf(&sc->sc_ec, sc->filter);
1679 1.1 mycroft sc->filter_change = 1;
1680 1.1 mycroft
1681 1.1 mycroft #if FE_DEBUG >= 3
1682 1.1 mycroft log(LOG_INFO,
1683 1.1 mycroft "%s: address filter: [%02x %02x %02x %02x %02x %02x %02x %02x]\n",
1684 1.1 mycroft sc->sc_dev.dv_xname,
1685 1.1 mycroft sc->filter[0], sc->filter[1], sc->filter[2], sc->filter[3],
1686 1.1 mycroft sc->filter[4], sc->filter[5], sc->filter[6], sc->filter[7]);
1687 1.1 mycroft #endif
1688 1.1 mycroft
1689 1.1 mycroft /*
1690 1.1 mycroft * We have to update the multicast filter in the 86960, A.S.A.P.
1691 1.1 mycroft *
1692 1.1 mycroft * Note that the DLC (Data Linc Control unit, i.e. transmitter
1693 1.1 mycroft * and receiver) must be stopped when feeding the filter, and
1694 1.1 mycroft * DLC trushes all packets in both transmission and receive
1695 1.1 mycroft * buffers when stopped.
1696 1.1 mycroft *
1697 1.1 mycroft * ... Are the above sentenses correct? I have to check the
1698 1.1 mycroft * manual of the MB86960A. FIXME.
1699 1.1 mycroft *
1700 1.1 mycroft * To reduce the packet lossage, we delay the filter update
1701 1.1 mycroft * process until buffers are empty.
1702 1.1 mycroft */
1703 1.1 mycroft if (sc->txb_sched == 0 && sc->txb_count == 0 &&
1704 1.21 enami (bus_space_read_1(bst, bsh, FE_DLCR1) & FE_D1_PKTRDY) == 0) {
1705 1.1 mycroft /*
1706 1.1 mycroft * Buffers are (apparently) empty. Load
1707 1.1 mycroft * the new filter value into MARs now.
1708 1.1 mycroft */
1709 1.21 enami mb86960_loadmar(sc);
1710 1.1 mycroft } else {
1711 1.1 mycroft /*
1712 1.1 mycroft * Buffers are not empty. Mark that we have to update
1713 1.21 enami * the MARs. The new filter will be loaded by mb86960_intr()
1714 1.1 mycroft * later.
1715 1.1 mycroft */
1716 1.1 mycroft #if FE_DEBUG >= 4
1717 1.21 enami log(LOG_INFO, "%s: filter change delayed\n",
1718 1.21 enami sc->sc_dev.dv_xname);
1719 1.1 mycroft #endif
1720 1.1 mycroft }
1721 1.1 mycroft }
1722 1.1 mycroft
1723 1.1 mycroft /*
1724 1.1 mycroft * Load a new multicast address filter into MARs.
1725 1.1 mycroft *
1726 1.21 enami * The caller must have splnet'ed befor mb86960_loadmar.
1727 1.1 mycroft * This function starts the DLC upon return. So it can be called only
1728 1.1 mycroft * when the chip is working, i.e., from the driver's point of view, when
1729 1.1 mycroft * a device is RUNNING. (I mistook the point in previous versions.)
1730 1.1 mycroft */
1731 1.1 mycroft void
1732 1.21 enami mb86960_loadmar(sc)
1733 1.21 enami struct mb86960_softc *sc;
1734 1.1 mycroft {
1735 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1736 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1737 1.1 mycroft
1738 1.1 mycroft /* Stop the DLC (transmitter and receiver). */
1739 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
1740 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
1741 1.1 mycroft
1742 1.1 mycroft /* Select register bank 1 for MARs. */
1743 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1744 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP);
1745 1.1 mycroft
1746 1.1 mycroft /* Copy filter value into the registers. */
1747 1.21 enami bus_space_write_region_1(bst, bsh, FE_MAR8, sc->filter, FE_FILTER_LEN);
1748 1.1 mycroft
1749 1.1 mycroft /* Restore the bank selection for BMPRs (i.e., runtime registers). */
1750 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1751 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP);
1752 1.1 mycroft
1753 1.1 mycroft /* Restart the DLC. */
1754 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
1755 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_ENABLE);
1756 1.1 mycroft
1757 1.1 mycroft /* We have just updated the filter. */
1758 1.1 mycroft sc->filter_change = 0;
1759 1.1 mycroft
1760 1.1 mycroft #if FE_DEBUG >= 3
1761 1.1 mycroft log(LOG_INFO, "%s: address filter changed\n", sc->sc_dev.dv_xname);
1762 1.1 mycroft #endif
1763 1.1 mycroft }
1764 1.1 mycroft
1765 1.21 enami /*
1766 1.21 enami * Enable power on the interface.
1767 1.21 enami */
1768 1.21 enami int
1769 1.21 enami mb86960_enable(sc)
1770 1.21 enami struct mb86960_softc *sc;
1771 1.21 enami {
1772 1.21 enami
1773 1.21 enami #if FE_DEBUG >= 3
1774 1.21 enami log(LOG_INFO, "%s: mb86960_enable()\n", sc->sc_dev.dv_xname);
1775 1.21 enami #endif
1776 1.21 enami
1777 1.21 enami if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
1778 1.21 enami if ((*sc->sc_enable)(sc) != 0) {
1779 1.21 enami printf("%s: device enable failed\n",
1780 1.21 enami sc->sc_dev.dv_xname);
1781 1.21 enami return (EIO);
1782 1.21 enami }
1783 1.21 enami }
1784 1.21 enami
1785 1.21 enami sc->sc_enabled = 1;
1786 1.21 enami return (0);
1787 1.21 enami }
1788 1.21 enami
1789 1.21 enami /*
1790 1.21 enami * Disable power on the interface.
1791 1.21 enami */
1792 1.21 enami void
1793 1.21 enami mb86960_disable(sc)
1794 1.21 enami struct mb86960_softc *sc;
1795 1.21 enami {
1796 1.21 enami
1797 1.21 enami #if FE_DEBUG >= 3
1798 1.21 enami log(LOG_INFO, "%s: mb86960_disable()\n", sc->sc_dev.dv_xname);
1799 1.21 enami #endif
1800 1.21 enami
1801 1.21 enami if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
1802 1.21 enami (*sc->sc_disable)(sc);
1803 1.21 enami sc->sc_enabled = 0;
1804 1.21 enami }
1805 1.21 enami }
1806 1.21 enami
1807 1.1 mycroft #if FE_DEBUG >= 1
1808 1.1 mycroft void
1809 1.21 enami mb86960_dump(level, sc)
1810 1.1 mycroft int level;
1811 1.21 enami struct mb86960_softc *sc;
1812 1.1 mycroft {
1813 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1814 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1815 1.1 mycroft u_char save_dlcr7;
1816 1.1 mycroft
1817 1.21 enami save_dlcr7 = bus_space_read_1(bst, bsh, FE_DLCR7);
1818 1.1 mycroft
1819 1.21 enami log(level, "\tDLCR = %02x %02x %02x %02x %02x %02x %02x %02x\n",
1820 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR0),
1821 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR1),
1822 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR2),
1823 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR3),
1824 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR4),
1825 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR5),
1826 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR6),
1827 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR7));
1828 1.21 enami
1829 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1830 1.21 enami (save_dlcr7 & ~FE_D7_RBS) | FE_D7_RBS_DLCR);
1831 1.21 enami log(level, "\t %02x %02x %02x %02x %02x %02x %02x %02x\n",
1832 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR8),
1833 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR9),
1834 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR10),
1835 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR11),
1836 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR12),
1837 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR13),
1838 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR14),
1839 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR15));
1840 1.21 enami
1841 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1842 1.21 enami (save_dlcr7 & ~FE_D7_RBS) | FE_D7_RBS_MAR);
1843 1.21 enami log(level, "\tMAR = %02x %02x %02x %02x %02x %02x %02x %02x\n",
1844 1.21 enami bus_space_read_1(bst, bsh, FE_MAR8),
1845 1.21 enami bus_space_read_1(bst, bsh, FE_MAR9),
1846 1.21 enami bus_space_read_1(bst, bsh, FE_MAR10),
1847 1.21 enami bus_space_read_1(bst, bsh, FE_MAR11),
1848 1.21 enami bus_space_read_1(bst, bsh, FE_MAR12),
1849 1.21 enami bus_space_read_1(bst, bsh, FE_MAR13),
1850 1.21 enami bus_space_read_1(bst, bsh, FE_MAR14),
1851 1.21 enami bus_space_read_1(bst, bsh, FE_MAR15));
1852 1.21 enami
1853 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1854 1.21 enami (save_dlcr7 & ~FE_D7_RBS) | FE_D7_RBS_BMPR);
1855 1.21 enami log(level,
1856 1.21 enami "\tBMPR = xx xx %02x %02x %02x %02x %02x %02x %02x %02x xx %02x\n",
1857 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR10),
1858 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR11),
1859 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR12),
1860 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR13),
1861 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR14),
1862 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR15),
1863 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR16),
1864 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR17),
1865 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR19));
1866 1.1 mycroft
1867 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7, save_dlcr7);
1868 1.1 mycroft }
1869 1.1 mycroft #endif
1870