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