mb86960.c revision 1.32.4.2 1 1.32.4.2 thorpej /* $NetBSD: mb86960.c,v 1.32.4.2 1999/07/01 23:32:29 thorpej 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.26 jonathan #include "opt_ns.h"
51 1.1 mycroft #include "bpfilter.h"
52 1.18 explorer #include "rnd.h"
53 1.1 mycroft
54 1.1 mycroft #include <sys/param.h>
55 1.1 mycroft #include <sys/systm.h>
56 1.1 mycroft #include <sys/errno.h>
57 1.1 mycroft #include <sys/ioctl.h>
58 1.1 mycroft #include <sys/mbuf.h>
59 1.1 mycroft #include <sys/socket.h>
60 1.1 mycroft #include <sys/syslog.h>
61 1.1 mycroft #include <sys/device.h>
62 1.18 explorer #if NRND > 0
63 1.18 explorer #include <sys/rnd.h>
64 1.18 explorer #endif
65 1.1 mycroft
66 1.1 mycroft #include <net/if.h>
67 1.1 mycroft #include <net/if_dl.h>
68 1.1 mycroft #include <net/if_types.h>
69 1.21 enami #include <net/if_media.h>
70 1.17 is #include <net/if_ether.h>
71 1.1 mycroft
72 1.1 mycroft #ifdef INET
73 1.1 mycroft #include <netinet/in.h>
74 1.1 mycroft #include <netinet/in_systm.h>
75 1.1 mycroft #include <netinet/in_var.h>
76 1.1 mycroft #include <netinet/ip.h>
77 1.17 is #include <netinet/if_inarp.h>
78 1.1 mycroft #endif
79 1.1 mycroft
80 1.1 mycroft #ifdef NS
81 1.1 mycroft #include <netns/ns.h>
82 1.1 mycroft #include <netns/ns_if.h>
83 1.1 mycroft #endif
84 1.1 mycroft
85 1.1 mycroft #if NBPFILTER > 0
86 1.1 mycroft #include <net/bpf.h>
87 1.1 mycroft #include <net/bpfdesc.h>
88 1.1 mycroft #endif
89 1.1 mycroft
90 1.21 enami #include <machine/bus.h>
91 1.1 mycroft
92 1.3 cgd #include <dev/ic/mb86960reg.h>
93 1.21 enami #include <dev/ic/mb86960var.h>
94 1.1 mycroft
95 1.1 mycroft /* Standard driver entry points. These can be static. */
96 1.21 enami void mb86960_init __P((struct mb86960_softc *));
97 1.21 enami int mb86960_ioctl __P((struct ifnet *, u_long, caddr_t));
98 1.21 enami void mb86960_start __P((struct ifnet *));
99 1.21 enami void mb86960_reset __P((struct mb86960_softc *));
100 1.21 enami void mb86960_watchdog __P((struct ifnet *));
101 1.1 mycroft
102 1.1 mycroft /* Local functions. Order of declaration is confused. FIXME. */
103 1.21 enami int mb86960_get_packet __P((struct mb86960_softc *, int));
104 1.21 enami void mb86960_stop __P((struct mb86960_softc *));
105 1.21 enami void mb86960_tint __P((struct mb86960_softc *, u_char));
106 1.21 enami void mb86960_rint __P((struct mb86960_softc *, u_char));
107 1.21 enami static __inline__
108 1.21 enami void mb86960_xmit __P((struct mb86960_softc *));
109 1.21 enami void mb86960_write_mbufs __P((struct mb86960_softc *, struct mbuf *));
110 1.21 enami static __inline__
111 1.21 enami void mb86960_droppacket __P((struct mb86960_softc *));
112 1.21 enami void mb86960_getmcaf __P((struct ethercom *, u_char *));
113 1.21 enami void mb86960_setmode __P((struct mb86960_softc *));
114 1.21 enami void mb86960_loadmar __P((struct mb86960_softc *));
115 1.1 mycroft
116 1.21 enami int mb86960_mediachange __P((struct ifnet *));
117 1.21 enami void mb86960_mediastatus __P((struct ifnet *, struct ifmediareq *));
118 1.1 mycroft
119 1.21 enami #if FE_DEBUG >= 1
120 1.21 enami void mb86960_dump __P((int, struct mb86960_softc *));
121 1.1 mycroft #endif
122 1.1 mycroft
123 1.1 mycroft void
124 1.21 enami mb86960_attach(sc, type, myea)
125 1.21 enami struct mb86960_softc *sc;
126 1.21 enami enum mb86960_type type;
127 1.21 enami u_int8_t *myea;
128 1.1 mycroft {
129 1.21 enami bus_space_tag_t bst = sc->sc_bst;
130 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
131 1.1 mycroft
132 1.21 enami sc->type = type;
133 1.1 mycroft
134 1.21 enami /* Register values which depend on board design. */
135 1.21 enami sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL;
136 1.21 enami sc->proto_dlcr5 = 0;
137 1.21 enami sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
138 1.1 mycroft
139 1.21 enami switch (sc->type) {
140 1.21 enami case MB86960_TYPE_86960:
141 1.21 enami sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
142 1.1 mycroft break;
143 1.21 enami case MB86960_TYPE_86965:
144 1.21 enami sc->proto_dlcr7 = FE_D7_BYTSWP_LH;
145 1.1 mycroft break;
146 1.1 mycroft }
147 1.1 mycroft
148 1.1 mycroft /*
149 1.1 mycroft * Program the 86960 as follows:
150 1.1 mycroft * SRAM: 32KB, 100ns, byte-wide access.
151 1.1 mycroft * Transmission buffer: 4KB x 2.
152 1.1 mycroft * System bus interface: 16 bits.
153 1.1 mycroft * We cannot change these values but TXBSIZE, because they
154 1.1 mycroft * are hard-wired on the board. Modifying TXBSIZE will affect
155 1.1 mycroft * the driver performance.
156 1.1 mycroft */
157 1.21 enami sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB |
158 1.21 enami FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
159 1.1 mycroft
160 1.1 mycroft /*
161 1.1 mycroft * Minimum initialization of the hardware.
162 1.1 mycroft * We write into registers; hope I/O ports have no
163 1.1 mycroft * overlap with other boards.
164 1.1 mycroft */
165 1.1 mycroft
166 1.1 mycroft /* Initialize 86960. */
167 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
168 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
169 1.1 mycroft delay(200);
170 1.1 mycroft
171 1.21 enami #ifdef DIAGNOSTIC
172 1.21 enami if (myea == NULL) {
173 1.21 enami printf("%s: ethernet address shouldn't be NULL\n",
174 1.21 enami sc->sc_dev.dv_xname);
175 1.21 enami panic("NULL ethernet address");
176 1.1 mycroft }
177 1.1 mycroft #endif
178 1.21 enami bcopy(myea, sc->sc_enaddr, sizeof(sc->sc_enaddr));
179 1.1 mycroft
180 1.1 mycroft /* Disable all interrupts. */
181 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0);
182 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0);
183 1.1 mycroft }
184 1.1 mycroft
185 1.1 mycroft /*
186 1.1 mycroft * Install interface into kernel networking data structures
187 1.1 mycroft */
188 1.1 mycroft void
189 1.21 enami mb86960_config(sc, media, nmedia, defmedia)
190 1.21 enami struct mb86960_softc *sc;
191 1.21 enami int *media, nmedia, defmedia;
192 1.1 mycroft {
193 1.1 mycroft struct cfdata *cf = sc->sc_dev.dv_cfdata;
194 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
195 1.21 enami int i;
196 1.1 mycroft
197 1.1 mycroft /* Stop the 86960. */
198 1.21 enami mb86960_stop(sc);
199 1.1 mycroft
200 1.1 mycroft /* Initialize ifnet structure. */
201 1.12 thorpej bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
202 1.12 thorpej ifp->if_softc = sc;
203 1.21 enami ifp->if_start = mb86960_start;
204 1.21 enami ifp->if_ioctl = mb86960_ioctl;
205 1.21 enami ifp->if_watchdog = mb86960_watchdog;
206 1.6 mycroft ifp->if_flags =
207 1.6 mycroft IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
208 1.1 mycroft
209 1.1 mycroft #if FE_DEBUG >= 3
210 1.21 enami log(LOG_INFO, "%s: mb86960_config()\n", sc->sc_dev.dv_xname);
211 1.21 enami mb86960_dump(LOG_INFO, sc);
212 1.1 mycroft #endif
213 1.1 mycroft
214 1.1 mycroft #if FE_SINGLE_TRANSMISSION
215 1.1 mycroft /* Override txb config to allocate minimum. */
216 1.1 mycroft sc->proto_dlcr6 &= ~FE_D6_TXBSIZ
217 1.1 mycroft sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
218 1.1 mycroft #endif
219 1.1 mycroft
220 1.1 mycroft /* Modify hardware config if it is requested. */
221 1.1 mycroft if ((cf->cf_flags & FE_FLAGS_OVERRIDE_DLCR6) != 0)
222 1.1 mycroft sc->proto_dlcr6 = cf->cf_flags & FE_FLAGS_DLCR6_VALUE;
223 1.1 mycroft
224 1.1 mycroft /* Find TX buffer size, based on the hardware dependent proto. */
225 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) {
226 1.1 mycroft case FE_D6_TXBSIZ_2x2KB:
227 1.1 mycroft sc->txb_size = 2048;
228 1.1 mycroft break;
229 1.1 mycroft case FE_D6_TXBSIZ_2x4KB:
230 1.1 mycroft sc->txb_size = 4096;
231 1.1 mycroft break;
232 1.1 mycroft case FE_D6_TXBSIZ_2x8KB:
233 1.1 mycroft sc->txb_size = 8192;
234 1.1 mycroft break;
235 1.1 mycroft default:
236 1.1 mycroft /* Oops, we can't work with single buffer configuration. */
237 1.1 mycroft #if FE_DEBUG >= 2
238 1.1 mycroft log(LOG_WARNING, "%s: strange TXBSIZ config; fixing\n",
239 1.1 mycroft sc->sc_dev.dv_xname);
240 1.1 mycroft #endif
241 1.1 mycroft sc->proto_dlcr6 &= ~FE_D6_TXBSIZ;
242 1.1 mycroft sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
243 1.1 mycroft sc->txb_size = 2048;
244 1.1 mycroft break;
245 1.1 mycroft }
246 1.1 mycroft
247 1.21 enami /* Initialize media goo. */
248 1.21 enami ifmedia_init(&sc->sc_media, 0, mb86960_mediachange,
249 1.21 enami mb86960_mediastatus);
250 1.21 enami if (media != NULL) {
251 1.21 enami for (i = 0; i < nmedia; i++)
252 1.21 enami ifmedia_add(&sc->sc_media, media[i], 0, NULL);
253 1.21 enami ifmedia_set(&sc->sc_media, defmedia);
254 1.21 enami } else {
255 1.21 enami ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
256 1.21 enami ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
257 1.21 enami }
258 1.21 enami
259 1.1 mycroft /* Attach the interface. */
260 1.1 mycroft if_attach(ifp);
261 1.17 is ether_ifattach(ifp, sc->sc_enaddr);
262 1.1 mycroft
263 1.21 enami #if NBPFILTER > 0
264 1.21 enami /* If BPF is in the kernel, call the attach for it. */
265 1.21 enami bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
266 1.21 enami #endif
267 1.21 enami #if NRND > 0
268 1.21 enami rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
269 1.31 explorer RND_TYPE_NET, 0);
270 1.21 enami #endif
271 1.1 mycroft /* Print additional info when attached. */
272 1.21 enami printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
273 1.21 enami ether_sprintf(sc->sc_enaddr));
274 1.21 enami
275 1.1 mycroft #if FE_DEBUG >= 3
276 1.1 mycroft {
277 1.1 mycroft int buf, txb, bbw, sbw, ram;
278 1.1 mycroft
279 1.1 mycroft buf = txb = bbw = sbw = ram = -1;
280 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_BUFSIZ) {
281 1.1 mycroft case FE_D6_BUFSIZ_8KB:
282 1.1 mycroft buf = 8;
283 1.1 mycroft break;
284 1.1 mycroft case FE_D6_BUFSIZ_16KB:
285 1.1 mycroft buf = 16;
286 1.1 mycroft break;
287 1.1 mycroft case FE_D6_BUFSIZ_32KB:
288 1.1 mycroft buf = 32;
289 1.1 mycroft break;
290 1.1 mycroft case FE_D6_BUFSIZ_64KB:
291 1.1 mycroft buf = 64;
292 1.1 mycroft break;
293 1.1 mycroft }
294 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) {
295 1.1 mycroft case FE_D6_TXBSIZ_2x2KB:
296 1.1 mycroft txb = 2;
297 1.1 mycroft break;
298 1.1 mycroft case FE_D6_TXBSIZ_2x4KB:
299 1.1 mycroft txb = 4;
300 1.1 mycroft break;
301 1.1 mycroft case FE_D6_TXBSIZ_2x8KB:
302 1.1 mycroft txb = 8;
303 1.1 mycroft break;
304 1.1 mycroft }
305 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_BBW) {
306 1.1 mycroft case FE_D6_BBW_BYTE:
307 1.1 mycroft bbw = 8;
308 1.1 mycroft break;
309 1.1 mycroft case FE_D6_BBW_WORD:
310 1.1 mycroft bbw = 16;
311 1.1 mycroft break;
312 1.1 mycroft }
313 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_SBW) {
314 1.1 mycroft case FE_D6_SBW_BYTE:
315 1.1 mycroft sbw = 8;
316 1.1 mycroft break;
317 1.1 mycroft case FE_D6_SBW_WORD:
318 1.1 mycroft sbw = 16;
319 1.1 mycroft break;
320 1.1 mycroft }
321 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_SRAM) {
322 1.1 mycroft case FE_D6_SRAM_100ns:
323 1.1 mycroft ram = 100;
324 1.1 mycroft break;
325 1.1 mycroft case FE_D6_SRAM_150ns:
326 1.1 mycroft ram = 150;
327 1.1 mycroft break;
328 1.1 mycroft }
329 1.15 christos printf("%s: SRAM %dKB %dbit %dns, TXB %dKBx2, %dbit I/O\n",
330 1.1 mycroft sc->sc_dev.dv_xname, buf, bbw, ram, txb, sbw);
331 1.1 mycroft }
332 1.1 mycroft #endif
333 1.21 enami }
334 1.21 enami
335 1.21 enami /*
336 1.21 enami * Media change callback.
337 1.21 enami */
338 1.21 enami int
339 1.21 enami mb86960_mediachange(ifp)
340 1.21 enami struct ifnet *ifp;
341 1.21 enami {
342 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
343 1.1 mycroft
344 1.21 enami if (sc->sc_mediachange)
345 1.21 enami return ((*sc->sc_mediachange)(sc));
346 1.32.4.2 thorpej return (0);
347 1.21 enami }
348 1.1 mycroft
349 1.21 enami /*
350 1.21 enami * Media status callback.
351 1.21 enami */
352 1.21 enami void
353 1.21 enami mb86960_mediastatus(ifp, ifmr)
354 1.21 enami struct ifnet *ifp;
355 1.21 enami struct ifmediareq *ifmr;
356 1.21 enami {
357 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
358 1.18 explorer
359 1.21 enami if (sc->sc_enabled == 0) {
360 1.21 enami ifmr->ifm_active = IFM_ETHER | IFM_NONE;
361 1.21 enami ifmr->ifm_status = 0;
362 1.21 enami return;
363 1.21 enami }
364 1.21 enami
365 1.21 enami if (sc->sc_mediastatus)
366 1.21 enami (*sc->sc_mediastatus)(sc, ifmr);
367 1.1 mycroft }
368 1.1 mycroft
369 1.1 mycroft /*
370 1.1 mycroft * Reset interface.
371 1.1 mycroft */
372 1.1 mycroft void
373 1.21 enami mb86960_reset(sc)
374 1.21 enami struct mb86960_softc *sc;
375 1.1 mycroft {
376 1.1 mycroft int s;
377 1.1 mycroft
378 1.8 mycroft s = splnet();
379 1.21 enami mb86960_stop(sc);
380 1.21 enami mb86960_init(sc);
381 1.1 mycroft splx(s);
382 1.1 mycroft }
383 1.1 mycroft
384 1.1 mycroft /*
385 1.1 mycroft * Stop everything on the interface.
386 1.1 mycroft *
387 1.1 mycroft * All buffered packets, both transmitting and receiving,
388 1.1 mycroft * if any, will be lost by stopping the interface.
389 1.1 mycroft */
390 1.1 mycroft void
391 1.21 enami mb86960_stop(sc)
392 1.21 enami struct mb86960_softc *sc;
393 1.1 mycroft {
394 1.21 enami bus_space_tag_t bst = sc->sc_bst;
395 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
396 1.1 mycroft
397 1.1 mycroft #if FE_DEBUG >= 3
398 1.21 enami log(LOG_INFO, "%s: top of mb86960_stop()\n", sc->sc_dev.dv_xname);
399 1.21 enami mb86960_dump(LOG_INFO, sc);
400 1.1 mycroft #endif
401 1.1 mycroft
402 1.1 mycroft /* Disable interrupts. */
403 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0x00);
404 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0x00);
405 1.1 mycroft
406 1.1 mycroft /* Stop interface hardware. */
407 1.1 mycroft delay(200);
408 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
409 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
410 1.1 mycroft delay(200);
411 1.1 mycroft
412 1.1 mycroft /* Clear all interrupt status. */
413 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF);
414 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF);
415 1.1 mycroft
416 1.1 mycroft /* Put the chip in stand-by mode. */
417 1.1 mycroft delay(200);
418 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
419 1.21 enami sc->proto_dlcr7 | FE_D7_POWER_DOWN);
420 1.1 mycroft delay(200);
421 1.1 mycroft
422 1.1 mycroft /* MAR loading can be delayed. */
423 1.1 mycroft sc->filter_change = 0;
424 1.1 mycroft
425 1.1 mycroft /* Call a hook. */
426 1.21 enami if (sc->stop_card)
427 1.21 enami (*sc->stop_card)(sc);
428 1.1 mycroft
429 1.1 mycroft #if DEBUG >= 3
430 1.21 enami log(LOG_INFO, "%s: end of mb86960_stop()\n", sc->sc_dev.dv_xname);
431 1.21 enami mb86960_dump(LOG_INFO, sc);
432 1.1 mycroft #endif
433 1.1 mycroft }
434 1.1 mycroft
435 1.1 mycroft /*
436 1.1 mycroft * Device timeout/watchdog routine. Entered if the device neglects to
437 1.1 mycroft * generate an interrupt after a transmit has been started on it.
438 1.1 mycroft */
439 1.1 mycroft void
440 1.21 enami mb86960_watchdog(ifp)
441 1.12 thorpej struct ifnet *ifp;
442 1.1 mycroft {
443 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
444 1.1 mycroft
445 1.1 mycroft log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
446 1.1 mycroft #if FE_DEBUG >= 3
447 1.21 enami mb86960_dump(LOG_INFO, sc);
448 1.1 mycroft #endif
449 1.1 mycroft
450 1.1 mycroft /* Record how many packets are lost by this accident. */
451 1.21 enami sc->sc_ec.ec_if.if_oerrors += sc->txb_sched + sc->txb_count;
452 1.1 mycroft
453 1.21 enami mb86960_reset(sc);
454 1.1 mycroft }
455 1.1 mycroft
456 1.1 mycroft /*
457 1.6 mycroft * Drop (skip) a packet from receive buffer in 86960 memory.
458 1.6 mycroft */
459 1.21 enami static __inline__ void
460 1.21 enami mb86960_droppacket(sc)
461 1.21 enami struct mb86960_softc *sc;
462 1.6 mycroft {
463 1.21 enami bus_space_tag_t bst = sc->sc_bst;
464 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
465 1.6 mycroft
466 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR14, FE_B14_FILTER | FE_B14_SKIP);
467 1.6 mycroft }
468 1.6 mycroft
469 1.6 mycroft /*
470 1.1 mycroft * Initialize device.
471 1.1 mycroft */
472 1.1 mycroft void
473 1.21 enami mb86960_init(sc)
474 1.21 enami struct mb86960_softc *sc;
475 1.1 mycroft {
476 1.21 enami bus_space_tag_t bst = sc->sc_bst;
477 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
478 1.21 enami struct ifnet *ifp = &sc->sc_ec.ec_if;
479 1.5 mycroft int i;
480 1.1 mycroft
481 1.1 mycroft #if FE_DEBUG >= 3
482 1.21 enami log(LOG_INFO, "%s: top of mb86960_init()\n", sc->sc_dev.dv_xname);
483 1.21 enami mb86960_dump(LOG_INFO, sc);
484 1.1 mycroft #endif
485 1.1 mycroft
486 1.1 mycroft /* Reset transmitter flags. */
487 1.1 mycroft ifp->if_flags &= ~IFF_OACTIVE;
488 1.1 mycroft ifp->if_timer = 0;
489 1.1 mycroft
490 1.1 mycroft sc->txb_free = sc->txb_size;
491 1.1 mycroft sc->txb_count = 0;
492 1.1 mycroft sc->txb_sched = 0;
493 1.1 mycroft
494 1.21 enami /* Do any card-specific initialization, if applicable. */
495 1.21 enami if (sc->init_card)
496 1.21 enami (*sc->init_card)(sc);
497 1.1 mycroft
498 1.1 mycroft #if FE_DEBUG >= 3
499 1.1 mycroft log(LOG_INFO, "%s: after init hook\n", sc->sc_dev.dv_xname);
500 1.21 enami mb86960_dump(LOG_INFO, sc);
501 1.1 mycroft #endif
502 1.1 mycroft
503 1.1 mycroft /*
504 1.1 mycroft * Make sure to disable the chip, also.
505 1.1 mycroft * This may also help re-programming the chip after
506 1.1 mycroft * hot insertion of PCMCIAs.
507 1.1 mycroft */
508 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
509 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
510 1.21 enami delay(200);
511 1.1 mycroft
512 1.1 mycroft /* Power up the chip and select register bank for DLCRs. */
513 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
514 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_DLCR | FE_D7_POWER_UP);
515 1.1 mycroft delay(200);
516 1.1 mycroft
517 1.1 mycroft /* Feed the station address. */
518 1.21 enami bus_space_write_region_1(bst, bsh, FE_DLCR8,
519 1.21 enami sc->sc_enaddr, ETHER_ADDR_LEN);
520 1.1 mycroft
521 1.1 mycroft /* Select the BMPR bank for runtime register access. */
522 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
523 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP);
524 1.1 mycroft
525 1.1 mycroft /* Initialize registers. */
526 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF); /* Clear all bits. */
527 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF); /* ditto. */
528 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0x00);
529 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0x00);
530 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR4, sc->proto_dlcr4);
531 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR5, sc->proto_dlcr5);
532 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR10, 0x00);
533 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR11, FE_B11_CTRL_SKIP);
534 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR12, 0x00);
535 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR13, sc->proto_bmpr13);
536 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR14, FE_B14_FILTER);
537 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR15, 0x00);
538 1.1 mycroft
539 1.1 mycroft #if FE_DEBUG >= 3
540 1.1 mycroft log(LOG_INFO, "%s: just before enabling DLC\n", sc->sc_dev.dv_xname);
541 1.21 enami mb86960_dump(LOG_INFO, sc);
542 1.1 mycroft #endif
543 1.1 mycroft
544 1.1 mycroft /* Enable interrupts. */
545 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, FE_TMASK);
546 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, FE_RMASK);
547 1.1 mycroft
548 1.1 mycroft /* Enable transmitter and receiver. */
549 1.1 mycroft delay(200);
550 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
551 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_ENABLE);
552 1.1 mycroft delay(200);
553 1.1 mycroft
554 1.1 mycroft #if FE_DEBUG >= 3
555 1.1 mycroft log(LOG_INFO, "%s: just after enabling DLC\n", sc->sc_dev.dv_xname);
556 1.21 enami mb86960_dump(LOG_INFO, sc);
557 1.1 mycroft #endif
558 1.1 mycroft
559 1.1 mycroft /*
560 1.1 mycroft * Make sure to empty the receive buffer.
561 1.1 mycroft *
562 1.1 mycroft * This may be redundant, but *if* the receive buffer were full
563 1.1 mycroft * at this point, the driver would hang. I have experienced
564 1.1 mycroft * some strange hangups just after UP. I hope the following
565 1.1 mycroft * code solve the problem.
566 1.1 mycroft *
567 1.1 mycroft * I have changed the order of hardware initialization.
568 1.1 mycroft * I think the receive buffer cannot have any packets at this
569 1.1 mycroft * point in this version. The following code *must* be
570 1.1 mycroft * redundant now. FIXME.
571 1.1 mycroft */
572 1.1 mycroft for (i = 0; i < FE_MAX_RECV_COUNT; i++) {
573 1.21 enami if (bus_space_read_1(bst, bsh, FE_DLCR5) & FE_D5_BUFEMP)
574 1.1 mycroft break;
575 1.21 enami mb86960_droppacket(sc);
576 1.1 mycroft }
577 1.1 mycroft #if FE_DEBUG >= 1
578 1.21 enami if (i >= FE_MAX_RECV_COUNT)
579 1.1 mycroft log(LOG_ERR, "%s: cannot empty receive buffer\n",
580 1.1 mycroft sc->sc_dev.dv_xname);
581 1.1 mycroft #endif
582 1.1 mycroft #if FE_DEBUG >= 3
583 1.21 enami if (i < FE_MAX_RECV_COUNT)
584 1.1 mycroft log(LOG_INFO, "%s: receive buffer emptied (%d)\n",
585 1.1 mycroft sc->sc_dev.dv_xname, i);
586 1.1 mycroft #endif
587 1.1 mycroft
588 1.1 mycroft #if FE_DEBUG >= 3
589 1.1 mycroft log(LOG_INFO, "%s: after ERB loop\n", sc->sc_dev.dv_xname);
590 1.21 enami mb86960_dump(LOG_INFO, sc);
591 1.1 mycroft #endif
592 1.1 mycroft
593 1.1 mycroft /* Do we need this here? */
594 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF); /* Clear all bits. */
595 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF); /* ditto. */
596 1.1 mycroft
597 1.1 mycroft #if FE_DEBUG >= 3
598 1.1 mycroft log(LOG_INFO, "%s: after FIXME\n", sc->sc_dev.dv_xname);
599 1.21 enami mb86960_dump(LOG_INFO, sc);
600 1.1 mycroft #endif
601 1.1 mycroft
602 1.1 mycroft /* Set 'running' flag. */
603 1.1 mycroft ifp->if_flags |= IFF_RUNNING;
604 1.1 mycroft
605 1.1 mycroft /*
606 1.1 mycroft * At this point, the interface is runnung properly,
607 1.1 mycroft * except that it receives *no* packets. we then call
608 1.21 enami * mb86960_setmode() to tell the chip what packets to be
609 1.1 mycroft * received, based on the if_flags and multicast group
610 1.1 mycroft * list. It completes the initialization process.
611 1.1 mycroft */
612 1.21 enami mb86960_setmode(sc);
613 1.1 mycroft
614 1.1 mycroft #if FE_DEBUG >= 3
615 1.1 mycroft log(LOG_INFO, "%s: after setmode\n", sc->sc_dev.dv_xname);
616 1.21 enami mb86960_dump(LOG_INFO, sc);
617 1.1 mycroft #endif
618 1.1 mycroft
619 1.1 mycroft /* ...and attempt to start output. */
620 1.21 enami mb86960_start(ifp);
621 1.1 mycroft
622 1.1 mycroft #if FE_DEBUG >= 3
623 1.21 enami log(LOG_INFO, "%s: end of mb86960_init()\n", sc->sc_dev.dv_xname);
624 1.21 enami mb86960_dump(LOG_INFO, sc);
625 1.1 mycroft #endif
626 1.1 mycroft }
627 1.1 mycroft
628 1.1 mycroft /*
629 1.1 mycroft * This routine actually starts the transmission on the interface
630 1.1 mycroft */
631 1.21 enami static __inline__ void
632 1.21 enami mb86960_xmit(sc)
633 1.21 enami struct mb86960_softc *sc;
634 1.1 mycroft {
635 1.21 enami bus_space_tag_t bst = sc->sc_bst;
636 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
637 1.1 mycroft
638 1.1 mycroft /*
639 1.1 mycroft * Set a timer just in case we never hear from the board again.
640 1.1 mycroft * We use longer timeout for multiple packet transmission.
641 1.1 mycroft * I'm not sure this timer value is appropriate. FIXME.
642 1.1 mycroft */
643 1.21 enami sc->sc_ec.ec_if.if_timer = 1 + sc->txb_count;
644 1.1 mycroft
645 1.1 mycroft /* Update txb variables. */
646 1.1 mycroft sc->txb_sched = sc->txb_count;
647 1.1 mycroft sc->txb_count = 0;
648 1.1 mycroft sc->txb_free = sc->txb_size;
649 1.1 mycroft
650 1.1 mycroft #if FE_DELAYED_PADDING
651 1.1 mycroft /* Omit the postponed padding process. */
652 1.1 mycroft sc->txb_padding = 0;
653 1.1 mycroft #endif
654 1.1 mycroft
655 1.1 mycroft /* Start transmitter, passing packets in TX buffer. */
656 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR10, sc->txb_sched | FE_B10_START);
657 1.1 mycroft }
658 1.1 mycroft
659 1.1 mycroft /*
660 1.1 mycroft * Start output on interface.
661 1.1 mycroft * We make two assumptions here:
662 1.8 mycroft * 1) that the current priority is set to splnet _before_ this code
663 1.1 mycroft * is called *and* is returned to the appropriate priority after
664 1.1 mycroft * return
665 1.1 mycroft * 2) that the IFF_OACTIVE flag is checked before this code is called
666 1.1 mycroft * (i.e. that the output part of the interface is idle)
667 1.1 mycroft */
668 1.1 mycroft void
669 1.21 enami mb86960_start(ifp)
670 1.1 mycroft struct ifnet *ifp;
671 1.1 mycroft {
672 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
673 1.1 mycroft struct mbuf *m;
674 1.1 mycroft
675 1.1 mycroft #if FE_DEBUG >= 1
676 1.1 mycroft /* Just a sanity check. */
677 1.1 mycroft if ((sc->txb_count == 0) != (sc->txb_free == sc->txb_size)) {
678 1.1 mycroft /*
679 1.1 mycroft * Txb_count and txb_free co-works to manage the
680 1.1 mycroft * transmission buffer. Txb_count keeps track of the
681 1.1 mycroft * used potion of the buffer, while txb_free does unused
682 1.1 mycroft * potion. So, as long as the driver runs properly,
683 1.1 mycroft * txb_count is zero if and only if txb_free is same
684 1.1 mycroft * as txb_size (which represents whole buffer.)
685 1.1 mycroft */
686 1.1 mycroft log(LOG_ERR, "%s: inconsistent txb variables (%d, %d)\n",
687 1.1 mycroft sc->sc_dev.dv_xname, sc->txb_count, sc->txb_free);
688 1.1 mycroft /*
689 1.1 mycroft * So, what should I do, then?
690 1.1 mycroft *
691 1.1 mycroft * We now know txb_count and txb_free contradicts. We
692 1.1 mycroft * cannot, however, tell which is wrong. More
693 1.1 mycroft * over, we cannot peek 86960 transmission buffer or
694 1.1 mycroft * reset the transmission buffer. (In fact, we can
695 1.1 mycroft * reset the entire interface. I don't want to do it.)
696 1.1 mycroft *
697 1.1 mycroft * If txb_count is incorrect, leaving it as is will cause
698 1.1 mycroft * sending of gabages after next interrupt. We have to
699 1.1 mycroft * avoid it. Hence, we reset the txb_count here. If
700 1.1 mycroft * txb_free was incorrect, resetting txb_count just loose
701 1.1 mycroft * some packets. We can live with it.
702 1.1 mycroft */
703 1.1 mycroft sc->txb_count = 0;
704 1.1 mycroft }
705 1.1 mycroft #endif
706 1.1 mycroft
707 1.1 mycroft #if FE_DEBUG >= 1
708 1.1 mycroft /*
709 1.1 mycroft * First, see if there are buffered packets and an idle
710 1.1 mycroft * transmitter - should never happen at this point.
711 1.1 mycroft */
712 1.1 mycroft if ((sc->txb_count > 0) && (sc->txb_sched == 0)) {
713 1.1 mycroft log(LOG_ERR, "%s: transmitter idle with %d buffered packets\n",
714 1.1 mycroft sc->sc_dev.dv_xname, sc->txb_count);
715 1.21 enami mb86960_xmit(sc);
716 1.1 mycroft }
717 1.1 mycroft #endif
718 1.1 mycroft
719 1.1 mycroft /*
720 1.1 mycroft * Stop accepting more transmission packets temporarily, when
721 1.1 mycroft * a filter change request is delayed. Updating the MARs on
722 1.1 mycroft * 86960 flushes the transmisstion buffer, so it is delayed
723 1.1 mycroft * until all buffered transmission packets have been sent
724 1.1 mycroft * out.
725 1.1 mycroft */
726 1.1 mycroft if (sc->filter_change) {
727 1.1 mycroft /*
728 1.1 mycroft * Filter change requst is delayed only when the DLC is
729 1.1 mycroft * working. DLC soon raise an interrupt after finishing
730 1.1 mycroft * the work.
731 1.1 mycroft */
732 1.1 mycroft goto indicate_active;
733 1.1 mycroft }
734 1.1 mycroft
735 1.1 mycroft for (;;) {
736 1.1 mycroft /*
737 1.1 mycroft * See if there is room to put another packet in the buffer.
738 1.1 mycroft * We *could* do better job by peeking the send queue to
739 1.1 mycroft * know the length of the next packet. Current version just
740 1.1 mycroft * tests against the worst case (i.e., longest packet). FIXME.
741 1.1 mycroft *
742 1.1 mycroft * When adding the packet-peek feature, don't forget adding a
743 1.1 mycroft * test on txb_count against QUEUEING_MAX.
744 1.1 mycroft * There is a little chance the packet count exceeds
745 1.1 mycroft * the limit. Assume transmission buffer is 8KB (2x8KB
746 1.1 mycroft * configuration) and an application sends a bunch of small
747 1.1 mycroft * (i.e., minimum packet sized) packets rapidly. An 8KB
748 1.1 mycroft * buffer can hold 130 blocks of 62 bytes long...
749 1.1 mycroft */
750 1.32 thorpej if (sc->txb_free <
751 1.32 thorpej (ETHER_MAX_LEN - ETHER_CRC_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.32 thorpej if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN) ||
1039 1.32 thorpej len < ETHER_HDR_LEN) {
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.32 thorpej len < ETHER_HDR_LEN ? "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.32 thorpej if (len < (ETHER_MIN_LEN - ETHER_CRC_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.30 thorpej } else if ((ifp->if_flags & IFF_UP) != 0) {
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.29 pk bus_space_read_multi_2(bst, bsh, FE_BMPR8, mtod(m, u_int16_t *),
1368 1.29 pk (len + 1) >> 1);
1369 1.1 mycroft
1370 1.1 mycroft #if NBPFILTER > 0
1371 1.1 mycroft /*
1372 1.1 mycroft * Check if there's a BPF listener on this interface. If so, hand off
1373 1.1 mycroft * the raw packet to bpf.
1374 1.1 mycroft */
1375 1.1 mycroft if (ifp->if_bpf) {
1376 1.1 mycroft bpf_mtap(ifp->if_bpf, m);
1377 1.1 mycroft
1378 1.1 mycroft /*
1379 1.1 mycroft * Note that the interface cannot be in promiscuous mode if
1380 1.1 mycroft * there are no BPF listeners. And if we are in promiscuous
1381 1.1 mycroft * mode, we have to check if this packet is really ours.
1382 1.1 mycroft */
1383 1.1 mycroft if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1384 1.1 mycroft (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
1385 1.17 is bcmp(eh->ether_dhost, sc->sc_enaddr,
1386 1.21 enami sizeof(eh->ether_dhost)) != 0) {
1387 1.1 mycroft m_freem(m);
1388 1.1 mycroft return (1);
1389 1.1 mycroft }
1390 1.1 mycroft }
1391 1.1 mycroft #endif
1392 1.1 mycroft
1393 1.32.4.1 thorpej (*ifp->if_input)(ifp, 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.32 thorpej if (totlen > (ETHER_MAX_LEN - ETHER_CRC_LEN) ||
1465 1.32 thorpej totlen < ETHER_HDR_LEN) {
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.32 thorpej totlen < ETHER_HDR_LEN ? "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.32 thorpej bus_space_write_2(bst, bsh, FE_BMPR8,
1483 1.32 thorpej max(totlen, (ETHER_MIN_LEN - ETHER_CRC_LEN)));
1484 1.1 mycroft
1485 1.1 mycroft /*
1486 1.1 mycroft * Update buffer status now.
1487 1.1 mycroft * Truncate the length up to an even number, since we use outw().
1488 1.1 mycroft */
1489 1.1 mycroft totlen = (totlen + 1) & ~1;
1490 1.32 thorpej sc->txb_free -= FE_DATA_LEN_LEN +
1491 1.32 thorpej max(totlen, (ETHER_MIN_LEN - ETHER_CRC_LEN));
1492 1.1 mycroft sc->txb_count++;
1493 1.1 mycroft
1494 1.1 mycroft #if FE_DELAYED_PADDING
1495 1.1 mycroft /* Postpone the packet padding if necessary. */
1496 1.32 thorpej if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN))
1497 1.32 thorpej sc->txb_padding = (ETHER_MIN_LEN - ETHER_CRC_LEN) - totlen;
1498 1.1 mycroft #endif
1499 1.1 mycroft
1500 1.1 mycroft /*
1501 1.1 mycroft * Transfer the data from mbuf chain to the transmission buffer.
1502 1.1 mycroft * MB86960 seems to require that data be transferred as words, and
1503 1.1 mycroft * only words. So that we require some extra code to patch
1504 1.1 mycroft * over odd-length mbufs.
1505 1.1 mycroft */
1506 1.1 mycroft wantbyte = 0;
1507 1.1 mycroft for (; m != 0; m = m->m_next) {
1508 1.1 mycroft /* Ignore empty mbuf. */
1509 1.1 mycroft len = m->m_len;
1510 1.1 mycroft if (len == 0)
1511 1.1 mycroft continue;
1512 1.1 mycroft
1513 1.1 mycroft /* Find the actual data to send. */
1514 1.1 mycroft data = mtod(m, caddr_t);
1515 1.1 mycroft
1516 1.1 mycroft /* Finish the last byte. */
1517 1.1 mycroft if (wantbyte) {
1518 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8,
1519 1.21 enami savebyte | (*data << 8));
1520 1.1 mycroft data++;
1521 1.1 mycroft len--;
1522 1.1 mycroft wantbyte = 0;
1523 1.1 mycroft }
1524 1.1 mycroft
1525 1.1 mycroft /* Output contiguous words. */
1526 1.1 mycroft if (len > 1)
1527 1.29 pk bus_space_write_multi_2(bst, bsh, FE_BMPR8,
1528 1.29 pk (u_int16_t *)data, len >> 1);
1529 1.1 mycroft
1530 1.1 mycroft /* Save remaining byte, if there is one. */
1531 1.1 mycroft if (len & 1) {
1532 1.1 mycroft data += len & ~1;
1533 1.1 mycroft savebyte = *data;
1534 1.1 mycroft wantbyte = 1;
1535 1.1 mycroft }
1536 1.1 mycroft }
1537 1.1 mycroft
1538 1.1 mycroft /* Spit the last byte, if the length is odd. */
1539 1.1 mycroft if (wantbyte)
1540 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, savebyte);
1541 1.1 mycroft
1542 1.1 mycroft #if ! FE_DELAYED_PADDING
1543 1.1 mycroft /*
1544 1.1 mycroft * Pad the packet to the minimum length if necessary.
1545 1.1 mycroft */
1546 1.32 thorpej len = ((ETHER_MIN_LEN - ETHER_CRC_LEN) >> 1) - (totlen >> 1);
1547 1.1 mycroft while (--len >= 0)
1548 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, 0);
1549 1.1 mycroft #endif
1550 1.1 mycroft }
1551 1.1 mycroft
1552 1.1 mycroft /*
1553 1.1 mycroft * Compute the multicast address filter from the
1554 1.1 mycroft * list of multicast addresses we need to listen to.
1555 1.1 mycroft */
1556 1.1 mycroft void
1557 1.21 enami mb86960_getmcaf(ec, af)
1558 1.17 is struct ethercom *ec;
1559 1.1 mycroft u_char *af;
1560 1.1 mycroft {
1561 1.17 is struct ifnet *ifp = &ec->ec_if;
1562 1.1 mycroft struct ether_multi *enm;
1563 1.22 mycroft register u_char *cp;
1564 1.23 mycroft register u_int32_t crc;
1565 1.24 mycroft static const u_int32_t crctab[] = {
1566 1.23 mycroft 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
1567 1.23 mycroft 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
1568 1.23 mycroft 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
1569 1.23 mycroft 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
1570 1.23 mycroft };
1571 1.23 mycroft register int len;
1572 1.1 mycroft struct ether_multistep step;
1573 1.1 mycroft
1574 1.1 mycroft /*
1575 1.1 mycroft * Set up multicast address filter by passing all multicast addresses
1576 1.1 mycroft * through a crc generator, and then using the high order 6 bits as an
1577 1.1 mycroft * index into the 64 bit logical address filter. The high order bit
1578 1.1 mycroft * selects the word, while the rest of the bits select the bit within
1579 1.1 mycroft * the word.
1580 1.1 mycroft */
1581 1.1 mycroft
1582 1.1 mycroft if ((ifp->if_flags & IFF_PROMISC) != 0)
1583 1.1 mycroft goto allmulti;
1584 1.1 mycroft
1585 1.1 mycroft af[0] = af[1] = af[2] = af[3] = af[4] = af[5] = af[6] = af[7] = 0x00;
1586 1.17 is ETHER_FIRST_MULTI(step, ec, enm);
1587 1.1 mycroft while (enm != NULL) {
1588 1.1 mycroft if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
1589 1.1 mycroft sizeof(enm->enm_addrlo)) != 0) {
1590 1.1 mycroft /*
1591 1.1 mycroft * We must listen to a range of multicast addresses.
1592 1.1 mycroft * For now, just accept all multicasts, rather than
1593 1.1 mycroft * trying to set only those filter bits needed to match
1594 1.1 mycroft * the range. (At this time, the only use of address
1595 1.1 mycroft * ranges is for IP multicast routing, for which the
1596 1.1 mycroft * range is big enough to require all bits set.)
1597 1.1 mycroft */
1598 1.1 mycroft goto allmulti;
1599 1.1 mycroft }
1600 1.1 mycroft
1601 1.1 mycroft cp = enm->enm_addrlo;
1602 1.1 mycroft crc = 0xffffffff;
1603 1.1 mycroft for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
1604 1.23 mycroft crc ^= *cp++;
1605 1.23 mycroft crc = (crc >> 4) ^ crctab[crc & 0xf];
1606 1.23 mycroft crc = (crc >> 4) ^ crctab[crc & 0xf];
1607 1.1 mycroft }
1608 1.1 mycroft /* Just want the 6 most significant bits. */
1609 1.1 mycroft crc >>= 26;
1610 1.1 mycroft
1611 1.1 mycroft /* Turn on the corresponding bit in the filter. */
1612 1.1 mycroft af[crc >> 3] |= 1 << (crc & 7);
1613 1.1 mycroft
1614 1.1 mycroft ETHER_NEXT_MULTI(step, enm);
1615 1.1 mycroft }
1616 1.1 mycroft ifp->if_flags &= ~IFF_ALLMULTI;
1617 1.1 mycroft return;
1618 1.1 mycroft
1619 1.1 mycroft allmulti:
1620 1.1 mycroft ifp->if_flags |= IFF_ALLMULTI;
1621 1.1 mycroft af[0] = af[1] = af[2] = af[3] = af[4] = af[5] = af[6] = af[7] = 0xff;
1622 1.1 mycroft }
1623 1.1 mycroft
1624 1.1 mycroft /*
1625 1.1 mycroft * Calculate a new "multicast packet filter" and put the 86960
1626 1.1 mycroft * receiver in appropriate mode.
1627 1.1 mycroft */
1628 1.1 mycroft void
1629 1.21 enami mb86960_setmode(sc)
1630 1.21 enami struct mb86960_softc *sc;
1631 1.1 mycroft {
1632 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1633 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1634 1.21 enami int flags = sc->sc_ec.ec_if.if_flags;
1635 1.1 mycroft
1636 1.1 mycroft /*
1637 1.1 mycroft * If the interface is not running, we postpone the update
1638 1.1 mycroft * process for receive modes and multicast address filter
1639 1.1 mycroft * until the interface is restarted. It reduces some
1640 1.1 mycroft * complicated job on maintaining chip states. (Earlier versions
1641 1.1 mycroft * of this driver had a bug on that point...)
1642 1.1 mycroft *
1643 1.21 enami * To complete the trick, mb86960_init() calls mb86960_setmode() after
1644 1.1 mycroft * restarting the interface.
1645 1.1 mycroft */
1646 1.1 mycroft if ((flags & IFF_RUNNING) == 0)
1647 1.1 mycroft return;
1648 1.1 mycroft
1649 1.1 mycroft /*
1650 1.1 mycroft * Promiscuous mode is handled separately.
1651 1.1 mycroft */
1652 1.1 mycroft if ((flags & IFF_PROMISC) != 0) {
1653 1.1 mycroft /*
1654 1.1 mycroft * Program 86960 to receive all packets on the segment
1655 1.1 mycroft * including those directed to other stations.
1656 1.1 mycroft * Multicast filter stored in MARs are ignored
1657 1.1 mycroft * under this setting, so we don't need to update it.
1658 1.1 mycroft *
1659 1.6 mycroft * Promiscuous mode is used solely by BPF, and BPF only
1660 1.6 mycroft * listens to valid (no error) packets. So, we ignore
1661 1.6 mycroft * errornous ones even in this mode.
1662 1.1 mycroft */
1663 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR5,
1664 1.1 mycroft sc->proto_dlcr5 | FE_D5_AFM0 | FE_D5_AFM1);
1665 1.1 mycroft sc->filter_change = 0;
1666 1.1 mycroft
1667 1.1 mycroft #if FE_DEBUG >= 3
1668 1.1 mycroft log(LOG_INFO, "%s: promiscuous mode\n", sc->sc_dev.dv_xname);
1669 1.1 mycroft #endif
1670 1.1 mycroft return;
1671 1.1 mycroft }
1672 1.1 mycroft
1673 1.1 mycroft /*
1674 1.1 mycroft * Turn the chip to the normal (non-promiscuous) mode.
1675 1.1 mycroft */
1676 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR5, sc->proto_dlcr5 | FE_D5_AFM1);
1677 1.1 mycroft
1678 1.1 mycroft /*
1679 1.1 mycroft * Find the new multicast filter value.
1680 1.1 mycroft */
1681 1.21 enami mb86960_getmcaf(&sc->sc_ec, sc->filter);
1682 1.1 mycroft sc->filter_change = 1;
1683 1.1 mycroft
1684 1.1 mycroft #if FE_DEBUG >= 3
1685 1.1 mycroft log(LOG_INFO,
1686 1.1 mycroft "%s: address filter: [%02x %02x %02x %02x %02x %02x %02x %02x]\n",
1687 1.1 mycroft sc->sc_dev.dv_xname,
1688 1.1 mycroft sc->filter[0], sc->filter[1], sc->filter[2], sc->filter[3],
1689 1.1 mycroft sc->filter[4], sc->filter[5], sc->filter[6], sc->filter[7]);
1690 1.1 mycroft #endif
1691 1.1 mycroft
1692 1.1 mycroft /*
1693 1.1 mycroft * We have to update the multicast filter in the 86960, A.S.A.P.
1694 1.1 mycroft *
1695 1.1 mycroft * Note that the DLC (Data Linc Control unit, i.e. transmitter
1696 1.1 mycroft * and receiver) must be stopped when feeding the filter, and
1697 1.1 mycroft * DLC trushes all packets in both transmission and receive
1698 1.1 mycroft * buffers when stopped.
1699 1.1 mycroft *
1700 1.1 mycroft * ... Are the above sentenses correct? I have to check the
1701 1.1 mycroft * manual of the MB86960A. FIXME.
1702 1.1 mycroft *
1703 1.1 mycroft * To reduce the packet lossage, we delay the filter update
1704 1.1 mycroft * process until buffers are empty.
1705 1.1 mycroft */
1706 1.1 mycroft if (sc->txb_sched == 0 && sc->txb_count == 0 &&
1707 1.21 enami (bus_space_read_1(bst, bsh, FE_DLCR1) & FE_D1_PKTRDY) == 0) {
1708 1.1 mycroft /*
1709 1.1 mycroft * Buffers are (apparently) empty. Load
1710 1.1 mycroft * the new filter value into MARs now.
1711 1.1 mycroft */
1712 1.21 enami mb86960_loadmar(sc);
1713 1.1 mycroft } else {
1714 1.1 mycroft /*
1715 1.1 mycroft * Buffers are not empty. Mark that we have to update
1716 1.21 enami * the MARs. The new filter will be loaded by mb86960_intr()
1717 1.1 mycroft * later.
1718 1.1 mycroft */
1719 1.1 mycroft #if FE_DEBUG >= 4
1720 1.21 enami log(LOG_INFO, "%s: filter change delayed\n",
1721 1.21 enami sc->sc_dev.dv_xname);
1722 1.1 mycroft #endif
1723 1.1 mycroft }
1724 1.1 mycroft }
1725 1.1 mycroft
1726 1.1 mycroft /*
1727 1.1 mycroft * Load a new multicast address filter into MARs.
1728 1.1 mycroft *
1729 1.21 enami * The caller must have splnet'ed befor mb86960_loadmar.
1730 1.1 mycroft * This function starts the DLC upon return. So it can be called only
1731 1.1 mycroft * when the chip is working, i.e., from the driver's point of view, when
1732 1.1 mycroft * a device is RUNNING. (I mistook the point in previous versions.)
1733 1.1 mycroft */
1734 1.1 mycroft void
1735 1.21 enami mb86960_loadmar(sc)
1736 1.21 enami struct mb86960_softc *sc;
1737 1.1 mycroft {
1738 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1739 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1740 1.1 mycroft
1741 1.1 mycroft /* Stop the DLC (transmitter and receiver). */
1742 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
1743 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
1744 1.1 mycroft
1745 1.1 mycroft /* Select register bank 1 for MARs. */
1746 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1747 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP);
1748 1.1 mycroft
1749 1.1 mycroft /* Copy filter value into the registers. */
1750 1.21 enami bus_space_write_region_1(bst, bsh, FE_MAR8, sc->filter, FE_FILTER_LEN);
1751 1.1 mycroft
1752 1.1 mycroft /* Restore the bank selection for BMPRs (i.e., runtime registers). */
1753 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1754 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP);
1755 1.1 mycroft
1756 1.1 mycroft /* Restart the DLC. */
1757 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
1758 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_ENABLE);
1759 1.1 mycroft
1760 1.1 mycroft /* We have just updated the filter. */
1761 1.1 mycroft sc->filter_change = 0;
1762 1.1 mycroft
1763 1.1 mycroft #if FE_DEBUG >= 3
1764 1.1 mycroft log(LOG_INFO, "%s: address filter changed\n", sc->sc_dev.dv_xname);
1765 1.1 mycroft #endif
1766 1.1 mycroft }
1767 1.1 mycroft
1768 1.21 enami /*
1769 1.21 enami * Enable power on the interface.
1770 1.21 enami */
1771 1.21 enami int
1772 1.21 enami mb86960_enable(sc)
1773 1.21 enami struct mb86960_softc *sc;
1774 1.21 enami {
1775 1.21 enami
1776 1.21 enami #if FE_DEBUG >= 3
1777 1.21 enami log(LOG_INFO, "%s: mb86960_enable()\n", sc->sc_dev.dv_xname);
1778 1.21 enami #endif
1779 1.21 enami
1780 1.21 enami if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
1781 1.21 enami if ((*sc->sc_enable)(sc) != 0) {
1782 1.21 enami printf("%s: device enable failed\n",
1783 1.21 enami sc->sc_dev.dv_xname);
1784 1.21 enami return (EIO);
1785 1.21 enami }
1786 1.21 enami }
1787 1.21 enami
1788 1.21 enami sc->sc_enabled = 1;
1789 1.21 enami return (0);
1790 1.21 enami }
1791 1.21 enami
1792 1.21 enami /*
1793 1.21 enami * Disable power on the interface.
1794 1.21 enami */
1795 1.21 enami void
1796 1.21 enami mb86960_disable(sc)
1797 1.21 enami struct mb86960_softc *sc;
1798 1.21 enami {
1799 1.21 enami
1800 1.21 enami #if FE_DEBUG >= 3
1801 1.21 enami log(LOG_INFO, "%s: mb86960_disable()\n", sc->sc_dev.dv_xname);
1802 1.21 enami #endif
1803 1.21 enami
1804 1.21 enami if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
1805 1.21 enami (*sc->sc_disable)(sc);
1806 1.21 enami sc->sc_enabled = 0;
1807 1.21 enami }
1808 1.28 thorpej }
1809 1.28 thorpej
1810 1.28 thorpej int
1811 1.28 thorpej mb86960_activate(self, act)
1812 1.28 thorpej struct device *self;
1813 1.28 thorpej enum devact act;
1814 1.28 thorpej {
1815 1.28 thorpej struct mb86960_softc *sc = (struct mb86960_softc *)self;
1816 1.28 thorpej int rv = 0, s;
1817 1.28 thorpej
1818 1.28 thorpej s = splnet();
1819 1.28 thorpej switch (act) {
1820 1.28 thorpej case DVACT_ACTIVATE:
1821 1.28 thorpej rv = EOPNOTSUPP;
1822 1.28 thorpej break;
1823 1.28 thorpej
1824 1.28 thorpej case DVACT_DEACTIVATE:
1825 1.28 thorpej #ifdef notyet
1826 1.28 thorpej /* First, kill off the interface. */
1827 1.28 thorpej if_detach(sc->sc_ec.ec_if);
1828 1.28 thorpej #endif
1829 1.28 thorpej
1830 1.28 thorpej /* Now disable the interface. */
1831 1.28 thorpej mb86960_disable(sc);
1832 1.28 thorpej break;
1833 1.28 thorpej }
1834 1.28 thorpej splx(s);
1835 1.28 thorpej return (rv);
1836 1.21 enami }
1837 1.21 enami
1838 1.1 mycroft #if FE_DEBUG >= 1
1839 1.1 mycroft void
1840 1.21 enami mb86960_dump(level, sc)
1841 1.1 mycroft int level;
1842 1.21 enami struct mb86960_softc *sc;
1843 1.1 mycroft {
1844 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1845 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1846 1.1 mycroft u_char save_dlcr7;
1847 1.1 mycroft
1848 1.21 enami save_dlcr7 = bus_space_read_1(bst, bsh, FE_DLCR7);
1849 1.1 mycroft
1850 1.21 enami log(level, "\tDLCR = %02x %02x %02x %02x %02x %02x %02x %02x\n",
1851 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR0),
1852 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR1),
1853 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR2),
1854 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR3),
1855 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR4),
1856 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR5),
1857 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR6),
1858 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR7));
1859 1.21 enami
1860 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1861 1.21 enami (save_dlcr7 & ~FE_D7_RBS) | FE_D7_RBS_DLCR);
1862 1.21 enami log(level, "\t %02x %02x %02x %02x %02x %02x %02x %02x\n",
1863 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR8),
1864 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR9),
1865 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR10),
1866 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR11),
1867 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR12),
1868 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR13),
1869 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR14),
1870 1.21 enami bus_space_read_1(bst, bsh, FE_DLCR15));
1871 1.21 enami
1872 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1873 1.21 enami (save_dlcr7 & ~FE_D7_RBS) | FE_D7_RBS_MAR);
1874 1.21 enami log(level, "\tMAR = %02x %02x %02x %02x %02x %02x %02x %02x\n",
1875 1.21 enami bus_space_read_1(bst, bsh, FE_MAR8),
1876 1.21 enami bus_space_read_1(bst, bsh, FE_MAR9),
1877 1.21 enami bus_space_read_1(bst, bsh, FE_MAR10),
1878 1.21 enami bus_space_read_1(bst, bsh, FE_MAR11),
1879 1.21 enami bus_space_read_1(bst, bsh, FE_MAR12),
1880 1.21 enami bus_space_read_1(bst, bsh, FE_MAR13),
1881 1.21 enami bus_space_read_1(bst, bsh, FE_MAR14),
1882 1.21 enami bus_space_read_1(bst, bsh, FE_MAR15));
1883 1.21 enami
1884 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
1885 1.21 enami (save_dlcr7 & ~FE_D7_RBS) | FE_D7_RBS_BMPR);
1886 1.21 enami log(level,
1887 1.21 enami "\tBMPR = xx xx %02x %02x %02x %02x %02x %02x %02x %02x xx %02x\n",
1888 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR10),
1889 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR11),
1890 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR12),
1891 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR13),
1892 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR14),
1893 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR15),
1894 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR16),
1895 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR17),
1896 1.21 enami bus_space_read_1(bst, bsh, FE_BMPR19));
1897 1.1 mycroft
1898 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7, save_dlcr7);
1899 1.1 mycroft }
1900 1.1 mycroft #endif
1901