1 /* $OpenBSD: if_lmc.c,v 1.18 2004/11/28 23:39:45 canacar Exp $ */
2 /* $NetBSD: if_lmc.c,v 1.1 1999/03/25 03:32:43 explorer Exp $ */
3
4 /*-
5 * Copyright (c) 1997-1999 LAN Media Corporation (LMC)
6 * All rights reserved. www.lanmedia.com
7 *
8 * This code is written by Michael Graff <graff@vix.com> for LMC.
9 * The code is derived from permitted modifications to software created
10 * by Matt Thomas (matt@3am-software.com).
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following disclaimer
19 * in the documentation and/or other materials provided with the
20 * distribution.
21 * 3. All marketing or advertising materials mentioning features or
22 * use of this software must display the following acknowledgement:
23 * This product includes software developed by LAN Media Corporation
24 * and its contributors.
25 * 4. Neither the name of LAN Media Corporation nor the names of its
26 * contributors may be used to endorse or promote products derived
27 * from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY LAN MEDIA CORPORATION AND CONTRIBUTORS
30 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
33 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
39 * THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42 /*-
43 * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
44 * All rights reserved.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. The name of the author may not be used to endorse or promote products
52 * derived from this software without specific prior written permission
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 */
65
66 /*
67 * LMC1200 (DS1) & LMC5245 (DS3) LED definitions
68 * led0 yellow = far-end link is in Red alarm condition
69 * led1 blue = received an Alarm Indication signal (upstream failure)
70 * led2 Green = power to adapter, Gate Array loaded & driver attached
71 * led3 red = Loss of Signal (LOS) or out of frame (OOF) conditions
72 * detected on T3 receive signal
73 *
74 * LMC1000 (SSI) & LMC5200 (HSSI) LED definitions
75 * led0 Green = power to adapter, Gate Array loaded & driver attached
76 * led1 Green = DSR and DTR and RTS and CTS are set (CA, TA for LMC5200)
77 * led2 Green = Cable detected (Green indicates non-loopback mode for LMC5200)
78 * led3 red = No timing is available from the cable or the on-board
79 * frequency generator. (ST not available for LMC5200)
80 */
81
82 #include <sys/param.h>
83 #include <sys/systm.h>
84 #include <sys/mbuf.h>
85 #include <sys/socket.h>
86 #include <sys/ioctl.h>
87 #include <sys/errno.h>
88 #include <sys/malloc.h>
89 #include <sys/kernel.h>
90 #include <sys/proc.h>
91 #if defined(__FreeBSD__)
92 #include <machine/clock.h>
93 #elif defined(__bsdi__) || defined(__NetBSD__) || defined(__OpenBSD__)
94 #include <sys/device.h>
95 #endif
96
97 #if defined(__OpenBSD__)
98 #include <dev/rndvar.h>
99 #include <dev/pci/pcidevs.h>
100 #endif
101
102 #if defined(__NetBSD__)
103 #include <dev/pci/pcidevs.h>
104 #include "rnd.h"
105 #if NRND > 0
106 #include <sys/rnd.h>
107 #endif
108 #endif
109
110 #include <net/if.h>
111 #include <net/if_types.h>
112 #include <net/if_dl.h>
113 #include <net/netisr.h>
114
115 #include "bpfilter.h"
116 #if NBPFILTER > 0
117 #include <net/bpf.h>
118 #endif
119
120 #include <uvm/uvm_extern.h>
121
122 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
123 #include <net/if_sppp.h>
124 #endif
125
126 #if defined(__bsdi__)
127 #if INET
128 #include <netinet/in.h>
129 #include <netinet/in_systm.h>
130 #include <netinet/ip.h>
131 #endif
132
133 #include <net/netisr.h>
134 #include <net/if.h>
135 #include <net/netisr.h>
136 #include <net/if_types.h>
137 #include <net/if_p2p.h>
138 #include <net/if_c_hdlc.h>
139 #endif
140
141 #if defined(__FreeBSD__)
142 #include <vm/pmap.h>
143 #include <pci.h>
144 #if NPCI > 0
145 #include <pci/pcivar.h>
146 #include <pci/dc21040reg.h>
147 #define INCLUDE_PATH_PREFIX "pci/"
148 #endif
149 #endif /* __FreeBSD__ */
150
151 #if defined(__bsdi__)
152 #include <i386/pci/ic/dc21040.h>
153 #include <i386/isa/isa.h>
154 #include <i386/isa/icu.h>
155 #include <i386/isa/dma.h>
156 #include <i386/isa/isavar.h>
157 #include <i386/pci/pci.h>
158
159 #define INCLUDE_PATH_PREFIX "i386/pci/"
160 #endif /* __bsdi__ */
161
162 #if defined(__NetBSD__) || defined(__OpenBSD__)
163 #include <machine/bus.h>
164 #if defined(__alpha__) && defined(__NetBSD__)
165 #include <machine/intr.h>
166 #endif
167 #include <dev/pci/pcireg.h>
168 #include <dev/pci/pcivar.h>
169 #include <dev/ic/dc21040reg.h>
170 #define INCLUDE_PATH_PREFIX "dev/pci/"
171 #endif /* __NetBSD__ */
172
173 #if defined(__OpenBSD__)
174 #define d_length1 u.bd_length1
175 #define d_length2 u.bd_length2
176 #define d_flag u.bd_flag
177 #endif
178
179 /*
180 * Sigh. Every OS puts these in different places. NetBSD and FreeBSD use
181 * a C preprocessor that allows this hack, but BSDI does not. Grr.
182 */
183 #if defined(__NetBSD__) || defined(__FreeBSD__)
184 #include INCLUDE_PATH_PREFIX "if_lmc_types.h"
185 #include INCLUDE_PATH_PREFIX "if_lmcioctl.h"
186 #include INCLUDE_PATH_PREFIX "if_lmcvar.h"
187 #elif defined(__OpenBSD__)
188 #include <dev/pci/if_lmc_types.h>
189 #include <dev/pci/if_lmcioctl.h>
190 #include <dev/pci/if_lmcvar.h>
191 #else /* BSDI */
192 #include "i386/pci/if_lmctypes.h"
193 #include "i386/pci/if_lmcioctl.h"
194 #include "i386/pci/if_lmcvar.h"
195 #endif
196
197 /*
198 * This module supports
199 * the DEC 21140A pass 2.2 PCI Fast Ethernet Controller.
200 */
201 static ifnet_ret_t lmc_ifstart_one(struct ifnet *ifp);
202 static ifnet_ret_t lmc_ifstart(struct ifnet *ifp);
203 static struct mbuf *lmc_txput(lmc_softc_t * const sc, struct mbuf *m);
204 static void lmc_rx_intr(lmc_softc_t * const sc);
205
206 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
207 static void lmc_watchdog(struct ifnet *ifp);
208 #endif
209 #if defined(__bsdi__)
210 static int lmc_watchdog(int);
211 #endif
212 static void lmc_ifup(lmc_softc_t * const sc);
213 static void lmc_ifdown(lmc_softc_t * const sc);
214
215
216 /*
217 * Code the read the SROM and MII bit streams (I2C)
218 */
219 static inline void
lmc_delay_300ns(lmc_softc_t * const sc)220 lmc_delay_300ns(lmc_softc_t * const sc)
221 {
222 int idx;
223 for (idx = (300 / 33) + 1; idx > 0; idx--)
224 (void)LMC_CSR_READ(sc, csr_busmode);
225 }
226
227
228 #define EMIT \
229 do { \
230 LMC_CSR_WRITE(sc, csr_srom_mii, csr); \
231 lmc_delay_300ns(sc); \
232 } while (0)
233
234 static inline void
lmc_srom_idle(lmc_softc_t * const sc)235 lmc_srom_idle(lmc_softc_t * const sc)
236 {
237 unsigned bit, csr;
238
239 csr = SROMSEL ; EMIT;
240 csr = SROMSEL | SROMRD; EMIT;
241 csr ^= SROMCS; EMIT;
242 csr ^= SROMCLKON; EMIT;
243
244 /*
245 * Write 25 cycles of 0 which will force the SROM to be idle.
246 */
247 for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
248 csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
249 csr ^= SROMCLKON; EMIT; /* clock high; data valid */
250 }
251 csr ^= SROMCLKOFF; EMIT;
252 csr ^= SROMCS; EMIT;
253 csr = 0; EMIT;
254 }
255
256
257 static void
lmc_srom_read(lmc_softc_t * const sc)258 lmc_srom_read(lmc_softc_t * const sc)
259 {
260 unsigned idx;
261 const unsigned bitwidth = SROM_BITWIDTH;
262 const unsigned cmdmask = (SROMCMD_RD << bitwidth);
263 const unsigned msb = 1 << (bitwidth + 3 - 1);
264 unsigned lastidx = (1 << bitwidth) - 1;
265
266 lmc_srom_idle(sc);
267
268 for (idx = 0; idx <= lastidx; idx++) {
269 unsigned lastbit, data, bits, bit, csr;
270 csr = SROMSEL ; EMIT;
271 csr = SROMSEL | SROMRD; EMIT;
272 csr ^= SROMCSON; EMIT;
273 csr ^= SROMCLKON; EMIT;
274
275 lastbit = 0;
276 for (bits = idx|cmdmask, bit = bitwidth + 3
277 ; bit > 0
278 ; bit--, bits <<= 1) {
279 const unsigned thisbit = bits & msb;
280 csr ^= SROMCLKOFF; EMIT; /* clock L data invalid */
281 if (thisbit != lastbit) {
282 csr ^= SROMDOUT; EMIT;/* clock L invert data */
283 } else {
284 EMIT;
285 }
286 csr ^= SROMCLKON; EMIT; /* clock H data valid */
287 lastbit = thisbit;
288 }
289 csr ^= SROMCLKOFF; EMIT;
290
291 for (data = 0, bits = 0; bits < 16; bits++) {
292 data <<= 1;
293 csr ^= SROMCLKON; EMIT; /* clock H data valid */
294 data |= LMC_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0;
295 csr ^= SROMCLKOFF; EMIT; /* clock L data invalid */
296 }
297 sc->lmc_rombuf[idx*2] = data & 0xFF;
298 sc->lmc_rombuf[idx*2+1] = data >> 8;
299 csr = SROMSEL | SROMRD; EMIT;
300 csr = 0; EMIT;
301 }
302 lmc_srom_idle(sc);
303 }
304
305 #define MII_EMIT do { LMC_CSR_WRITE(sc, csr_srom_mii, csr); lmc_delay_300ns(sc); } while (0)
306
307 static inline void
lmc_mii_writebits(lmc_softc_t * const sc,unsigned data,unsigned bits)308 lmc_mii_writebits(lmc_softc_t * const sc, unsigned data, unsigned bits)
309 {
310 unsigned msb = 1 << (bits - 1);
311 unsigned csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
312 unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
313
314 csr |= MII_WR; MII_EMIT; /* clock low; assert write */
315
316 for (; bits > 0; bits--, data <<= 1) {
317 const unsigned thisbit = data & msb;
318 if (thisbit != lastbit) {
319 csr ^= MII_DOUT; MII_EMIT; /* clock low; invert data */
320 }
321 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
322 lastbit = thisbit;
323 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
324 }
325 }
326
327 static void
lmc_mii_turnaround(lmc_softc_t * const sc,u_int32_t cmd)328 lmc_mii_turnaround(lmc_softc_t * const sc, u_int32_t cmd)
329 {
330 u_int32_t csr;
331
332 csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
333 if (cmd == MII_WRCMD) {
334 csr |= MII_DOUT; MII_EMIT; /* clock low; change data */
335 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
336 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
337 csr ^= MII_DOUT; MII_EMIT; /* clock low; change data */
338 } else {
339 csr |= MII_RD; MII_EMIT; /* clock low; switch to read */
340 }
341 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
342 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
343 }
344
345 static u_int32_t
lmc_mii_readbits(lmc_softc_t * const sc)346 lmc_mii_readbits(lmc_softc_t * const sc)
347 {
348 u_int32_t data;
349 u_int32_t csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
350 int idx;
351
352 for (idx = 0, data = 0; idx < 16; idx++) {
353 data <<= 1; /* this is NOOP on the first pass through */
354 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
355 if (LMC_CSR_READ(sc, csr_srom_mii) & MII_DIN)
356 data |= 1;
357 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */
358 }
359 csr ^= MII_RD; MII_EMIT; /* clock low; turn off read */
360
361 return data;
362 }
363
364 u_int32_t
lmc_mii_readreg(lmc_softc_t * const sc,u_int32_t devaddr,u_int32_t regno)365 lmc_mii_readreg(lmc_softc_t * const sc, u_int32_t devaddr, u_int32_t regno)
366 {
367 u_int32_t csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
368 u_int32_t data;
369
370 csr &= ~(MII_RD|MII_CLK); MII_EMIT;
371 lmc_mii_writebits(sc, MII_PREAMBLE, 32);
372 lmc_mii_writebits(sc, MII_RDCMD, 8);
373 lmc_mii_writebits(sc, devaddr, 5);
374 lmc_mii_writebits(sc, regno, 5);
375 lmc_mii_turnaround(sc, MII_RDCMD);
376
377 data = lmc_mii_readbits(sc);
378 return (data);
379 }
380
381 void
lmc_mii_writereg(lmc_softc_t * const sc,u_int32_t devaddr,u_int32_t regno,u_int32_t data)382 lmc_mii_writereg(lmc_softc_t * const sc, u_int32_t devaddr,
383 u_int32_t regno, u_int32_t data)
384 {
385 u_int32_t csr;
386
387 csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
388 csr &= ~(MII_RD|MII_CLK); MII_EMIT;
389 lmc_mii_writebits(sc, MII_PREAMBLE, 32);
390 lmc_mii_writebits(sc, MII_WRCMD, 8);
391 lmc_mii_writebits(sc, devaddr, 5);
392 lmc_mii_writebits(sc, regno, 5);
393 lmc_mii_turnaround(sc, MII_WRCMD);
394 lmc_mii_writebits(sc, data, 16);
395 }
396
397 int
lmc_read_macaddr(lmc_softc_t * const sc)398 lmc_read_macaddr(lmc_softc_t * const sc)
399 {
400 lmc_srom_read(sc);
401
402 bcopy(sc->lmc_rombuf + 20, sc->lmc_enaddr, 6);
403
404 return 0;
405 }
406
407 /*
408 * Check to make certain there is a signal from the modem, and flicker
409 * lights as needed.
410 */
411 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
412 static void
lmc_watchdog(struct ifnet * ifp)413 lmc_watchdog(struct ifnet *ifp)
414 #endif
415 #if defined(__bsdi__)
416 static int
417 lmc_watchdog(int unit)
418 #endif
419 {
420 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
421 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
422 #endif
423 #if defined(__bsdi__)
424 lmc_softc_t * const sc = LMC_UNIT_TO_SOFTC(unit);
425 struct ifnet *ifp = &sc->lmc_if;
426 #endif
427 int state;
428 u_int32_t ostatus;
429 u_int32_t link_status;
430 u_int32_t ticks;
431
432 state = 0;
433
434 /*
435 * Make sure the tx jabber and rx watchdog are off,
436 * and the transmit and receive processes are running.
437 */
438 LMC_CSR_WRITE (sc, csr_15, 0x00000011);
439 sc->lmc_cmdmode |= TULIP_CMD_TXRUN | TULIP_CMD_RXRUN;
440 LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
441
442 /* Is the transmit clock still available? */
443 ticks = LMC_CSR_READ (sc, csr_gp_timer);
444 ticks = 0x0000ffff - (ticks & 0x0000ffff);
445
446 if (ticks == 0)
447 {
448 /* no clock found ? */
449 if (sc->tx_clockState != 0)
450 {
451 sc->tx_clockState = 0;
452 if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
453 lmc_led_on (sc, LMC_MII16_LED3); /* ON red */
454 }
455 else
456 if (sc->tx_clockState == 0)
457 {
458 sc->tx_clockState = 1;
459 if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
460 lmc_led_off (sc, LMC_MII16_LED3); /* OFF red */
461 }
462 }
463
464 link_status = sc->lmc_media->get_link_status(sc);
465 ostatus = ((sc->lmc_flags & LMC_MODEMOK) == LMC_MODEMOK);
466
467 /*
468 * hardware level link lost, but the interface is marked as up.
469 * Mark it as down.
470 */
471 if (link_status == LMC_LINK_DOWN && ostatus) {
472 printf(LMC_PRINTF_FMT ": physical link down\n",
473 LMC_PRINTF_ARGS);
474 sc->lmc_flags &= ~LMC_MODEMOK;
475 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
476 sc->lmc_cardtype == LMC_CARDTYPE_T1)
477 lmc_led_on (sc, LMC_DS3_LED3 | LMC_DS3_LED2);
478 /* turn on red LED */
479 else {
480 lmc_led_off (sc, LMC_MII16_LED1);
481 lmc_led_on (sc, LMC_MII16_LED0);
482 if (sc->lmc_timing == LMC_CTL_CLOCK_SOURCE_EXT)
483 lmc_led_on (sc, LMC_MII16_LED3);
484 }
485
486 }
487
488 /*
489 * hardware link is up, but the interface is marked as down.
490 * Bring it back up again.
491 */
492 if (link_status != LMC_LINK_DOWN && !ostatus) {
493 printf(LMC_PRINTF_FMT ": physical link up\n",
494 LMC_PRINTF_ARGS);
495 if (sc->lmc_flags & LMC_IFUP)
496 lmc_ifup(sc);
497 sc->lmc_flags |= LMC_MODEMOK;
498 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
499 sc->lmc_cardtype == LMC_CARDTYPE_T1)
500 {
501 sc->lmc_miireg16 |= LMC_DS3_LED3;
502 lmc_led_off (sc, LMC_DS3_LED3);
503 /* turn off red LED */
504 lmc_led_on (sc, LMC_DS3_LED2);
505 } else {
506 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED1
507 | LMC_MII16_LED2);
508 if (sc->lmc_timing != LMC_CTL_CLOCK_SOURCE_EXT)
509 lmc_led_off (sc, LMC_MII16_LED3);
510 }
511
512 return;
513 }
514
515 /* Call media specific watchdog functions */
516 sc->lmc_media->watchdog(sc);
517
518 /*
519 * remember the timer value
520 */
521 ticks = LMC_CSR_READ(sc, csr_gp_timer);
522 LMC_CSR_WRITE(sc, csr_gp_timer, 0xffffffffUL);
523 sc->ictl.ticks = 0x0000ffff - (ticks & 0x0000ffff);
524
525 ifp->if_timer = 1;
526 }
527
528 /*
529 * Mark the interface as "up" and enable TX/RX and TX/RX interrupts.
530 * This also does a full software reset.
531 */
532 static void
lmc_ifup(lmc_softc_t * const sc)533 lmc_ifup(lmc_softc_t * const sc)
534 {
535 sc->lmc_if.if_timer = 0;
536
537 lmc_dec_reset(sc);
538 lmc_reset(sc);
539
540 sc->lmc_media->set_link_status(sc, LMC_LINK_UP);
541 sc->lmc_media->set_status(sc, NULL);
542
543 sc->lmc_flags |= LMC_IFUP;
544
545 /*
546 * for DS3 & DS1 adapters light the green light, led2
547 */
548 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
549 sc->lmc_cardtype == LMC_CARDTYPE_T1)
550 lmc_led_on (sc, LMC_MII16_LED2);
551 else
552 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
553
554 /*
555 * select what interrupts we want to get
556 */
557 sc->lmc_intrmask |= (TULIP_STS_NORMALINTR
558 | TULIP_STS_RXINTR
559 | TULIP_STS_TXINTR
560 | TULIP_STS_ABNRMLINTR
561 | TULIP_STS_SYSERROR
562 | TULIP_STS_TXSTOPPED
563 | TULIP_STS_TXUNDERFLOW
564 | TULIP_STS_RXSTOPPED
565 );
566 LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);
567
568 sc->lmc_cmdmode |= TULIP_CMD_TXRUN;
569 sc->lmc_cmdmode |= TULIP_CMD_RXRUN;
570 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
571
572 sc->lmc_if.if_timer = 1;
573 }
574
575 /*
576 * Mark the interface as "down" and disable TX/RX and TX/RX interrupts.
577 * This is done by performing a full reset on the interface.
578 */
579 static void
lmc_ifdown(lmc_softc_t * const sc)580 lmc_ifdown(lmc_softc_t * const sc)
581 {
582 sc->lmc_if.if_timer = 0;
583 sc->lmc_flags &= ~LMC_IFUP;
584
585 sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
586 lmc_led_off(sc, LMC_MII16_LED_ALL);
587
588 lmc_dec_reset(sc);
589 lmc_reset(sc);
590 sc->lmc_media->set_status(sc, NULL);
591 }
592
593 static void
lmc_rx_intr(lmc_softc_t * const sc)594 lmc_rx_intr(lmc_softc_t * const sc)
595 {
596 lmc_ringinfo_t * const ri = &sc->lmc_rxinfo;
597 struct ifnet * const ifp = &sc->lmc_if;
598 int fillok = 1;
599
600 sc->lmc_rxtick++;
601
602 for (;;) {
603 tulip_desc_t *eop = ri->ri_nextin;
604 int total_len = 0, last_offset = 0;
605 struct mbuf *ms = NULL, *me = NULL;
606 int accept = 0;
607
608 if (fillok && sc->lmc_rxq.ifq_len < LMC_RXQ_TARGET)
609 goto queue_mbuf;
610
611 /*
612 * If the TULIP has no descriptors, there can't be any receive
613 * descriptors to process.
614 */
615 if (eop == ri->ri_nextout)
616 break;
617
618 /*
619 * 90% of the packets will fit in one descriptor. So we
620 * optimize for that case.
621 */
622 if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
623 IF_DEQUEUE(&sc->lmc_rxq, ms);
624 me = ms;
625 } else {
626 /*
627 * If still owned by the TULIP, don't touch it.
628 */
629 if (((volatile tulip_desc_t *)eop)->d_status & TULIP_DSTS_OWNER)
630 break;
631
632 /*
633 * It is possible (though improbable unless the
634 * BIG_PACKET support is enabled or MCLBYTES < 1518)
635 * for a received packet to cross more than one
636 * receive descriptor.
637 */
638 while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) {
639 if (++eop == ri->ri_last)
640 eop = ri->ri_first;
641 if (eop == ri->ri_nextout || ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER))) {
642 return;
643 }
644 total_len++;
645 }
646
647 /*
648 * Dequeue the first buffer for the start of the
649 * packet. Hopefully this will be the only one we
650 * need to dequeue. However, if the packet consumed
651 * multiple descriptors, then we need to dequeue
652 * those buffers and chain to the starting mbuf.
653 * All buffers but the last buffer have the same
654 * length so we can set that now. (we add to
655 * last_offset instead of multiplying since we
656 * normally won't go into the loop and thereby
657 * saving a ourselves from doing a multiplication
658 * by 0 in the normal case).
659 */
660 IF_DEQUEUE(&sc->lmc_rxq, ms);
661 for (me = ms; total_len > 0; total_len--) {
662 me->m_len = LMC_RX_BUFLEN;
663 last_offset += LMC_RX_BUFLEN;
664 IF_DEQUEUE(&sc->lmc_rxq, me->m_next);
665 me = me->m_next;
666 }
667 }
668
669 /*
670 * Now get the size of received packet (minus the CRC).
671 */
672 total_len = ((eop->d_status >> 16) & 0x7FFF);
673 if (sc->ictl.crc_length == 16)
674 total_len -= 2;
675 else
676 total_len -= 4;
677
678 if ((sc->lmc_flags & LMC_RXIGNORE) == 0
679 && ((eop->d_status & LMC_DSTS_ERRSUM) == 0
680 #ifdef BIG_PACKET
681 || (total_len <= sc->lmc_if.if_mtu + PPP_HEADER_LEN
682 && (eop->d_status & TULIP_DSTS_RxOVERFLOW) == 0)
683 #endif
684 )) {
685 me->m_len = total_len - last_offset;
686 #if NBPFILTER > 0
687 if (sc->lmc_bpf != NULL) {
688 if (me == ms)
689 LMC_BPF_TAP(sc, mtod(ms, caddr_t), total_len);
690 else
691 LMC_BPF_MTAP(sc, ms);
692 }
693 #endif
694 sc->lmc_flags |= LMC_RXACT;
695 accept = 1;
696 } else {
697 ifp->if_ierrors++;
698 if (eop->d_status & TULIP_DSTS_RxOVERFLOW) {
699 sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
700 }
701 }
702
703 ifp->if_ipackets++;
704 if (++eop == ri->ri_last)
705 eop = ri->ri_first;
706 ri->ri_nextin = eop;
707
708 queue_mbuf:
709 /*
710 * Either we are priming the TULIP with mbufs (m == NULL)
711 * or we are about to accept an mbuf for the upper layers
712 * so we need to allocate an mbuf to replace it. If we
713 * can't replace it, send up it anyways. This may cause
714 * us to drop packets in the future but that's better than
715 * being caught in livelock.
716 *
717 * Note that if this packet crossed multiple descriptors
718 * we don't even try to reallocate all the mbufs here.
719 * Instead we rely on the test of the beginning of
720 * the loop to refill for the extra consumed mbufs.
721 */
722 if (accept || ms == NULL) {
723 struct mbuf *m0;
724 MGETHDR(m0, M_DONTWAIT, MT_DATA);
725 if (m0 != NULL) {
726 MCLGET(m0, M_DONTWAIT);
727 if ((m0->m_flags & M_EXT) == 0) {
728 m_freem(m0);
729 m0 = NULL;
730 }
731 }
732 if (accept) {
733 ms->m_pkthdr.len = total_len;
734 ms->m_pkthdr.rcvif = ifp;
735 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
736 sppp_input(ifp, ms);
737 #endif
738 #if defined(__bsdi__)
739 sc->lmc_p2pcom.p2p_input(&sc->lmc_p2pcom, ms);
740 #endif
741 }
742 ms = m0;
743 }
744 if (ms == NULL) {
745 /*
746 * Couldn't allocate a new buffer. Don't bother
747 * trying to replenish the receive queue.
748 */
749 fillok = 0;
750 sc->lmc_flags |= LMC_RXBUFSLOW;
751 continue;
752 }
753 /*
754 * Now give the buffer(s) to the TULIP and save in our
755 * receive queue.
756 */
757 do {
758 ri->ri_nextout->d_length1 = LMC_RX_BUFLEN;
759 ri->ri_nextout->d_addr1 = LMC_KVATOPHYS(sc, mtod(ms, caddr_t));
760 ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
761 if (++ri->ri_nextout == ri->ri_last)
762 ri->ri_nextout = ri->ri_first;
763 me = ms->m_next;
764 ms->m_next = NULL;
765 IF_ENQUEUE(&sc->lmc_rxq, ms);
766 } while ((ms = me) != NULL);
767
768 if (sc->lmc_rxq.ifq_len >= LMC_RXQ_TARGET)
769 sc->lmc_flags &= ~LMC_RXBUFSLOW;
770 }
771 }
772
773 static int
lmc_tx_intr(lmc_softc_t * const sc)774 lmc_tx_intr(lmc_softc_t * const sc)
775 {
776 lmc_ringinfo_t * const ri = &sc->lmc_txinfo;
777 struct mbuf *m;
778 int xmits = 0;
779 int descs = 0;
780
781 sc->lmc_txtick++;
782
783 while (ri->ri_free < ri->ri_max) {
784 #ifdef __OpenBSD__
785 u_int32_t duh_flag;
786 #else
787 u_int32_t d_flag;
788 #endif
789
790 if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER)
791 break;
792
793 #ifdef __OpenBSD__
794 duh_flag = ri->ri_nextin->d_flag;
795 if (duh_flag & TULIP_DFLAG_TxLASTSEG) {
796 #else
797 d_flag = ri->ri_nextin->d_flag;
798 if (d_flag & TULIP_DFLAG_TxLASTSEG) {
799 #endif
800 const u_int32_t d_status = ri->ri_nextin->d_status;
801 IF_DEQUEUE(&sc->lmc_txq, m);
802 if (m != NULL) {
803 #if NBPFILTER > 0
804 if (sc->lmc_bpf != NULL)
805 LMC_BPF_MTAP(sc, m);
806 #endif
807 m_freem(m);
808 #if defined(LMC_DEBUG)
809 } else {
810 printf(LMC_PRINTF_FMT ": tx_intr: failed to dequeue mbuf?!?\n", LMC_PRINTF_ARGS);
811 #endif
812 }
813 xmits++;
814 if (d_status & LMC_DSTS_ERRSUM) {
815 sc->lmc_if.if_oerrors++;
816 if (d_status & TULIP_DSTS_TxUNDERFLOW)
817 sc->lmc_dot3stats.dot3StatsInternalTransmitUnderflows++;
818 } else {
819 if (d_status & TULIP_DSTS_TxDEFERRED)
820 sc->lmc_dot3stats.dot3StatsDeferredTransmissions++;
821 }
822 }
823
824 if (++ri->ri_nextin == ri->ri_last)
825 ri->ri_nextin = ri->ri_first;
826
827 ri->ri_free++;
828 descs++;
829 sc->lmc_if.if_flags &= ~IFF_OACTIVE;
830 }
831 /*
832 * If nothing left to transmit, disable the timer.
833 * Else if progress, reset the timer back to 2 ticks.
834 */
835 sc->lmc_if.if_opackets += xmits;
836
837 return descs;
838 }
839
840 static void
841 lmc_print_abnormal_interrupt (lmc_softc_t * const sc, u_int32_t csr)
842 {
843 printf(LMC_PRINTF_FMT ": Abnormal interrupt\n", LMC_PRINTF_ARGS);
844 }
845
846 static void
847 lmc_intr_handler(lmc_softc_t * const sc, int *progress_p)
848 {
849 u_int32_t csr;
850
851 while ((csr = LMC_CSR_READ(sc, csr_status)) & sc->lmc_intrmask) {
852
853 #ifdef __MirBSD__
854 rnd_lopool_addv(csr);
855 #endif
856 #if defined(__NetBSD__)
857 #if NRND > 0
858 rnd_add_uint32(&sc->lmc_rndsource, csr);
859 #endif
860 #endif
861
862 *progress_p = 1;
863 LMC_CSR_WRITE(sc, csr_status, csr);
864
865 if (csr & TULIP_STS_SYSERROR) {
866 sc->lmc_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
867 if (sc->lmc_flags & LMC_NOMESSAGES) {
868 sc->lmc_flags |= LMC_SYSTEMERROR;
869 } else {
870 printf(LMC_PRINTF_FMT ": system error: %s\n",
871 LMC_PRINTF_ARGS,
872 lmc_system_errors[sc->lmc_last_system_error]);
873 }
874 sc->lmc_flags |= LMC_NEEDRESET;
875 sc->lmc_system_errors++;
876 break;
877 }
878 if (csr & (TULIP_STS_RXINTR | TULIP_STS_RXNOBUF)) {
879 u_int32_t misses = LMC_CSR_READ(sc, csr_missed_frames);
880 if (csr & TULIP_STS_RXNOBUF)
881 sc->lmc_dot3stats.dot3StatsMissedFrames += misses & 0xFFFF;
882 /*
883 * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
884 * on receive overflows.
885 */
886 if ((misses & 0x0FFE0000) && (sc->lmc_features & LMC_HAVE_RXBADOVRFLW)) {
887 sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
888 /*
889 * Stop the receiver process and spin until it's stopped.
890 * Tell rx_intr to drop the packets it dequeues.
891 */
892 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode & ~TULIP_CMD_RXRUN);
893 while ((LMC_CSR_READ(sc, csr_status) & TULIP_STS_RXSTOPPED) == 0)
894 ;
895 LMC_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
896 sc->lmc_flags |= LMC_RXIGNORE;
897 }
898 lmc_rx_intr(sc);
899 if (sc->lmc_flags & LMC_RXIGNORE) {
900 /*
901 * Restart the receiver.
902 */
903 sc->lmc_flags &= ~LMC_RXIGNORE;
904 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
905 }
906 }
907 if (csr & TULIP_STS_ABNRMLINTR) {
908 u_int32_t tmp = csr & sc->lmc_intrmask
909 & ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
910 if (csr & TULIP_STS_TXUNDERFLOW) {
911 if ((sc->lmc_cmdmode & TULIP_CMD_THRESHOLDCTL) != TULIP_CMD_THRSHLD160) {
912 sc->lmc_cmdmode += TULIP_CMD_THRSHLD96;
913 sc->lmc_flags |= LMC_NEWTXTHRESH;
914 } else if (sc->lmc_features & LMC_HAVE_STOREFWD) {
915 sc->lmc_cmdmode |= TULIP_CMD_STOREFWD;
916 sc->lmc_flags |= LMC_NEWTXTHRESH;
917 }
918 }
919 if (sc->lmc_flags & LMC_NOMESSAGES) {
920 sc->lmc_statusbits |= tmp;
921 } else {
922 lmc_print_abnormal_interrupt(sc, tmp);
923 sc->lmc_flags |= LMC_NOMESSAGES;
924 }
925 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
926 }
927
928 if (csr & TULIP_STS_TXINTR)
929 lmc_tx_intr(sc);
930
931 if (sc->lmc_flags & LMC_WANTTXSTART)
932 lmc_ifstart(&sc->lmc_if);
933 }
934 }
935
936 lmc_intrfunc_t
937 lmc_intr_normal(void *arg)
938 {
939 lmc_softc_t * sc = (lmc_softc_t *) arg;
940 int progress = 0;
941
942 lmc_intr_handler(sc, &progress);
943
944 #if !defined(LMC_VOID_INTRFUNC)
945 return progress;
946 #endif
947 }
948
949 static struct mbuf *
950 lmc_mbuf_compress(struct mbuf *m)
951 {
952 struct mbuf *m0;
953 #if MCLBYTES >= LMC_MTU + PPP_HEADER_LEN && !defined(BIG_PACKET)
954 MGETHDR(m0, M_DONTWAIT, MT_DATA);
955 if (m0 != NULL) {
956 if (m->m_pkthdr.len > MHLEN) {
957 MCLGET(m0, M_DONTWAIT);
958 if ((m0->m_flags & M_EXT) == 0) {
959 m_freem(m);
960 m_freem(m0);
961 return NULL;
962 }
963 }
964 m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
965 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
966 }
967 #else
968 int mlen = MHLEN;
969 int len = m->m_pkthdr.len;
970 struct mbuf **mp = &m0;
971
972 while (len > 0) {
973 if (mlen == MHLEN) {
974 MGETHDR(*mp, M_DONTWAIT, MT_DATA);
975 } else {
976 MGET(*mp, M_DONTWAIT, MT_DATA);
977 }
978 if (*mp == NULL) {
979 m_freem(m0);
980 m0 = NULL;
981 break;
982 }
983 if (len > MLEN) {
984 MCLGET(*mp, M_DONTWAIT);
985 if (((*mp)->m_flags & M_EXT) == 0) {
986 m_freem(m0);
987 m0 = NULL;
988 break;
989 }
990 (*mp)->m_len = (len <= MCLBYTES ? len : MCLBYTES);
991 } else {
992 (*mp)->m_len = (len <= mlen ? len : mlen);
993 }
994 m_copydata(m, m->m_pkthdr.len - len,
995 (*mp)->m_len, mtod((*mp), caddr_t));
996 len -= (*mp)->m_len;
997 mp = &(*mp)->m_next;
998 mlen = MLEN;
999 }
1000 #endif
1001 m_freem(m);
1002 return m0;
1003 }
1004
1005 /*
1006 * queue the mbuf handed to us for the interface. If we cannot
1007 * queue it, return the mbuf. Return NULL if the mbuf was queued.
1008 */
1009 static struct mbuf *
1010 lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
1011 {
1012 lmc_ringinfo_t * const ri = &sc->lmc_txinfo;
1013 tulip_desc_t *eop, *nextout;
1014 int segcnt, free;
1015 u_int32_t d_status;
1016 struct mbuf *m0;
1017
1018 #if defined(LMC_DEBUG)
1019 if ((sc->lmc_cmdmode & TULIP_CMD_TXRUN) == 0) {
1020 printf(LMC_PRINTF_FMT ": txput: tx not running\n",
1021 LMC_PRINTF_ARGS);
1022 sc->lmc_flags |= LMC_WANTTXSTART;
1023 goto finish;
1024 }
1025 #endif
1026
1027 /*
1028 * Now we try to fill in our transmit descriptors. This is
1029 * a bit reminiscent of going on the Ark two by two
1030 * since each descriptor for the TULIP can describe
1031 * two buffers. So we advance through packet filling
1032 * each of the two entries at a time to fill each
1033 * descriptor. Clear the first and last segment bits
1034 * in each descriptor (actually just clear everything
1035 * but the end-of-ring or chain bits) to make sure
1036 * we don't get messed up by previously sent packets.
1037 *
1038 * We may fail to put the entire packet on the ring if
1039 * there is either not enough ring entries free or if the
1040 * packet has more than MAX_TXSEG segments. In the former
1041 * case we will just wait for the ring to empty. In the
1042 * latter case we have to recopy.
1043 */
1044 again:
1045 d_status = 0;
1046 eop = nextout = ri->ri_nextout;
1047 m0 = m;
1048 segcnt = 0;
1049 free = ri->ri_free;
1050 do {
1051 int len = m0->m_len;
1052 caddr_t addr = mtod(m0, caddr_t);
1053 unsigned clsize = PAGE_SIZE - (((u_long) addr) & PAGE_MASK);
1054
1055 while (len > 0) {
1056 unsigned slen = min(len, clsize);
1057 #ifdef BIG_PACKET
1058 int partial = 0;
1059 if (slen >= 2048)
1060 slen = 2040, partial = 1;
1061 #endif
1062 segcnt++;
1063 if (segcnt > LMC_MAX_TXSEG) {
1064 /*
1065 * The packet exceeds the number of transmit
1066 * buffer entries that we can use for one
1067 * packet, so we have recopy it into one mbuf
1068 * and then try again.
1069 */
1070 m = lmc_mbuf_compress(m);
1071 if (m == NULL)
1072 goto finish;
1073 goto again;
1074 }
1075 if (segcnt & 1) {
1076 if (--free == 0) {
1077 /*
1078 * See if there's any unclaimed space
1079 * in the transmit ring.
1080 */
1081 if ((free += lmc_tx_intr(sc)) == 0) {
1082 /*
1083 * There's no more room but
1084 * since nothing has been
1085 * committed at this point,
1086 * just show output is active,
1087 * put back the mbuf and
1088 * return.
1089 */
1090 sc->lmc_flags |= LMC_WANTTXSTART;
1091 goto finish;
1092 }
1093 }
1094 eop = nextout;
1095 if (++nextout == ri->ri_last)
1096 nextout = ri->ri_first;
1097 eop->d_flag &= TULIP_DFLAG_ENDRING;
1098 eop->d_flag |= TULIP_DFLAG_TxNOPADDING;
1099 if (sc->ictl.crc_length == 16)
1100 eop->d_flag |= TULIP_DFLAG_TxHASCRC;
1101 eop->d_status = d_status;
1102 eop->d_addr1 = LMC_KVATOPHYS(sc, addr);
1103 eop->d_length1 = slen;
1104 } else {
1105 /*
1106 * Fill in second half of descriptor
1107 */
1108 eop->d_addr2 = LMC_KVATOPHYS(sc, addr);
1109 eop->d_length2 = slen;
1110 }
1111 d_status = TULIP_DSTS_OWNER;
1112 len -= slen;
1113 addr += slen;
1114 #ifdef BIG_PACKET
1115 if (partial)
1116 continue;
1117 #endif
1118 clsize = PAGE_SIZE;
1119 }
1120 } while ((m0 = m0->m_next) != NULL);
1121
1122
1123 /*
1124 * The descriptors have been filled in. Now get ready
1125 * to transmit.
1126 */
1127 IF_ENQUEUE(&sc->lmc_txq, m);
1128 m = NULL;
1129
1130 /*
1131 * Make sure the next descriptor after this packet is owned
1132 * by us since it may have been set up above if we ran out
1133 * of room in the ring.
1134 */
1135 nextout->d_status = 0;
1136
1137 /*
1138 * If we only used the first segment of the last descriptor,
1139 * make sure the second segment will not be used.
1140 */
1141 if (segcnt & 1) {
1142 eop->d_addr2 = 0;
1143 eop->d_length2 = 0;
1144 }
1145
1146 /*
1147 * Mark the last and first segments, indicate we want a transmit
1148 * complete interrupt, and tell it to transmit!
1149 */
1150 eop->d_flag |= TULIP_DFLAG_TxLASTSEG | TULIP_DFLAG_TxWANTINTR;
1151
1152 /*
1153 * Note that ri->ri_nextout is still the start of the packet
1154 * and until we set the OWNER bit, we can still back out of
1155 * everything we have done.
1156 */
1157 ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
1158 ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
1159
1160 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1161
1162 /*
1163 * This advances the ring for us.
1164 */
1165 ri->ri_nextout = nextout;
1166 ri->ri_free = free;
1167
1168 /*
1169 * switch back to the single queueing ifstart.
1170 */
1171 sc->lmc_flags &= ~LMC_WANTTXSTART;
1172 sc->lmc_if.if_start = lmc_ifstart_one;
1173
1174 /*
1175 * If we want a txstart, there must be not enough space in the
1176 * transmit ring. So we want to enable transmit done interrupts
1177 * so we can immediately reclaim some space. When the transmit
1178 * interrupt is posted, the interrupt handler will call tx_intr
1179 * to reclaim space and then txstart (since WANTTXSTART is set).
1180 * txstart will move the packet into the transmit ring and clear
1181 * WANTTXSTART thereby causing TXINTR to be cleared.
1182 */
1183 finish:
1184 if (sc->lmc_flags & LMC_WANTTXSTART) {
1185 sc->lmc_if.if_flags |= IFF_OACTIVE;
1186 sc->lmc_if.if_start = lmc_ifstart;
1187 }
1188
1189 return m;
1190 }
1191
1192
1193 /*
1194 * This routine is entered at splnet() (splsoftnet() on NetBSD)
1195 */
1196 static int
1197 lmc_ifioctl(struct ifnet * ifp, ioctl_cmd_t cmd, caddr_t data)
1198 {
1199 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1200 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1201 lmc_spl_t s;
1202 #endif
1203 struct proc *p = curproc;
1204 int error = 0;
1205 struct ifreq *ifr = (struct ifreq *)data;
1206 u_int32_t new_state;
1207 u_int32_t old_state;
1208 lmc_ctl_t ctl;
1209
1210 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1211 s = LMC_RAISESPL();
1212 #endif
1213
1214 switch (cmd) {
1215 case LMCIOCGINFO:
1216 error = copyout(&sc->ictl, ifr->ifr_data, sizeof(lmc_ctl_t));
1217
1218 goto out;
1219 break;
1220
1221 case LMCIOCSINFO:
1222 error = suser(p, 0);
1223 if (error)
1224 goto out;
1225
1226 error = copyin(ifr->ifr_data, &ctl, sizeof(lmc_ctl_t));
1227 if (error != 0)
1228 goto out;
1229
1230 sc->lmc_media->set_status(sc, &ctl);
1231
1232 goto out;
1233 break;
1234
1235 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1236 case SIOCSIFMTU:
1237 /*
1238 * Don't allow the MTU to get larger than we can handle
1239 */
1240 if (ifr->ifr_mtu > LMC_MTU) {
1241 error = EINVAL;
1242 goto out;
1243 } else {
1244 ifp->if_mtu = ifr->ifr_mtu;
1245 }
1246 break;
1247 #endif
1248 }
1249
1250 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1251 /*
1252 * call the sppp ioctl layer
1253 */
1254 error = sppp_ioctl(ifp, cmd, data);
1255 if (error != 0)
1256 goto out;
1257 #endif
1258
1259 #if defined(__bsdi__)
1260 error = p2p_ioctl(ifp, cmd, data);
1261 #endif
1262
1263 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1264 /*
1265 * If we are transitioning from up to down or down to up, call
1266 * our init routine.
1267 */
1268 new_state = ifp->if_flags & IFF_UP;
1269 old_state = sc->lmc_flags & LMC_IFUP;
1270
1271 if (new_state && !old_state)
1272 lmc_ifup(sc);
1273 else if (!new_state && old_state)
1274 lmc_ifdown(sc);
1275 #endif
1276
1277 out:
1278 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1279 LMC_RESTORESPL(s);
1280 #endif
1281
1282 return error;
1283 }
1284
1285 /*
1286 * These routines gets called at device spl (from sppp_output).
1287 */
1288
1289 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1290 static ifnet_ret_t
1291 lmc_ifstart(struct ifnet * const ifp)
1292 {
1293 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1294 struct mbuf *m, *m0;
1295
1296 if (sc->lmc_flags & LMC_IFUP) {
1297 while (sppp_isempty(ifp) == 0) {
1298 m = sppp_pick(ifp);
1299 if (m == NULL)
1300 break;
1301 if ((m = lmc_txput(sc, m)) != NULL)
1302 break;
1303 m0 = sppp_dequeue(ifp);
1304 #if defined(LMC_DEBUG)
1305 if (m0 != m)
1306 printf("lmc_ifstart: mbuf mismatch!\n");
1307 #endif
1308 }
1309 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1310 }
1311 }
1312
1313 static ifnet_ret_t
1314 lmc_ifstart_one(struct ifnet * const ifp)
1315 {
1316 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1317 struct mbuf *m, *m0;
1318
1319 if ((sc->lmc_flags & LMC_IFUP) && (sppp_isempty(ifp) == 0)) {
1320 m = sppp_pick(ifp);
1321 if ((m = lmc_txput(sc, m)) != NULL)
1322 return;
1323 m0 = sppp_dequeue(ifp);
1324 #if defined(LMC_DEBUG)
1325 if (m0 != m)
1326 printf("lmc_ifstart: mbuf mismatch!\n");
1327 #endif
1328 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1329 }
1330 }
1331 #endif
1332
1333 #if defined(__bsdi__)
1334 static ifnet_ret_t
1335 lmc_ifstart(struct ifnet * const ifp)
1336 {
1337 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1338 struct mbuf *m;
1339 struct ifqueue *ifq;
1340
1341 if ((sc->lmc_flags & LMC_IFUP) == 0)
1342 return;
1343
1344 for (;;) {
1345 ifq = &sc->lmc_p2pcom.p2p_isnd;
1346
1347 m = ifq->ifq_head;
1348 if (m == NULL) {
1349 ifq = &sc->lmc_if.if_snd;
1350 m = ifq->ifq_head;
1351 }
1352 if (m == NULL)
1353 break;
1354 IF_DEQUEUE(ifq, m);
1355
1356 m = lmc_txput(sc, m);
1357 if (m != NULL) {
1358 IF_PREPEND(ifq, m);
1359 break;
1360 }
1361 }
1362
1363 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1364 }
1365
1366 static ifnet_ret_t
1367 lmc_ifstart_one(struct ifnet * const ifp)
1368 {
1369 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1370 struct mbuf *m;
1371 struct ifqueue *ifq;
1372
1373 if ((sc->lmc_flags & LMC_IFUP) == 0)
1374 return;
1375
1376 ifq = &sc->lmc_p2pcom.p2p_isnd;
1377
1378 m = ifq->ifq_head;
1379 {
1380 if (m == NULL) {
1381 ifq = &sc->lmc_if.if_snd;
1382 m = ifq->ifq_head;
1383 }
1384 if (m == NULL)
1385 return 0;
1386 IF_DEQUEUE(ifq, m);
1387
1388 m = lmc_txput(sc, m);
1389 }
1390 if (m != NULL)
1391 IF_PREPEND(ifq, m);
1392
1393 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1394 }
1395 #endif
1396
1397 #if defined(__bsdi__)
1398 int
1399 lmc_getmdm(struct p2pcom *pp, caddr_t b)
1400 {
1401 lmc_softc_t *sc = LMC_UNIT_TO_SOFTC(pp->p2p_if.if_unit);
1402
1403 if (sc->lmc_media->get_link_status(sc)) {
1404 *(int *)b = TIOCM_CAR;
1405 } else {
1406 *(int *)b = 0;
1407 }
1408
1409 return (0);
1410 }
1411
1412 int
1413 lmc_mdmctl(struct p2pcom *pp, int flag)
1414 {
1415 lmc_softc_t *sc = LMC_UNIT_TO_SOFTC(pp->p2p_if.if_unit);
1416
1417 sc->lmc_media->set_link_status(sc, flag);
1418
1419 if (flag)
1420 if ((sc->lmc_flags & LMC_IFUP) == 0)
1421 lmc_ifup(sc);
1422 else
1423 if ((sc->lmc_flags & LMC_IFUP) == LMC_IFUP)
1424 lmc_ifdown(sc);
1425
1426 return (0);
1427 }
1428 #endif
1429
1430 /*
1431 * Set up the OS interface magic and attach to the operating system
1432 * network services.
1433 */
1434 void
1435 lmc_attach(lmc_softc_t * const sc)
1436 {
1437 struct ifnet * const ifp = &sc->lmc_if;
1438
1439 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
1440 ifp->if_ioctl = lmc_ifioctl;
1441 ifp->if_start = lmc_ifstart;
1442 ifp->if_watchdog = lmc_watchdog;
1443 ifp->if_timer = 1;
1444 ifp->if_mtu = LMC_MTU;
1445 IFQ_SET_READY(&ifp->if_snd);
1446
1447 #if defined(__bsdi__)
1448 ifp->if_type = IFT_NONE;
1449 ifp->if_unit = (sc->lmc_dev.dv_unit);
1450 #endif
1451
1452 if_attach(ifp);
1453 if_alloc_sadl(ifp);
1454
1455 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1456 sppp_attach((struct ifnet *)&sc->lmc_sppp);
1457 sc->lmc_sppp.pp_flags = PP_CISCO | PP_KEEPALIVE;
1458 sc->lmc_sppp.pp_framebytes = 3;
1459 #endif
1460 #if defined(__bsdi__)
1461 sc->lmc_p2pcom.p2p_mdmctl = lmc_mdmctl;
1462 sc->lmc_p2pcom.p2p_getmdm = lmc_getmdm;
1463 p2p_attach(&sc->lmc_p2pcom);
1464 #endif
1465
1466 #if NBPFILTER > 0
1467 LMC_BPF_ATTACH(sc);
1468 #endif
1469
1470 #if defined(__NetBSD__) && NRND > 0
1471 rnd_attach_source(&sc->lmc_rndsource, sc->lmc_dev.dv_xname,
1472 RND_TYPE_NET, 0);
1473 #endif
1474
1475 /*
1476 * turn off those LEDs...
1477 */
1478 sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
1479 /*
1480 * for DS3 & DS1 adapters light the green light, led2
1481 */
1482 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
1483 sc->lmc_cardtype == LMC_CARDTYPE_T1)
1484 lmc_led_on (sc, LMC_MII16_LED2);
1485 else
1486 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
1487 }
1488
1489 void
1490 lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
1491 tulip_desc_t *descs, int ndescs)
1492 {
1493 ri->ri_max = ndescs;
1494 ri->ri_first = descs;
1495 ri->ri_last = ri->ri_first + ri->ri_max;
1496 bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
1497 ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
1498 }
1499