mb86960.c revision 1.29.2.1 1 1.29.2.1 kenh /* $NetBSD: mb86960.c,v 1.29.2.1 1998/12/11 04:52:59 kenh 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.29.2.1 kenh struct ifnet *ifp;
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.29.2.1 kenh ifp = if_alloc();
202 1.29.2.1 kenh ifp->if_ifcom = &sc->sc_ec;
203 1.29.2.1 kenh sc->sc_ec.ec_if = ifp;
204 1.12 thorpej bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
205 1.12 thorpej ifp->if_softc = sc;
206 1.21 enami ifp->if_start = mb86960_start;
207 1.21 enami ifp->if_ioctl = mb86960_ioctl;
208 1.21 enami ifp->if_watchdog = mb86960_watchdog;
209 1.6 mycroft ifp->if_flags =
210 1.6 mycroft IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
211 1.1 mycroft
212 1.1 mycroft #if FE_DEBUG >= 3
213 1.21 enami log(LOG_INFO, "%s: mb86960_config()\n", sc->sc_dev.dv_xname);
214 1.21 enami mb86960_dump(LOG_INFO, sc);
215 1.1 mycroft #endif
216 1.1 mycroft
217 1.1 mycroft #if FE_SINGLE_TRANSMISSION
218 1.1 mycroft /* Override txb config to allocate minimum. */
219 1.1 mycroft sc->proto_dlcr6 &= ~FE_D6_TXBSIZ
220 1.1 mycroft sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
221 1.1 mycroft #endif
222 1.1 mycroft
223 1.1 mycroft /* Modify hardware config if it is requested. */
224 1.1 mycroft if ((cf->cf_flags & FE_FLAGS_OVERRIDE_DLCR6) != 0)
225 1.1 mycroft sc->proto_dlcr6 = cf->cf_flags & FE_FLAGS_DLCR6_VALUE;
226 1.1 mycroft
227 1.1 mycroft /* Find TX buffer size, based on the hardware dependent proto. */
228 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) {
229 1.1 mycroft case FE_D6_TXBSIZ_2x2KB:
230 1.1 mycroft sc->txb_size = 2048;
231 1.1 mycroft break;
232 1.1 mycroft case FE_D6_TXBSIZ_2x4KB:
233 1.1 mycroft sc->txb_size = 4096;
234 1.1 mycroft break;
235 1.1 mycroft case FE_D6_TXBSIZ_2x8KB:
236 1.1 mycroft sc->txb_size = 8192;
237 1.1 mycroft break;
238 1.1 mycroft default:
239 1.1 mycroft /* Oops, we can't work with single buffer configuration. */
240 1.1 mycroft #if FE_DEBUG >= 2
241 1.1 mycroft log(LOG_WARNING, "%s: strange TXBSIZ config; fixing\n",
242 1.1 mycroft sc->sc_dev.dv_xname);
243 1.1 mycroft #endif
244 1.1 mycroft sc->proto_dlcr6 &= ~FE_D6_TXBSIZ;
245 1.1 mycroft sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
246 1.1 mycroft sc->txb_size = 2048;
247 1.1 mycroft break;
248 1.1 mycroft }
249 1.1 mycroft
250 1.21 enami /* Initialize media goo. */
251 1.21 enami ifmedia_init(&sc->sc_media, 0, mb86960_mediachange,
252 1.21 enami mb86960_mediastatus);
253 1.21 enami if (media != NULL) {
254 1.21 enami for (i = 0; i < nmedia; i++)
255 1.21 enami ifmedia_add(&sc->sc_media, media[i], 0, NULL);
256 1.21 enami ifmedia_set(&sc->sc_media, defmedia);
257 1.21 enami } else {
258 1.21 enami ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
259 1.21 enami ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
260 1.21 enami }
261 1.21 enami
262 1.1 mycroft /* Attach the interface. */
263 1.1 mycroft if_attach(ifp);
264 1.17 is ether_ifattach(ifp, sc->sc_enaddr);
265 1.1 mycroft
266 1.21 enami #if NBPFILTER > 0
267 1.21 enami /* If BPF is in the kernel, call the attach for it. */
268 1.21 enami bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
269 1.21 enami #endif
270 1.21 enami #if NRND > 0
271 1.21 enami rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
272 1.21 enami RND_TYPE_NET);
273 1.21 enami #endif
274 1.1 mycroft /* Print additional info when attached. */
275 1.21 enami printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
276 1.21 enami ether_sprintf(sc->sc_enaddr));
277 1.21 enami
278 1.1 mycroft #if FE_DEBUG >= 3
279 1.1 mycroft {
280 1.1 mycroft int buf, txb, bbw, sbw, ram;
281 1.1 mycroft
282 1.1 mycroft buf = txb = bbw = sbw = ram = -1;
283 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_BUFSIZ) {
284 1.1 mycroft case FE_D6_BUFSIZ_8KB:
285 1.1 mycroft buf = 8;
286 1.1 mycroft break;
287 1.1 mycroft case FE_D6_BUFSIZ_16KB:
288 1.1 mycroft buf = 16;
289 1.1 mycroft break;
290 1.1 mycroft case FE_D6_BUFSIZ_32KB:
291 1.1 mycroft buf = 32;
292 1.1 mycroft break;
293 1.1 mycroft case FE_D6_BUFSIZ_64KB:
294 1.1 mycroft buf = 64;
295 1.1 mycroft break;
296 1.1 mycroft }
297 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) {
298 1.1 mycroft case FE_D6_TXBSIZ_2x2KB:
299 1.1 mycroft txb = 2;
300 1.1 mycroft break;
301 1.1 mycroft case FE_D6_TXBSIZ_2x4KB:
302 1.1 mycroft txb = 4;
303 1.1 mycroft break;
304 1.1 mycroft case FE_D6_TXBSIZ_2x8KB:
305 1.1 mycroft txb = 8;
306 1.1 mycroft break;
307 1.1 mycroft }
308 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_BBW) {
309 1.1 mycroft case FE_D6_BBW_BYTE:
310 1.1 mycroft bbw = 8;
311 1.1 mycroft break;
312 1.1 mycroft case FE_D6_BBW_WORD:
313 1.1 mycroft bbw = 16;
314 1.1 mycroft break;
315 1.1 mycroft }
316 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_SBW) {
317 1.1 mycroft case FE_D6_SBW_BYTE:
318 1.1 mycroft sbw = 8;
319 1.1 mycroft break;
320 1.1 mycroft case FE_D6_SBW_WORD:
321 1.1 mycroft sbw = 16;
322 1.1 mycroft break;
323 1.1 mycroft }
324 1.1 mycroft switch (sc->proto_dlcr6 & FE_D6_SRAM) {
325 1.1 mycroft case FE_D6_SRAM_100ns:
326 1.1 mycroft ram = 100;
327 1.1 mycroft break;
328 1.1 mycroft case FE_D6_SRAM_150ns:
329 1.1 mycroft ram = 150;
330 1.1 mycroft break;
331 1.1 mycroft }
332 1.15 christos printf("%s: SRAM %dKB %dbit %dns, TXB %dKBx2, %dbit I/O\n",
333 1.1 mycroft sc->sc_dev.dv_xname, buf, bbw, ram, txb, sbw);
334 1.1 mycroft }
335 1.1 mycroft #endif
336 1.21 enami }
337 1.21 enami
338 1.21 enami /*
339 1.21 enami * Media change callback.
340 1.21 enami */
341 1.21 enami int
342 1.21 enami mb86960_mediachange(ifp)
343 1.21 enami struct ifnet *ifp;
344 1.21 enami {
345 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
346 1.1 mycroft
347 1.21 enami if (sc->sc_mediachange)
348 1.21 enami return ((*sc->sc_mediachange)(sc));
349 1.21 enami return (EINVAL);
350 1.21 enami }
351 1.1 mycroft
352 1.21 enami /*
353 1.21 enami * Media status callback.
354 1.21 enami */
355 1.21 enami void
356 1.21 enami mb86960_mediastatus(ifp, ifmr)
357 1.21 enami struct ifnet *ifp;
358 1.21 enami struct ifmediareq *ifmr;
359 1.21 enami {
360 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
361 1.18 explorer
362 1.21 enami if (sc->sc_enabled == 0) {
363 1.21 enami ifmr->ifm_active = IFM_ETHER | IFM_NONE;
364 1.21 enami ifmr->ifm_status = 0;
365 1.21 enami return;
366 1.21 enami }
367 1.21 enami
368 1.21 enami if (sc->sc_mediastatus)
369 1.21 enami (*sc->sc_mediastatus)(sc, ifmr);
370 1.1 mycroft }
371 1.1 mycroft
372 1.1 mycroft /*
373 1.1 mycroft * Reset interface.
374 1.1 mycroft */
375 1.1 mycroft void
376 1.21 enami mb86960_reset(sc)
377 1.21 enami struct mb86960_softc *sc;
378 1.1 mycroft {
379 1.1 mycroft int s;
380 1.1 mycroft
381 1.8 mycroft s = splnet();
382 1.21 enami mb86960_stop(sc);
383 1.21 enami mb86960_init(sc);
384 1.1 mycroft splx(s);
385 1.1 mycroft }
386 1.1 mycroft
387 1.1 mycroft /*
388 1.1 mycroft * Stop everything on the interface.
389 1.1 mycroft *
390 1.1 mycroft * All buffered packets, both transmitting and receiving,
391 1.1 mycroft * if any, will be lost by stopping the interface.
392 1.1 mycroft */
393 1.1 mycroft void
394 1.21 enami mb86960_stop(sc)
395 1.21 enami struct mb86960_softc *sc;
396 1.1 mycroft {
397 1.21 enami bus_space_tag_t bst = sc->sc_bst;
398 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
399 1.1 mycroft
400 1.1 mycroft #if FE_DEBUG >= 3
401 1.21 enami log(LOG_INFO, "%s: top of mb86960_stop()\n", sc->sc_dev.dv_xname);
402 1.21 enami mb86960_dump(LOG_INFO, sc);
403 1.1 mycroft #endif
404 1.1 mycroft
405 1.1 mycroft /* Disable interrupts. */
406 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0x00);
407 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0x00);
408 1.1 mycroft
409 1.1 mycroft /* Stop interface hardware. */
410 1.1 mycroft delay(200);
411 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
412 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
413 1.1 mycroft delay(200);
414 1.1 mycroft
415 1.1 mycroft /* Clear all interrupt status. */
416 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF);
417 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF);
418 1.1 mycroft
419 1.1 mycroft /* Put the chip in stand-by mode. */
420 1.1 mycroft delay(200);
421 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
422 1.21 enami sc->proto_dlcr7 | FE_D7_POWER_DOWN);
423 1.1 mycroft delay(200);
424 1.1 mycroft
425 1.1 mycroft /* MAR loading can be delayed. */
426 1.1 mycroft sc->filter_change = 0;
427 1.1 mycroft
428 1.1 mycroft /* Call a hook. */
429 1.21 enami if (sc->stop_card)
430 1.21 enami (*sc->stop_card)(sc);
431 1.1 mycroft
432 1.1 mycroft #if DEBUG >= 3
433 1.21 enami log(LOG_INFO, "%s: end of mb86960_stop()\n", sc->sc_dev.dv_xname);
434 1.21 enami mb86960_dump(LOG_INFO, sc);
435 1.1 mycroft #endif
436 1.1 mycroft }
437 1.1 mycroft
438 1.1 mycroft /*
439 1.1 mycroft * Device timeout/watchdog routine. Entered if the device neglects to
440 1.1 mycroft * generate an interrupt after a transmit has been started on it.
441 1.1 mycroft */
442 1.1 mycroft void
443 1.21 enami mb86960_watchdog(ifp)
444 1.12 thorpej struct ifnet *ifp;
445 1.1 mycroft {
446 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
447 1.1 mycroft
448 1.1 mycroft log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
449 1.1 mycroft #if FE_DEBUG >= 3
450 1.21 enami mb86960_dump(LOG_INFO, sc);
451 1.1 mycroft #endif
452 1.1 mycroft
453 1.1 mycroft /* Record how many packets are lost by this accident. */
454 1.29.2.1 kenh sc->sc_ec.ec_if->if_oerrors += sc->txb_sched + sc->txb_count;
455 1.1 mycroft
456 1.21 enami mb86960_reset(sc);
457 1.1 mycroft }
458 1.1 mycroft
459 1.1 mycroft /*
460 1.6 mycroft * Drop (skip) a packet from receive buffer in 86960 memory.
461 1.6 mycroft */
462 1.21 enami static __inline__ void
463 1.21 enami mb86960_droppacket(sc)
464 1.21 enami struct mb86960_softc *sc;
465 1.6 mycroft {
466 1.21 enami bus_space_tag_t bst = sc->sc_bst;
467 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
468 1.6 mycroft
469 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR14, FE_B14_FILTER | FE_B14_SKIP);
470 1.6 mycroft }
471 1.6 mycroft
472 1.6 mycroft /*
473 1.1 mycroft * Initialize device.
474 1.1 mycroft */
475 1.1 mycroft void
476 1.21 enami mb86960_init(sc)
477 1.21 enami struct mb86960_softc *sc;
478 1.1 mycroft {
479 1.21 enami bus_space_tag_t bst = sc->sc_bst;
480 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
481 1.29.2.1 kenh struct ifnet *ifp = sc->sc_ec.ec_if;
482 1.5 mycroft int i;
483 1.1 mycroft
484 1.1 mycroft #if FE_DEBUG >= 3
485 1.21 enami log(LOG_INFO, "%s: top of mb86960_init()\n", sc->sc_dev.dv_xname);
486 1.21 enami mb86960_dump(LOG_INFO, sc);
487 1.1 mycroft #endif
488 1.1 mycroft
489 1.1 mycroft /* Reset transmitter flags. */
490 1.1 mycroft ifp->if_flags &= ~IFF_OACTIVE;
491 1.1 mycroft ifp->if_timer = 0;
492 1.1 mycroft
493 1.1 mycroft sc->txb_free = sc->txb_size;
494 1.1 mycroft sc->txb_count = 0;
495 1.1 mycroft sc->txb_sched = 0;
496 1.1 mycroft
497 1.21 enami /* Do any card-specific initialization, if applicable. */
498 1.21 enami if (sc->init_card)
499 1.21 enami (*sc->init_card)(sc);
500 1.1 mycroft
501 1.1 mycroft #if FE_DEBUG >= 3
502 1.1 mycroft log(LOG_INFO, "%s: after init hook\n", sc->sc_dev.dv_xname);
503 1.21 enami mb86960_dump(LOG_INFO, sc);
504 1.1 mycroft #endif
505 1.1 mycroft
506 1.1 mycroft /*
507 1.1 mycroft * Make sure to disable the chip, also.
508 1.1 mycroft * This may also help re-programming the chip after
509 1.1 mycroft * hot insertion of PCMCIAs.
510 1.1 mycroft */
511 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
512 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
513 1.21 enami delay(200);
514 1.1 mycroft
515 1.1 mycroft /* Power up the chip and select register bank for DLCRs. */
516 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
517 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_DLCR | FE_D7_POWER_UP);
518 1.1 mycroft delay(200);
519 1.1 mycroft
520 1.1 mycroft /* Feed the station address. */
521 1.21 enami bus_space_write_region_1(bst, bsh, FE_DLCR8,
522 1.21 enami sc->sc_enaddr, ETHER_ADDR_LEN);
523 1.1 mycroft
524 1.1 mycroft /* Select the BMPR bank for runtime register access. */
525 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR7,
526 1.1 mycroft sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP);
527 1.1 mycroft
528 1.1 mycroft /* Initialize registers. */
529 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF); /* Clear all bits. */
530 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF); /* ditto. */
531 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, 0x00);
532 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, 0x00);
533 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR4, sc->proto_dlcr4);
534 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR5, sc->proto_dlcr5);
535 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR10, 0x00);
536 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR11, FE_B11_CTRL_SKIP);
537 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR12, 0x00);
538 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR13, sc->proto_bmpr13);
539 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR14, FE_B14_FILTER);
540 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR15, 0x00);
541 1.1 mycroft
542 1.1 mycroft #if FE_DEBUG >= 3
543 1.1 mycroft log(LOG_INFO, "%s: just before enabling DLC\n", sc->sc_dev.dv_xname);
544 1.21 enami mb86960_dump(LOG_INFO, sc);
545 1.1 mycroft #endif
546 1.1 mycroft
547 1.1 mycroft /* Enable interrupts. */
548 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR2, FE_TMASK);
549 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR3, FE_RMASK);
550 1.1 mycroft
551 1.1 mycroft /* Enable transmitter and receiver. */
552 1.1 mycroft delay(200);
553 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR6,
554 1.21 enami sc->proto_dlcr6 | FE_D6_DLC_ENABLE);
555 1.1 mycroft delay(200);
556 1.1 mycroft
557 1.1 mycroft #if FE_DEBUG >= 3
558 1.1 mycroft log(LOG_INFO, "%s: just after enabling DLC\n", sc->sc_dev.dv_xname);
559 1.21 enami mb86960_dump(LOG_INFO, sc);
560 1.1 mycroft #endif
561 1.1 mycroft
562 1.1 mycroft /*
563 1.1 mycroft * Make sure to empty the receive buffer.
564 1.1 mycroft *
565 1.1 mycroft * This may be redundant, but *if* the receive buffer were full
566 1.1 mycroft * at this point, the driver would hang. I have experienced
567 1.1 mycroft * some strange hangups just after UP. I hope the following
568 1.1 mycroft * code solve the problem.
569 1.1 mycroft *
570 1.1 mycroft * I have changed the order of hardware initialization.
571 1.1 mycroft * I think the receive buffer cannot have any packets at this
572 1.1 mycroft * point in this version. The following code *must* be
573 1.1 mycroft * redundant now. FIXME.
574 1.1 mycroft */
575 1.1 mycroft for (i = 0; i < FE_MAX_RECV_COUNT; i++) {
576 1.21 enami if (bus_space_read_1(bst, bsh, FE_DLCR5) & FE_D5_BUFEMP)
577 1.1 mycroft break;
578 1.21 enami mb86960_droppacket(sc);
579 1.1 mycroft }
580 1.1 mycroft #if FE_DEBUG >= 1
581 1.21 enami if (i >= FE_MAX_RECV_COUNT)
582 1.1 mycroft log(LOG_ERR, "%s: cannot empty receive buffer\n",
583 1.1 mycroft sc->sc_dev.dv_xname);
584 1.1 mycroft #endif
585 1.1 mycroft #if FE_DEBUG >= 3
586 1.21 enami if (i < FE_MAX_RECV_COUNT)
587 1.1 mycroft log(LOG_INFO, "%s: receive buffer emptied (%d)\n",
588 1.1 mycroft sc->sc_dev.dv_xname, i);
589 1.1 mycroft #endif
590 1.1 mycroft
591 1.1 mycroft #if FE_DEBUG >= 3
592 1.1 mycroft log(LOG_INFO, "%s: after ERB loop\n", sc->sc_dev.dv_xname);
593 1.21 enami mb86960_dump(LOG_INFO, sc);
594 1.1 mycroft #endif
595 1.1 mycroft
596 1.1 mycroft /* Do we need this here? */
597 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, 0xFF); /* Clear all bits. */
598 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, 0xFF); /* ditto. */
599 1.1 mycroft
600 1.1 mycroft #if FE_DEBUG >= 3
601 1.1 mycroft log(LOG_INFO, "%s: after FIXME\n", sc->sc_dev.dv_xname);
602 1.21 enami mb86960_dump(LOG_INFO, sc);
603 1.1 mycroft #endif
604 1.1 mycroft
605 1.1 mycroft /* Set 'running' flag. */
606 1.1 mycroft ifp->if_flags |= IFF_RUNNING;
607 1.1 mycroft
608 1.1 mycroft /*
609 1.1 mycroft * At this point, the interface is runnung properly,
610 1.1 mycroft * except that it receives *no* packets. we then call
611 1.21 enami * mb86960_setmode() to tell the chip what packets to be
612 1.1 mycroft * received, based on the if_flags and multicast group
613 1.1 mycroft * list. It completes the initialization process.
614 1.1 mycroft */
615 1.21 enami mb86960_setmode(sc);
616 1.1 mycroft
617 1.1 mycroft #if FE_DEBUG >= 3
618 1.1 mycroft log(LOG_INFO, "%s: after setmode\n", sc->sc_dev.dv_xname);
619 1.21 enami mb86960_dump(LOG_INFO, sc);
620 1.1 mycroft #endif
621 1.1 mycroft
622 1.1 mycroft /* ...and attempt to start output. */
623 1.21 enami mb86960_start(ifp);
624 1.1 mycroft
625 1.1 mycroft #if FE_DEBUG >= 3
626 1.21 enami log(LOG_INFO, "%s: end of mb86960_init()\n", sc->sc_dev.dv_xname);
627 1.21 enami mb86960_dump(LOG_INFO, sc);
628 1.1 mycroft #endif
629 1.1 mycroft }
630 1.1 mycroft
631 1.1 mycroft /*
632 1.1 mycroft * This routine actually starts the transmission on the interface
633 1.1 mycroft */
634 1.21 enami static __inline__ void
635 1.21 enami mb86960_xmit(sc)
636 1.21 enami struct mb86960_softc *sc;
637 1.1 mycroft {
638 1.21 enami bus_space_tag_t bst = sc->sc_bst;
639 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
640 1.1 mycroft
641 1.1 mycroft /*
642 1.1 mycroft * Set a timer just in case we never hear from the board again.
643 1.1 mycroft * We use longer timeout for multiple packet transmission.
644 1.1 mycroft * I'm not sure this timer value is appropriate. FIXME.
645 1.1 mycroft */
646 1.29.2.1 kenh sc->sc_ec.ec_if->if_timer = 1 + sc->txb_count;
647 1.1 mycroft
648 1.1 mycroft /* Update txb variables. */
649 1.1 mycroft sc->txb_sched = sc->txb_count;
650 1.1 mycroft sc->txb_count = 0;
651 1.1 mycroft sc->txb_free = sc->txb_size;
652 1.1 mycroft
653 1.1 mycroft #if FE_DELAYED_PADDING
654 1.1 mycroft /* Omit the postponed padding process. */
655 1.1 mycroft sc->txb_padding = 0;
656 1.1 mycroft #endif
657 1.1 mycroft
658 1.1 mycroft /* Start transmitter, passing packets in TX buffer. */
659 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR10, sc->txb_sched | FE_B10_START);
660 1.1 mycroft }
661 1.1 mycroft
662 1.1 mycroft /*
663 1.1 mycroft * Start output on interface.
664 1.1 mycroft * We make two assumptions here:
665 1.8 mycroft * 1) that the current priority is set to splnet _before_ this code
666 1.1 mycroft * is called *and* is returned to the appropriate priority after
667 1.1 mycroft * return
668 1.1 mycroft * 2) that the IFF_OACTIVE flag is checked before this code is called
669 1.1 mycroft * (i.e. that the output part of the interface is idle)
670 1.1 mycroft */
671 1.1 mycroft void
672 1.21 enami mb86960_start(ifp)
673 1.1 mycroft struct ifnet *ifp;
674 1.1 mycroft {
675 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
676 1.1 mycroft struct mbuf *m;
677 1.1 mycroft
678 1.1 mycroft #if FE_DEBUG >= 1
679 1.1 mycroft /* Just a sanity check. */
680 1.1 mycroft if ((sc->txb_count == 0) != (sc->txb_free == sc->txb_size)) {
681 1.1 mycroft /*
682 1.1 mycroft * Txb_count and txb_free co-works to manage the
683 1.1 mycroft * transmission buffer. Txb_count keeps track of the
684 1.1 mycroft * used potion of the buffer, while txb_free does unused
685 1.1 mycroft * potion. So, as long as the driver runs properly,
686 1.1 mycroft * txb_count is zero if and only if txb_free is same
687 1.1 mycroft * as txb_size (which represents whole buffer.)
688 1.1 mycroft */
689 1.1 mycroft log(LOG_ERR, "%s: inconsistent txb variables (%d, %d)\n",
690 1.1 mycroft sc->sc_dev.dv_xname, sc->txb_count, sc->txb_free);
691 1.1 mycroft /*
692 1.1 mycroft * So, what should I do, then?
693 1.1 mycroft *
694 1.1 mycroft * We now know txb_count and txb_free contradicts. We
695 1.1 mycroft * cannot, however, tell which is wrong. More
696 1.1 mycroft * over, we cannot peek 86960 transmission buffer or
697 1.1 mycroft * reset the transmission buffer. (In fact, we can
698 1.1 mycroft * reset the entire interface. I don't want to do it.)
699 1.1 mycroft *
700 1.1 mycroft * If txb_count is incorrect, leaving it as is will cause
701 1.1 mycroft * sending of gabages after next interrupt. We have to
702 1.1 mycroft * avoid it. Hence, we reset the txb_count here. If
703 1.1 mycroft * txb_free was incorrect, resetting txb_count just loose
704 1.1 mycroft * some packets. We can live with it.
705 1.1 mycroft */
706 1.1 mycroft sc->txb_count = 0;
707 1.1 mycroft }
708 1.1 mycroft #endif
709 1.1 mycroft
710 1.1 mycroft #if FE_DEBUG >= 1
711 1.1 mycroft /*
712 1.1 mycroft * First, see if there are buffered packets and an idle
713 1.1 mycroft * transmitter - should never happen at this point.
714 1.1 mycroft */
715 1.1 mycroft if ((sc->txb_count > 0) && (sc->txb_sched == 0)) {
716 1.1 mycroft log(LOG_ERR, "%s: transmitter idle with %d buffered packets\n",
717 1.1 mycroft sc->sc_dev.dv_xname, sc->txb_count);
718 1.21 enami mb86960_xmit(sc);
719 1.1 mycroft }
720 1.1 mycroft #endif
721 1.1 mycroft
722 1.1 mycroft /*
723 1.1 mycroft * Stop accepting more transmission packets temporarily, when
724 1.1 mycroft * a filter change request is delayed. Updating the MARs on
725 1.1 mycroft * 86960 flushes the transmisstion buffer, so it is delayed
726 1.1 mycroft * until all buffered transmission packets have been sent
727 1.1 mycroft * out.
728 1.1 mycroft */
729 1.1 mycroft if (sc->filter_change) {
730 1.1 mycroft /*
731 1.1 mycroft * Filter change requst is delayed only when the DLC is
732 1.1 mycroft * working. DLC soon raise an interrupt after finishing
733 1.1 mycroft * the work.
734 1.1 mycroft */
735 1.1 mycroft goto indicate_active;
736 1.1 mycroft }
737 1.1 mycroft
738 1.1 mycroft for (;;) {
739 1.1 mycroft /*
740 1.1 mycroft * See if there is room to put another packet in the buffer.
741 1.1 mycroft * We *could* do better job by peeking the send queue to
742 1.1 mycroft * know the length of the next packet. Current version just
743 1.1 mycroft * tests against the worst case (i.e., longest packet). FIXME.
744 1.1 mycroft *
745 1.1 mycroft * When adding the packet-peek feature, don't forget adding a
746 1.1 mycroft * test on txb_count against QUEUEING_MAX.
747 1.1 mycroft * There is a little chance the packet count exceeds
748 1.1 mycroft * the limit. Assume transmission buffer is 8KB (2x8KB
749 1.1 mycroft * configuration) and an application sends a bunch of small
750 1.1 mycroft * (i.e., minimum packet sized) packets rapidly. An 8KB
751 1.1 mycroft * buffer can hold 130 blocks of 62 bytes long...
752 1.1 mycroft */
753 1.1 mycroft if (sc->txb_free < ETHER_MAX_LEN + FE_DATA_LEN_LEN) {
754 1.1 mycroft /* No room. */
755 1.1 mycroft goto indicate_active;
756 1.1 mycroft }
757 1.1 mycroft
758 1.1 mycroft #if FE_SINGLE_TRANSMISSION
759 1.1 mycroft if (sc->txb_count > 0) {
760 1.1 mycroft /* Just one packet per a transmission buffer. */
761 1.1 mycroft goto indicate_active;
762 1.1 mycroft }
763 1.1 mycroft #endif
764 1.1 mycroft
765 1.1 mycroft /*
766 1.1 mycroft * Get the next mbuf chain for a packet to send.
767 1.1 mycroft */
768 1.1 mycroft IF_DEQUEUE(&ifp->if_snd, m);
769 1.1 mycroft if (m == 0) {
770 1.1 mycroft /* No more packets to send. */
771 1.1 mycroft goto indicate_inactive;
772 1.1 mycroft }
773 1.1 mycroft
774 1.6 mycroft #if NBPFILTER > 0
775 1.6 mycroft /* Tap off here if there is a BPF listener. */
776 1.6 mycroft if (ifp->if_bpf)
777 1.6 mycroft bpf_mtap(ifp->if_bpf, m);
778 1.6 mycroft #endif
779 1.6 mycroft
780 1.1 mycroft /*
781 1.1 mycroft * Copy the mbuf chain into the transmission buffer.
782 1.1 mycroft * txb_* variables are updated as necessary.
783 1.1 mycroft */
784 1.21 enami mb86960_write_mbufs(sc, m);
785 1.1 mycroft
786 1.6 mycroft m_freem(m);
787 1.6 mycroft
788 1.1 mycroft /* Start transmitter if it's idle. */
789 1.1 mycroft if (sc->txb_sched == 0)
790 1.21 enami mb86960_xmit(sc);
791 1.1 mycroft }
792 1.1 mycroft
793 1.1 mycroft indicate_inactive:
794 1.1 mycroft /*
795 1.1 mycroft * We are using the !OACTIVE flag to indicate to
796 1.1 mycroft * the outside world that we can accept an
797 1.1 mycroft * additional packet rather than that the
798 1.1 mycroft * transmitter is _actually_ active. Indeed, the
799 1.1 mycroft * transmitter may be active, but if we haven't
800 1.1 mycroft * filled all the buffers with data then we still
801 1.1 mycroft * want to accept more.
802 1.1 mycroft */
803 1.1 mycroft ifp->if_flags &= ~IFF_OACTIVE;
804 1.1 mycroft return;
805 1.1 mycroft
806 1.1 mycroft indicate_active:
807 1.1 mycroft /*
808 1.1 mycroft * The transmitter is active, and there are no room for
809 1.1 mycroft * more outgoing packets in the transmission buffer.
810 1.1 mycroft */
811 1.1 mycroft ifp->if_flags |= IFF_OACTIVE;
812 1.1 mycroft return;
813 1.1 mycroft }
814 1.1 mycroft
815 1.1 mycroft /*
816 1.1 mycroft * Transmission interrupt handler
817 1.1 mycroft * The control flow of this function looks silly. FIXME.
818 1.1 mycroft */
819 1.1 mycroft void
820 1.21 enami mb86960_tint(sc, tstat)
821 1.21 enami struct mb86960_softc *sc;
822 1.1 mycroft u_char tstat;
823 1.1 mycroft {
824 1.21 enami bus_space_tag_t bst = sc->sc_bst;
825 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
826 1.29.2.1 kenh struct ifnet *ifp = sc->sc_ec.ec_if;
827 1.1 mycroft int left;
828 1.1 mycroft int col;
829 1.1 mycroft
830 1.1 mycroft /*
831 1.1 mycroft * Handle "excessive collision" interrupt.
832 1.1 mycroft */
833 1.1 mycroft if (tstat & FE_D0_COLL16) {
834 1.1 mycroft /*
835 1.1 mycroft * Find how many packets (including this collided one)
836 1.1 mycroft * are left unsent in transmission buffer.
837 1.1 mycroft */
838 1.21 enami left = bus_space_read_1(bst, bsh, FE_BMPR10);
839 1.1 mycroft
840 1.1 mycroft #if FE_DEBUG >= 2
841 1.1 mycroft log(LOG_WARNING, "%s: excessive collision (%d/%d)\n",
842 1.1 mycroft sc->sc_dev.dv_xname, left, sc->txb_sched);
843 1.1 mycroft #endif
844 1.1 mycroft #if FE_DEBUG >= 3
845 1.21 enami mb86960_dump(LOG_INFO, sc);
846 1.1 mycroft #endif
847 1.1 mycroft
848 1.1 mycroft /*
849 1.1 mycroft * Update statistics.
850 1.1 mycroft */
851 1.1 mycroft ifp->if_collisions += 16;
852 1.1 mycroft ifp->if_oerrors++;
853 1.1 mycroft ifp->if_opackets += sc->txb_sched - left;
854 1.1 mycroft
855 1.1 mycroft /*
856 1.1 mycroft * Collision statistics has been updated.
857 1.1 mycroft * Clear the collision flag on 86960 now to avoid confusion.
858 1.1 mycroft */
859 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, FE_D0_COLLID);
860 1.1 mycroft
861 1.1 mycroft /*
862 1.1 mycroft * Restart transmitter, skipping the
863 1.1 mycroft * collided packet.
864 1.1 mycroft *
865 1.1 mycroft * We *must* skip the packet to keep network running
866 1.1 mycroft * properly. Excessive collision error is an
867 1.1 mycroft * indication of the network overload. If we
868 1.1 mycroft * tried sending the same packet after excessive
869 1.1 mycroft * collision, the network would be filled with
870 1.1 mycroft * out-of-time packets. Packets belonging
871 1.1 mycroft * to reliable transport (such as TCP) are resent
872 1.1 mycroft * by some upper layer.
873 1.1 mycroft */
874 1.21 enami bus_space_write_1(bst, bsh, FE_BMPR11,
875 1.1 mycroft FE_B11_CTRL_SKIP | FE_B11_MODE1);
876 1.1 mycroft sc->txb_sched = left - 1;
877 1.1 mycroft }
878 1.1 mycroft
879 1.1 mycroft /*
880 1.1 mycroft * Handle "transmission complete" interrupt.
881 1.1 mycroft */
882 1.1 mycroft if (tstat & FE_D0_TXDONE) {
883 1.1 mycroft /*
884 1.1 mycroft * Add in total number of collisions on last
885 1.1 mycroft * transmission. We also clear "collision occurred" flag
886 1.1 mycroft * here.
887 1.1 mycroft *
888 1.1 mycroft * 86960 has a design flow on collision count on multiple
889 1.1 mycroft * packet transmission. When we send two or more packets
890 1.1 mycroft * with one start command (that's what we do when the
891 1.1 mycroft * transmission queue is clauded), 86960 informs us number
892 1.1 mycroft * of collisions occured on the last packet on the
893 1.1 mycroft * transmission only. Number of collisions on previous
894 1.1 mycroft * packets are lost. I have told that the fact is clearly
895 1.1 mycroft * stated in the Fujitsu document.
896 1.1 mycroft *
897 1.1 mycroft * I considered not to mind it seriously. Collision
898 1.1 mycroft * count is not so important, anyway. Any comments? FIXME.
899 1.1 mycroft */
900 1.1 mycroft
901 1.21 enami if (bus_space_read_1(bst, bsh, FE_DLCR0) & FE_D0_COLLID) {
902 1.1 mycroft /* Clear collision flag. */
903 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, FE_D0_COLLID);
904 1.1 mycroft
905 1.1 mycroft /* Extract collision count from 86960. */
906 1.21 enami col = bus_space_read_1(bst, bsh, FE_DLCR4) & FE_D4_COL;
907 1.1 mycroft if (col == 0) {
908 1.1 mycroft /*
909 1.1 mycroft * Status register indicates collisions,
910 1.1 mycroft * while the collision count is zero.
911 1.1 mycroft * This can happen after multiple packet
912 1.1 mycroft * transmission, indicating that one or more
913 1.1 mycroft * previous packet(s) had been collided.
914 1.1 mycroft *
915 1.1 mycroft * Since the accurate number of collisions
916 1.1 mycroft * has been lost, we just guess it as 1;
917 1.1 mycroft * Am I too optimistic? FIXME.
918 1.1 mycroft */
919 1.1 mycroft col = 1;
920 1.1 mycroft } else
921 1.1 mycroft col >>= FE_D4_COL_SHIFT;
922 1.1 mycroft ifp->if_collisions += col;
923 1.1 mycroft #if FE_DEBUG >= 4
924 1.1 mycroft log(LOG_WARNING, "%s: %d collision%s (%d)\n",
925 1.1 mycroft sc->sc_dev.dv_xname, col, col == 1 ? "" : "s",
926 1.1 mycroft sc->txb_sched);
927 1.1 mycroft #endif
928 1.1 mycroft }
929 1.1 mycroft
930 1.1 mycroft /*
931 1.1 mycroft * Update total number of successfully
932 1.1 mycroft * transmitted packets.
933 1.1 mycroft */
934 1.1 mycroft ifp->if_opackets += sc->txb_sched;
935 1.1 mycroft sc->txb_sched = 0;
936 1.10 mycroft }
937 1.1 mycroft
938 1.10 mycroft if (sc->txb_sched == 0) {
939 1.1 mycroft /*
940 1.1 mycroft * The transmitter is no more active.
941 1.1 mycroft * Reset output active flag and watchdog timer.
942 1.1 mycroft */
943 1.1 mycroft ifp->if_flags &= ~IFF_OACTIVE;
944 1.1 mycroft ifp->if_timer = 0;
945 1.1 mycroft
946 1.1 mycroft /*
947 1.1 mycroft * If more data is ready to transmit in the buffer, start
948 1.1 mycroft * transmitting them. Otherwise keep transmitter idle,
949 1.1 mycroft * even if more data is queued. This gives receive
950 1.1 mycroft * process a slight priority.
951 1.1 mycroft */
952 1.1 mycroft if (sc->txb_count > 0)
953 1.21 enami mb86960_xmit(sc);
954 1.1 mycroft }
955 1.1 mycroft }
956 1.1 mycroft
957 1.1 mycroft /*
958 1.1 mycroft * Ethernet interface receiver interrupt.
959 1.1 mycroft */
960 1.1 mycroft void
961 1.21 enami mb86960_rint(sc, rstat)
962 1.21 enami struct mb86960_softc *sc;
963 1.1 mycroft u_char rstat;
964 1.1 mycroft {
965 1.21 enami bus_space_tag_t bst = sc->sc_bst;
966 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
967 1.29.2.1 kenh struct ifnet *ifp = sc->sc_ec.ec_if;
968 1.1 mycroft int len;
969 1.1 mycroft u_char status;
970 1.1 mycroft int i;
971 1.1 mycroft
972 1.1 mycroft /*
973 1.1 mycroft * Update statistics if this interrupt is caused by an error.
974 1.1 mycroft */
975 1.21 enami if (rstat & (FE_D1_OVRFLO | FE_D1_CRCERR | FE_D1_ALGERR |
976 1.21 enami FE_D1_SRTPKT)) {
977 1.1 mycroft #if FE_DEBUG >= 3
978 1.1 mycroft log(LOG_WARNING, "%s: receive error: %b\n",
979 1.1 mycroft sc->sc_dev.dv_xname, rstat, FE_D1_ERRBITS);
980 1.1 mycroft #endif
981 1.1 mycroft ifp->if_ierrors++;
982 1.1 mycroft }
983 1.1 mycroft
984 1.1 mycroft /*
985 1.1 mycroft * MB86960 has a flag indicating "receive queue empty."
986 1.1 mycroft * We just loop cheking the flag to pull out all received
987 1.1 mycroft * packets.
988 1.1 mycroft *
989 1.1 mycroft * We limit the number of iterrations to avoid infinite loop.
990 1.1 mycroft * It can be caused by a very slow CPU (some broken
991 1.1 mycroft * peripheral may insert incredible number of wait cycles)
992 1.1 mycroft * or, worse, by a broken MB86960 chip.
993 1.1 mycroft */
994 1.1 mycroft for (i = 0; i < FE_MAX_RECV_COUNT; i++) {
995 1.1 mycroft /* Stop the iterration if 86960 indicates no packets. */
996 1.21 enami if (bus_space_read_1(bst, bsh, FE_DLCR5) & FE_D5_BUFEMP)
997 1.1 mycroft break;
998 1.1 mycroft
999 1.1 mycroft /*
1000 1.1 mycroft * Extract A receive status byte.
1001 1.1 mycroft * As our 86960 is in 16 bit bus access mode, we have to
1002 1.1 mycroft * use inw() to get the status byte. The significant
1003 1.1 mycroft * value is returned in lower 8 bits.
1004 1.1 mycroft */
1005 1.21 enami status = (u_char)bus_space_read_2(bst, bsh, FE_BMPR8);
1006 1.1 mycroft #if FE_DEBUG >= 4
1007 1.1 mycroft log(LOG_INFO, "%s: receive status = %02x\n",
1008 1.1 mycroft sc->sc_dev.dv_xname, status);
1009 1.1 mycroft #endif
1010 1.1 mycroft
1011 1.1 mycroft /*
1012 1.1 mycroft * If there was an error, update statistics and drop
1013 1.1 mycroft * the packet, unless the interface is in promiscuous
1014 1.1 mycroft * mode.
1015 1.1 mycroft */
1016 1.1 mycroft if ((status & 0xF0) != 0x20) { /* XXXX ? */
1017 1.1 mycroft if ((ifp->if_flags & IFF_PROMISC) == 0) {
1018 1.1 mycroft ifp->if_ierrors++;
1019 1.21 enami mb86960_droppacket(sc);
1020 1.1 mycroft continue;
1021 1.1 mycroft }
1022 1.1 mycroft }
1023 1.1 mycroft
1024 1.1 mycroft /*
1025 1.1 mycroft * Extract the packet length.
1026 1.1 mycroft * It is a sum of a header (14 bytes) and a payload.
1027 1.1 mycroft * CRC has been stripped off by the 86960.
1028 1.1 mycroft */
1029 1.21 enami len = bus_space_read_2(bst, bsh, FE_BMPR8);
1030 1.1 mycroft
1031 1.1 mycroft /*
1032 1.1 mycroft * MB86965 checks the packet length and drop big packet
1033 1.1 mycroft * before passing it to us. There are no chance we can
1034 1.1 mycroft * get [crufty] packets. Hence, if the length exceeds
1035 1.1 mycroft * the specified limit, it means some serious failure,
1036 1.1 mycroft * such as out-of-sync on receive buffer management.
1037 1.1 mycroft *
1038 1.1 mycroft * Is this statement true? FIXME.
1039 1.1 mycroft */
1040 1.1 mycroft if (len > ETHER_MAX_LEN || len < ETHER_HDR_SIZE) {
1041 1.1 mycroft #if FE_DEBUG >= 2
1042 1.1 mycroft log(LOG_WARNING,
1043 1.1 mycroft "%s: received a %s packet? (%u bytes)\n",
1044 1.1 mycroft sc->sc_dev.dv_xname,
1045 1.1 mycroft len < ETHER_HDR_SIZE ? "partial" : "big", len);
1046 1.1 mycroft #endif
1047 1.1 mycroft ifp->if_ierrors++;
1048 1.21 enami mb86960_droppacket(sc);
1049 1.1 mycroft continue;
1050 1.1 mycroft }
1051 1.1 mycroft
1052 1.1 mycroft /*
1053 1.1 mycroft * Check for a short (RUNT) packet. We *do* check
1054 1.1 mycroft * but do nothing other than print a message.
1055 1.1 mycroft * Short packets are illegal, but does nothing bad
1056 1.1 mycroft * if it carries data for upper layer.
1057 1.1 mycroft */
1058 1.1 mycroft #if FE_DEBUG >= 2
1059 1.1 mycroft if (len < ETHER_MIN_LEN) {
1060 1.1 mycroft log(LOG_WARNING,
1061 1.21 enami "%s: received a short packet? (%u bytes)\n",
1062 1.21 enami sc->sc_dev.dv_xname, len);
1063 1.1 mycroft }
1064 1.1 mycroft #endif
1065 1.1 mycroft
1066 1.1 mycroft /*
1067 1.1 mycroft * Go get a packet.
1068 1.1 mycroft */
1069 1.21 enami if (!mb86960_get_packet(sc, len)) {
1070 1.1 mycroft /* Skip a packet, updating statistics. */
1071 1.1 mycroft #if FE_DEBUG >= 2
1072 1.1 mycroft log(LOG_WARNING,
1073 1.1 mycroft "%s: out of mbufs; dropping packet (%u bytes)\n",
1074 1.1 mycroft sc->sc_dev.dv_xname, len);
1075 1.1 mycroft #endif
1076 1.1 mycroft ifp->if_ierrors++;
1077 1.21 enami mb86960_droppacket(sc);
1078 1.1 mycroft
1079 1.1 mycroft /*
1080 1.1 mycroft * We stop receiving packets, even if there are
1081 1.1 mycroft * more in the buffer. We hope we can get more
1082 1.1 mycroft * mbufs next time.
1083 1.1 mycroft */
1084 1.1 mycroft return;
1085 1.1 mycroft }
1086 1.1 mycroft
1087 1.1 mycroft /* Successfully received a packet. Update stat. */
1088 1.1 mycroft ifp->if_ipackets++;
1089 1.1 mycroft }
1090 1.1 mycroft }
1091 1.1 mycroft
1092 1.1 mycroft /*
1093 1.1 mycroft * Ethernet interface interrupt processor
1094 1.1 mycroft */
1095 1.1 mycroft int
1096 1.21 enami mb86960_intr(arg)
1097 1.1 mycroft void *arg;
1098 1.1 mycroft {
1099 1.21 enami struct mb86960_softc *sc = arg;
1100 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1101 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1102 1.29.2.1 kenh struct ifnet *ifp = sc->sc_ec.ec_if;
1103 1.1 mycroft u_char tstat, rstat;
1104 1.1 mycroft
1105 1.21 enami if (sc->sc_enabled == 0)
1106 1.21 enami return (0);
1107 1.21 enami
1108 1.1 mycroft #if FE_DEBUG >= 4
1109 1.21 enami log(LOG_INFO, "%s: mb86960_intr()\n", sc->sc_dev.dv_xname);
1110 1.21 enami mb86960_dump(LOG_INFO, sc);
1111 1.1 mycroft #endif
1112 1.1 mycroft
1113 1.1 mycroft /*
1114 1.1 mycroft * Get interrupt conditions, masking unneeded flags.
1115 1.1 mycroft */
1116 1.21 enami tstat = bus_space_read_1(bst, bsh, FE_DLCR0) & FE_TMASK;
1117 1.21 enami rstat = bus_space_read_1(bst, bsh, FE_DLCR1) & FE_RMASK;
1118 1.1 mycroft if (tstat == 0 && rstat == 0)
1119 1.1 mycroft return (0);
1120 1.1 mycroft
1121 1.1 mycroft /*
1122 1.1 mycroft * Loop until there are no more new interrupt conditions.
1123 1.1 mycroft */
1124 1.1 mycroft for (;;) {
1125 1.1 mycroft /*
1126 1.1 mycroft * Reset the conditions we are acknowledging.
1127 1.1 mycroft */
1128 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR0, tstat);
1129 1.21 enami bus_space_write_1(bst, bsh, FE_DLCR1, rstat);
1130 1.1 mycroft
1131 1.1 mycroft /*
1132 1.1 mycroft * Handle transmitter interrupts. Handle these first because
1133 1.1 mycroft * the receiver will reset the board under some conditions.
1134 1.1 mycroft */
1135 1.1 mycroft if (tstat != 0)
1136 1.21 enami mb86960_tint(sc, tstat);
1137 1.1 mycroft
1138 1.1 mycroft /*
1139 1.1 mycroft * Handle receiver interrupts.
1140 1.1 mycroft */
1141 1.1 mycroft if (rstat != 0)
1142 1.21 enami mb86960_rint(sc, rstat);
1143 1.1 mycroft
1144 1.1 mycroft /*
1145 1.1 mycroft * Update the multicast address filter if it is
1146 1.1 mycroft * needed and possible. We do it now, because
1147 1.1 mycroft * we can make sure the transmission buffer is empty,
1148 1.1 mycroft * and there is a good chance that the receive queue
1149 1.1 mycroft * is empty. It will minimize the possibility of
1150 1.1 mycroft * packet lossage.
1151 1.1 mycroft */
1152 1.1 mycroft if (sc->filter_change &&
1153 1.1 mycroft sc->txb_count == 0 && sc->txb_sched == 0) {
1154 1.21 enami mb86960_loadmar(sc);
1155 1.21 enami ifp->if_flags &= ~IFF_OACTIVE;
1156 1.1 mycroft }
1157 1.1 mycroft
1158 1.1 mycroft /*
1159 1.1 mycroft * If it looks like the transmitter can take more data,
1160 1.1 mycroft * attempt to start output on the interface. This is done
1161 1.1 mycroft * after handling the receiver interrupt to give the
1162 1.1 mycroft * receive operation priority.
1163 1.1 mycroft */
1164 1.21 enami if ((ifp->if_flags & IFF_OACTIVE) == 0)
1165 1.21 enami mb86960_start(ifp);
1166 1.18 explorer
1167 1.18 explorer #if NRND > 0
1168 1.18 explorer if (rstat != 0 || tstat != 0)
1169 1.18 explorer rnd_add_uint32(&sc->rnd_source, rstat + tstat);
1170 1.18 explorer #endif
1171 1.1 mycroft
1172 1.1 mycroft /*
1173 1.1 mycroft * Get interrupt conditions, masking unneeded flags.
1174 1.1 mycroft */
1175 1.21 enami tstat = bus_space_read_1(bst, bsh, FE_DLCR0) & FE_TMASK;
1176 1.21 enami rstat = bus_space_read_1(bst, bsh, FE_DLCR1) & FE_RMASK;
1177 1.1 mycroft if (tstat == 0 && rstat == 0)
1178 1.1 mycroft return (1);
1179 1.1 mycroft }
1180 1.1 mycroft }
1181 1.1 mycroft
1182 1.1 mycroft /*
1183 1.1 mycroft * Process an ioctl request. This code needs some work - it looks pretty ugly.
1184 1.1 mycroft */
1185 1.1 mycroft int
1186 1.21 enami mb86960_ioctl(ifp, cmd, data)
1187 1.21 enami struct ifnet *ifp;
1188 1.21 enami u_long cmd;
1189 1.1 mycroft caddr_t data;
1190 1.1 mycroft {
1191 1.21 enami struct mb86960_softc *sc = ifp->if_softc;
1192 1.21 enami struct ifaddr *ifa = (struct ifaddr *)data;
1193 1.1 mycroft struct ifreq *ifr = (struct ifreq *)data;
1194 1.1 mycroft int s, error = 0;
1195 1.1 mycroft
1196 1.1 mycroft #if FE_DEBUG >= 3
1197 1.21 enami log(LOG_INFO, "%s: ioctl(%lx)\n", sc->sc_dev.dv_xname, cmd);
1198 1.1 mycroft #endif
1199 1.1 mycroft
1200 1.8 mycroft s = splnet();
1201 1.1 mycroft
1202 1.21 enami switch (cmd) {
1203 1.1 mycroft case SIOCSIFADDR:
1204 1.21 enami if ((error = mb86960_enable(sc)) != 0)
1205 1.21 enami break;
1206 1.1 mycroft ifp->if_flags |= IFF_UP;
1207 1.1 mycroft
1208 1.1 mycroft switch (ifa->ifa_addr->sa_family) {
1209 1.1 mycroft #ifdef INET
1210 1.1 mycroft case AF_INET:
1211 1.21 enami mb86960_init(sc);
1212 1.17 is arp_ifinit(ifp, ifa);
1213 1.1 mycroft break;
1214 1.1 mycroft #endif
1215 1.1 mycroft #ifdef NS
1216 1.1 mycroft case AF_NS:
1217 1.1 mycroft {
1218 1.21 enami struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1219 1.1 mycroft
1220 1.1 mycroft if (ns_nullhost(*ina))
1221 1.1 mycroft ina->x_host =
1222 1.21 enami *(union ns_host *)LLADDR(ifp->if_sadl);
1223 1.17 is else {
1224 1.17 is bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
1225 1.17 is ETHER_ADDR_LEN);
1226 1.17 is }
1227 1.1 mycroft /* Set new address. */
1228 1.21 enami mb86960_init(sc);
1229 1.1 mycroft break;
1230 1.1 mycroft }
1231 1.1 mycroft #endif
1232 1.1 mycroft default:
1233 1.21 enami mb86960_init(sc);
1234 1.1 mycroft break;
1235 1.1 mycroft }
1236 1.1 mycroft break;
1237 1.1 mycroft
1238 1.1 mycroft case SIOCSIFFLAGS:
1239 1.1 mycroft if ((ifp->if_flags & IFF_UP) == 0 &&
1240 1.1 mycroft (ifp->if_flags & IFF_RUNNING) != 0) {
1241 1.1 mycroft /*
1242 1.1 mycroft * If interface is marked down and it is running, then
1243 1.1 mycroft * stop it.
1244 1.1 mycroft */
1245 1.21 enami mb86960_stop(sc);
1246 1.1 mycroft ifp->if_flags &= ~IFF_RUNNING;
1247 1.21 enami mb86960_disable(sc);
1248 1.1 mycroft } else if ((ifp->if_flags & IFF_UP) != 0 &&
1249 1.21 enami (ifp->if_flags & IFF_RUNNING) == 0) {
1250 1.1 mycroft /*
1251 1.1 mycroft * If interface is marked up and it is stopped, then
1252 1.1 mycroft * start it.
1253 1.1 mycroft */
1254 1.21 enami if ((error = mb86960_enable(sc)) != 0)
1255 1.21 enami break;
1256 1.21 enami mb86960_init(sc);
1257 1.21 enami } else if (sc->sc_enabled) {
1258 1.1 mycroft /*
1259 1.1 mycroft * Reset the interface to pick up changes in any other
1260 1.1 mycroft * flags that affect hardware registers.
1261 1.1 mycroft */
1262 1.21 enami mb86960_setmode(sc);
1263 1.1 mycroft }
1264 1.1 mycroft #if DEBUG >= 1
1265 1.1 mycroft /* "ifconfig fe0 debug" to print register dump. */
1266 1.1 mycroft if (ifp->if_flags & IFF_DEBUG) {
1267 1.21 enami log(LOG_INFO, "%s: SIOCSIFFLAGS(DEBUG)\n",
1268 1.21 enami sc->sc_dev.dv_xname);
1269 1.21 enami mb86960_dump(LOG_DEBUG, sc);
1270 1.1 mycroft }
1271 1.1 mycroft #endif
1272 1.1 mycroft break;
1273 1.1 mycroft
1274 1.1 mycroft case SIOCADDMULTI:
1275 1.1 mycroft case SIOCDELMULTI:
1276 1.21 enami if (sc->sc_enabled == 0) {
1277 1.21 enami error = EIO;
1278 1.21 enami break;
1279 1.21 enami }
1280 1.21 enami
1281 1.1 mycroft /* Update our multicast list. */
1282 1.21 enami error = (cmd == SIOCADDMULTI) ?
1283 1.21 enami ether_addmulti(ifr, &sc->sc_ec) :
1284 1.21 enami ether_delmulti(ifr, &sc->sc_ec);
1285 1.1 mycroft
1286 1.1 mycroft if (error == ENETRESET) {
1287 1.1 mycroft /*
1288 1.1 mycroft * Multicast list has changed; set the hardware filter
1289 1.1 mycroft * accordingly.
1290 1.1 mycroft */
1291 1.21 enami mb86960_setmode(sc);
1292 1.1 mycroft error = 0;
1293 1.1 mycroft }
1294 1.1 mycroft break;
1295 1.1 mycroft
1296 1.21 enami case SIOCGIFMEDIA:
1297 1.21 enami case SIOCSIFMEDIA:
1298 1.21 enami error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1299 1.21 enami break;
1300 1.21 enami
1301 1.1 mycroft default:
1302 1.1 mycroft error = EINVAL;
1303 1.21 enami break;
1304 1.1 mycroft }
1305 1.1 mycroft
1306 1.1 mycroft splx(s);
1307 1.1 mycroft return (error);
1308 1.1 mycroft }
1309 1.1 mycroft
1310 1.1 mycroft /*
1311 1.1 mycroft * Retreive packet from receive buffer and send to the next level up via
1312 1.1 mycroft * ether_input(). If there is a BPF listener, give a copy to BPF, too.
1313 1.1 mycroft * Returns 0 if success, -1 if error (i.e., mbuf allocation failure).
1314 1.1 mycroft */
1315 1.1 mycroft int
1316 1.21 enami mb86960_get_packet(sc, len)
1317 1.21 enami struct mb86960_softc *sc;
1318 1.1 mycroft int len;
1319 1.1 mycroft {
1320 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1321 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1322 1.29.2.1 kenh struct ifnet *ifp = sc->sc_ec.ec_if;
1323 1.1 mycroft struct ether_header *eh;
1324 1.1 mycroft struct mbuf *m;
1325 1.1 mycroft
1326 1.1 mycroft /* Allocate a header mbuf. */
1327 1.1 mycroft MGETHDR(m, M_DONTWAIT, MT_DATA);
1328 1.1 mycroft if (m == 0)
1329 1.1 mycroft return (0);
1330 1.1 mycroft m->m_pkthdr.rcvif = ifp;
1331 1.1 mycroft m->m_pkthdr.len = len;
1332 1.1 mycroft
1333 1.1 mycroft /* The following silliness is to make NFS happy. */
1334 1.1 mycroft #define EROUND ((sizeof(struct ether_header) + 3) & ~3)
1335 1.1 mycroft #define EOFF (EROUND - sizeof(struct ether_header))
1336 1.1 mycroft
1337 1.1 mycroft /*
1338 1.1 mycroft * Our strategy has one more problem. There is a policy on
1339 1.1 mycroft * mbuf cluster allocation. It says that we must have at
1340 1.6 mycroft * least MINCLSIZE (208 bytes) to allocate a cluster. For a
1341 1.6 mycroft * packet of a size between (MHLEN - 2) to (MINCLSIZE - 2),
1342 1.6 mycroft * our code violates the rule...
1343 1.1 mycroft * On the other hand, the current code is short, simle,
1344 1.1 mycroft * and fast, however. It does no harmful thing, just waists
1345 1.1 mycroft * some memory. Any comments? FIXME.
1346 1.1 mycroft */
1347 1.1 mycroft
1348 1.1 mycroft /* Attach a cluster if this packet doesn't fit in a normal mbuf. */
1349 1.1 mycroft if (len > MHLEN - EOFF) {
1350 1.1 mycroft MCLGET(m, M_DONTWAIT);
1351 1.1 mycroft if ((m->m_flags & M_EXT) == 0) {
1352 1.1 mycroft m_freem(m);
1353 1.1 mycroft return (0);
1354 1.1 mycroft }
1355 1.1 mycroft }
1356 1.1 mycroft
1357 1.1 mycroft /*
1358 1.1 mycroft * The following assumes there is room for the ether header in the
1359 1.1 mycroft * header mbuf.
1360 1.1 mycroft */
1361 1.1 mycroft m->m_data += EOFF;
1362 1.1 mycroft eh = mtod(m, struct ether_header *);
1363 1.1 mycroft
1364 1.1 mycroft /* Set the length of this packet. */
1365 1.1 mycroft m->m_len = len;
1366 1.1 mycroft
1367 1.1 mycroft /* Get a packet. */
1368 1.29 pk bus_space_read_multi_2(bst, bsh, FE_BMPR8, mtod(m, u_int16_t *),
1369 1.29 pk (len + 1) >> 1);
1370 1.1 mycroft
1371 1.1 mycroft #if NBPFILTER > 0
1372 1.1 mycroft /*
1373 1.1 mycroft * Check if there's a BPF listener on this interface. If so, hand off
1374 1.1 mycroft * the raw packet to bpf.
1375 1.1 mycroft */
1376 1.1 mycroft if (ifp->if_bpf) {
1377 1.1 mycroft bpf_mtap(ifp->if_bpf, m);
1378 1.1 mycroft
1379 1.1 mycroft /*
1380 1.1 mycroft * Note that the interface cannot be in promiscuous mode if
1381 1.1 mycroft * there are no BPF listeners. And if we are in promiscuous
1382 1.1 mycroft * mode, we have to check if this packet is really ours.
1383 1.1 mycroft */
1384 1.1 mycroft if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1385 1.1 mycroft (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
1386 1.17 is bcmp(eh->ether_dhost, sc->sc_enaddr,
1387 1.21 enami sizeof(eh->ether_dhost)) != 0) {
1388 1.1 mycroft m_freem(m);
1389 1.1 mycroft return (1);
1390 1.1 mycroft }
1391 1.1 mycroft }
1392 1.1 mycroft #endif
1393 1.1 mycroft
1394 1.1 mycroft /* Fix up data start offset in mbuf to point past ether header. */
1395 1.1 mycroft m_adj(m, sizeof(struct ether_header));
1396 1.1 mycroft ether_input(ifp, eh, m);
1397 1.1 mycroft return (1);
1398 1.1 mycroft }
1399 1.1 mycroft
1400 1.1 mycroft /*
1401 1.1 mycroft * Write an mbuf chain to the transmission buffer memory using 16 bit PIO.
1402 1.1 mycroft * Returns number of bytes actually written, including length word.
1403 1.1 mycroft *
1404 1.1 mycroft * If an mbuf chain is too long for an Ethernet frame, it is not sent.
1405 1.1 mycroft * Packets shorter than Ethernet minimum are legal, and we pad them
1406 1.1 mycroft * before sending out. An exception is "partial" packets which are
1407 1.1 mycroft * shorter than mandatory Ethernet header.
1408 1.1 mycroft *
1409 1.1 mycroft * I wrote a code for an experimental "delayed padding" technique.
1410 1.1 mycroft * When employed, it postpones the padding process for short packets.
1411 1.1 mycroft * If xmit() occured at the moment, the padding process is omitted, and
1412 1.1 mycroft * garbages are sent as pad data. If next packet is stored in the
1413 1.1 mycroft * transmission buffer before xmit(), write_mbuf() pads the previous
1414 1.1 mycroft * packet before transmitting new packet. This *may* gain the
1415 1.1 mycroft * system performance (slightly).
1416 1.1 mycroft */
1417 1.1 mycroft void
1418 1.21 enami mb86960_write_mbufs(sc, m)
1419 1.21 enami struct mb86960_softc *sc;
1420 1.1 mycroft struct mbuf *m;
1421 1.1 mycroft {
1422 1.21 enami bus_space_tag_t bst = sc->sc_bst;
1423 1.21 enami bus_space_handle_t bsh = sc->sc_bsh;
1424 1.1 mycroft u_char *data;
1425 1.1 mycroft u_short savebyte; /* WARNING: Architecture dependent! */
1426 1.1 mycroft int totlen, len, wantbyte;
1427 1.21 enami #if FE_DEBUG >= 2
1428 1.21 enami struct mbuf *mp;
1429 1.21 enami #endif
1430 1.16 thorpej
1431 1.16 thorpej /* XXX thorpej 960116 - quiet bogus compiler warning. */
1432 1.16 thorpej savebyte = 0;
1433 1.1 mycroft
1434 1.1 mycroft #if FE_DELAYED_PADDING
1435 1.1 mycroft /* Do the "delayed padding." */
1436 1.1 mycroft len = sc->txb_padding >> 1;
1437 1.1 mycroft if (len > 0) {
1438 1.1 mycroft while (--len >= 0)
1439 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, 0);
1440 1.1 mycroft sc->txb_padding = 0;
1441 1.1 mycroft }
1442 1.1 mycroft #endif
1443 1.1 mycroft
1444 1.4 mycroft /* We need to use m->m_pkthdr.len, so require the header */
1445 1.4 mycroft if ((m->m_flags & M_PKTHDR) == 0)
1446 1.21 enami panic("mb86960_write_mbufs: no header mbuf");
1447 1.4 mycroft
1448 1.1 mycroft #if FE_DEBUG >= 2
1449 1.1 mycroft /* First, count up the total number of bytes to copy. */
1450 1.1 mycroft for (totlen = 0, mp = m; mp != 0; mp = mp->m_next)
1451 1.1 mycroft totlen += mp->m_len;
1452 1.1 mycroft /* Check if this matches the one in the packet header. */
1453 1.1 mycroft if (totlen != m->m_pkthdr.len)
1454 1.1 mycroft log(LOG_WARNING, "%s: packet length mismatch? (%d/%d)\n",
1455 1.1 mycroft sc->sc_dev.dv_xname, totlen, m->m_pkthdr.len);
1456 1.1 mycroft #else
1457 1.1 mycroft /* Just use the length value in the packet header. */
1458 1.1 mycroft totlen = m->m_pkthdr.len;
1459 1.1 mycroft #endif
1460 1.1 mycroft
1461 1.1 mycroft #if FE_DEBUG >= 1
1462 1.1 mycroft /*
1463 1.1 mycroft * Should never send big packets. If such a packet is passed,
1464 1.1 mycroft * it should be a bug of upper layer. We just ignore it.
1465 1.1 mycroft * ... Partial (too short) packets, neither.
1466 1.1 mycroft */
1467 1.1 mycroft if (totlen > ETHER_MAX_LEN || totlen < ETHER_HDR_SIZE) {
1468 1.1 mycroft log(LOG_ERR, "%s: got a %s packet (%u bytes) to send\n",
1469 1.1 mycroft sc->sc_dev.dv_xname,
1470 1.1 mycroft totlen < ETHER_HDR_SIZE ? "partial" : "big", totlen);
1471 1.29.2.1 kenh sc->sc_ec.ec_if->if_oerrors++;
1472 1.1 mycroft return;
1473 1.1 mycroft }
1474 1.1 mycroft #endif
1475 1.1 mycroft
1476 1.1 mycroft /*
1477 1.1 mycroft * Put the length word for this frame.
1478 1.1 mycroft * Does 86960 accept odd length? -- Yes.
1479 1.1 mycroft * Do we need to pad the length to minimum size by ourselves?
1480 1.1 mycroft * -- Generally yes. But for (or will be) the last
1481 1.1 mycroft * packet in the transmission buffer, we can skip the
1482 1.1 mycroft * padding process. It may gain performance slightly. FIXME.
1483 1.1 mycroft */
1484 1.21 enami bus_space_write_2(bst, bsh, FE_BMPR8, max(totlen, ETHER_MIN_LEN));
1485 1.1 mycroft
1486 1.1 mycroft /*
1487 1.1 mycroft * Update buffer status now.
1488 1.1 mycroft * Truncate the length up to an even number, since we use outw().
1489 1.1 mycroft */
1490 1.1 mycroft totlen = (totlen + 1) & ~1;
1491 1.1 mycroft sc->txb_free -= FE_DATA_LEN_LEN + max(totlen, ETHER_MIN_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.1 mycroft if (totlen < ETHER_MIN_LEN)
1497 1.1 mycroft sc->txb_padding = ETHER_MIN_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.1 mycroft len = (ETHER_MIN_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.29.2.1 kenh 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.29.2.1 kenh 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