This source file includes following definitions.
- lmc_delay_300ns
- lmc_srom_idle
- lmc_srom_read
- lmc_mii_writebits
- lmc_mii_turnaround
- lmc_mii_readbits
- lmc_mii_readreg
- lmc_mii_writereg
- lmc_read_macaddr
- lmc_watchdog
- lmc_ifup
- lmc_ifdown
- lmc_rx_intr
- lmc_tx_intr
- lmc_print_abnormal_interrupt
- lmc_intr_handler
- lmc_intr_normal
- lmc_mbuf_compress
- lmc_txput
- lmc_ifioctl
- lmc_ifstart
- lmc_ifstart_one
- lmc_attach
- lmc_initring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 #include "bpfilter.h"
83
84 #include <sys/param.h>
85 #include <sys/systm.h>
86 #include <sys/mbuf.h>
87 #include <sys/socket.h>
88 #include <sys/ioctl.h>
89 #include <sys/errno.h>
90 #include <sys/malloc.h>
91 #include <sys/kernel.h>
92 #include <sys/proc.h>
93 #include <sys/device.h>
94
95 #include <dev/pci/pcidevs.h>
96
97 #include <net/if.h>
98 #include <net/if_types.h>
99 #include <net/if_dl.h>
100 #include <net/netisr.h>
101
102 #if NBPFILTER > 0
103 #include <net/bpf.h>
104 #endif
105
106 #include <net/if_sppp.h>
107
108 #include <machine/bus.h>
109
110 #include <dev/pci/pcireg.h>
111 #include <dev/pci/pcivar.h>
112 #include <dev/ic/dc21040reg.h>
113
114 #include <dev/pci/if_lmc_types.h>
115 #include <dev/pci/if_lmcioctl.h>
116 #include <dev/pci/if_lmcvar.h>
117
118
119
120
121
122 static ifnet_ret_t lmc_ifstart_one(struct ifnet *ifp);
123 static ifnet_ret_t lmc_ifstart(struct ifnet *ifp);
124 static struct mbuf *lmc_txput(lmc_softc_t * const sc, struct mbuf *m);
125 static void lmc_rx_intr(lmc_softc_t * const sc);
126
127 static void lmc_watchdog(struct ifnet *ifp);
128 static void lmc_ifup(lmc_softc_t * const sc);
129 static void lmc_ifdown(lmc_softc_t * const sc);
130
131
132
133
134 static inline void
135 lmc_delay_300ns(lmc_softc_t * const sc)
136 {
137 int idx;
138 for (idx = (300 / 33) + 1; idx > 0; idx--)
139 (void)LMC_CSR_READ(sc, csr_busmode);
140 }
141
142 #define EMIT \
143 do { \
144 LMC_CSR_WRITE(sc, csr_srom_mii, csr); \
145 lmc_delay_300ns(sc); \
146 } while (0)
147
148 static inline void
149 lmc_srom_idle(lmc_softc_t * const sc)
150 {
151 unsigned bit, csr;
152
153 csr = SROMSEL ; EMIT;
154 csr = SROMSEL | SROMRD; EMIT;
155 csr ^= SROMCS; EMIT;
156 csr ^= SROMCLKON; EMIT;
157
158
159
160
161 for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
162 csr ^= SROMCLKOFF; EMIT;
163 csr ^= SROMCLKON; EMIT;
164 }
165 csr ^= SROMCLKOFF; EMIT;
166 csr ^= SROMCS; EMIT;
167 csr = 0; EMIT;
168 }
169
170
171 static void
172 lmc_srom_read(lmc_softc_t * const sc)
173 {
174 unsigned idx;
175 const unsigned bitwidth = SROM_BITWIDTH;
176 const unsigned cmdmask = (SROMCMD_RD << bitwidth);
177 const unsigned msb = 1 << (bitwidth + 3 - 1);
178 unsigned lastidx = (1 << bitwidth) - 1;
179
180 lmc_srom_idle(sc);
181
182 for (idx = 0; idx <= lastidx; idx++) {
183 unsigned lastbit, data, bits, bit, csr;
184 csr = SROMSEL ; EMIT;
185 csr = SROMSEL | SROMRD; EMIT;
186 csr ^= SROMCSON; EMIT;
187 csr ^= SROMCLKON; EMIT;
188
189 lastbit = 0;
190 for (bits = idx|cmdmask, bit = bitwidth + 3
191 ; bit > 0
192 ; bit--, bits <<= 1) {
193 const unsigned thisbit = bits & msb;
194 csr ^= SROMCLKOFF; EMIT;
195 if (thisbit != lastbit) {
196 csr ^= SROMDOUT; EMIT;
197 } else {
198 EMIT;
199 }
200 csr ^= SROMCLKON; EMIT;
201 lastbit = thisbit;
202 }
203 csr ^= SROMCLKOFF; EMIT;
204
205 for (data = 0, bits = 0; bits < 16; bits++) {
206 data <<= 1;
207 csr ^= SROMCLKON; EMIT;
208 data |= LMC_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0;
209 csr ^= SROMCLKOFF; EMIT;
210 }
211 sc->lmc_rombuf[idx*2] = data & 0xFF;
212 sc->lmc_rombuf[idx*2+1] = data >> 8;
213 csr = SROMSEL | SROMRD; EMIT;
214 csr = 0; EMIT;
215 }
216 lmc_srom_idle(sc);
217 }
218
219 #define MII_EMIT do { LMC_CSR_WRITE(sc, csr_srom_mii, csr); lmc_delay_300ns(sc); } while (0)
220
221 static inline void
222 lmc_mii_writebits(lmc_softc_t * const sc, unsigned data, unsigned bits)
223 {
224 unsigned msb = 1 << (bits - 1);
225 unsigned csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
226 unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
227
228 csr |= MII_WR; MII_EMIT;
229
230 for (; bits > 0; bits--, data <<= 1) {
231 const unsigned thisbit = data & msb;
232 if (thisbit != lastbit) {
233 csr ^= MII_DOUT; MII_EMIT;
234 }
235 csr ^= MII_CLKON; MII_EMIT;
236 lastbit = thisbit;
237 csr ^= MII_CLKOFF; MII_EMIT;
238 }
239 }
240
241 static void
242 lmc_mii_turnaround(lmc_softc_t * const sc, u_int32_t cmd)
243 {
244 u_int32_t csr;
245
246 csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
247 if (cmd == MII_WRCMD) {
248 csr |= MII_DOUT; MII_EMIT;
249 csr ^= MII_CLKON; MII_EMIT;
250 csr ^= MII_CLKOFF; MII_EMIT;
251 csr ^= MII_DOUT; MII_EMIT;
252 } else {
253 csr |= MII_RD; MII_EMIT;
254 }
255 csr ^= MII_CLKON; MII_EMIT;
256 csr ^= MII_CLKOFF; MII_EMIT;
257 }
258
259 static u_int32_t
260 lmc_mii_readbits(lmc_softc_t * const sc)
261 {
262 u_int32_t data;
263 u_int32_t csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
264 int idx;
265
266 for (idx = 0, data = 0; idx < 16; idx++) {
267 data <<= 1;
268 csr ^= MII_CLKON; MII_EMIT;
269 if (LMC_CSR_READ(sc, csr_srom_mii) & MII_DIN)
270 data |= 1;
271 csr ^= MII_CLKOFF; MII_EMIT;
272 }
273 csr ^= MII_RD; MII_EMIT;
274
275 return data;
276 }
277
278 u_int32_t
279 lmc_mii_readreg(lmc_softc_t * const sc, u_int32_t devaddr, u_int32_t regno)
280 {
281 u_int32_t csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
282 u_int32_t data;
283
284 csr &= ~(MII_RD|MII_CLK); MII_EMIT;
285 lmc_mii_writebits(sc, MII_PREAMBLE, 32);
286 lmc_mii_writebits(sc, MII_RDCMD, 8);
287 lmc_mii_writebits(sc, devaddr, 5);
288 lmc_mii_writebits(sc, regno, 5);
289 lmc_mii_turnaround(sc, MII_RDCMD);
290
291 data = lmc_mii_readbits(sc);
292 return (data);
293 }
294
295 void
296 lmc_mii_writereg(lmc_softc_t * const sc, u_int32_t devaddr,
297 u_int32_t regno, u_int32_t data)
298 {
299 u_int32_t csr;
300
301 csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
302 csr &= ~(MII_RD|MII_CLK); MII_EMIT;
303 lmc_mii_writebits(sc, MII_PREAMBLE, 32);
304 lmc_mii_writebits(sc, MII_WRCMD, 8);
305 lmc_mii_writebits(sc, devaddr, 5);
306 lmc_mii_writebits(sc, regno, 5);
307 lmc_mii_turnaround(sc, MII_WRCMD);
308 lmc_mii_writebits(sc, data, 16);
309 }
310
311 int
312 lmc_read_macaddr(lmc_softc_t * const sc)
313 {
314 lmc_srom_read(sc);
315
316 bcopy(sc->lmc_rombuf + 20, sc->lmc_enaddr, 6);
317
318 return 0;
319 }
320
321
322
323
324
325 static void
326 lmc_watchdog(struct ifnet *ifp)
327 {
328 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
329 int state;
330 u_int32_t ostatus;
331 u_int32_t link_status;
332 u_int32_t ticks;
333
334 state = 0;
335
336
337
338
339
340 LMC_CSR_WRITE (sc, csr_15, 0x00000011);
341 sc->lmc_cmdmode |= TULIP_CMD_TXRUN | TULIP_CMD_RXRUN;
342 LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
343
344
345 ticks = LMC_CSR_READ (sc, csr_gp_timer);
346 ticks = 0x0000ffff - (ticks & 0x0000ffff);
347 if (ticks == 0)
348 {
349
350 if (sc->tx_clockState != 0)
351 {
352 sc->tx_clockState = 0;
353 if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
354 lmc_led_on (sc, LMC_MII16_LED3);
355 }
356 else
357 if (sc->tx_clockState == 0)
358 {
359 sc->tx_clockState = 1;
360 if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
361 lmc_led_off (sc, LMC_MII16_LED3);
362 }
363 }
364
365 link_status = sc->lmc_media->get_link_status(sc);
366 ostatus = ((sc->lmc_flags & LMC_MODEMOK) == LMC_MODEMOK);
367
368
369
370
371
372 if (link_status == LMC_LINK_DOWN && ostatus) {
373 printf(LMC_PRINTF_FMT ": physical link down\n",
374 LMC_PRINTF_ARGS);
375 sc->lmc_flags &= ~LMC_MODEMOK;
376 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
377 sc->lmc_cardtype == LMC_CARDTYPE_T1)
378 lmc_led_on (sc, LMC_DS3_LED3 | LMC_DS3_LED2);
379
380 else {
381 lmc_led_off (sc, LMC_MII16_LED1);
382 lmc_led_on (sc, LMC_MII16_LED0);
383 if (sc->lmc_timing == LMC_CTL_CLOCK_SOURCE_EXT)
384 lmc_led_on (sc, LMC_MII16_LED3);
385 }
386
387 }
388
389
390
391
392
393 if (link_status != LMC_LINK_DOWN && !ostatus) {
394 printf(LMC_PRINTF_FMT ": physical link up\n",
395 LMC_PRINTF_ARGS);
396 if (sc->lmc_flags & LMC_IFUP)
397 lmc_ifup(sc);
398 sc->lmc_flags |= LMC_MODEMOK;
399 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
400 sc->lmc_cardtype == LMC_CARDTYPE_T1)
401 {
402 sc->lmc_miireg16 |= LMC_DS3_LED3;
403 lmc_led_off (sc, LMC_DS3_LED3);
404
405 lmc_led_on (sc, LMC_DS3_LED2);
406 } else {
407 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED1
408 | LMC_MII16_LED2);
409 if (sc->lmc_timing != LMC_CTL_CLOCK_SOURCE_EXT)
410 lmc_led_off (sc, LMC_MII16_LED3);
411 }
412
413 return;
414 }
415
416
417 sc->lmc_media->watchdog(sc);
418
419
420
421
422 ticks = LMC_CSR_READ(sc, csr_gp_timer);
423 LMC_CSR_WRITE(sc, csr_gp_timer, 0xffffffffUL);
424 sc->ictl.ticks = 0x0000ffff - (ticks & 0x0000ffff);
425
426 ifp->if_timer = 1;
427 }
428
429
430
431
432
433 static void
434 lmc_ifup(lmc_softc_t * const sc)
435 {
436 sc->lmc_if.if_timer = 0;
437
438 lmc_dec_reset(sc);
439 lmc_reset(sc);
440
441 sc->lmc_media->set_link_status(sc, LMC_LINK_UP);
442 sc->lmc_media->set_status(sc, NULL);
443
444 sc->lmc_flags |= LMC_IFUP;
445
446
447
448
449 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
450 sc->lmc_cardtype == LMC_CARDTYPE_T1)
451 lmc_led_on (sc, LMC_MII16_LED2);
452 else
453 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
454
455
456
457
458 sc->lmc_intrmask |= (TULIP_STS_NORMALINTR
459 | TULIP_STS_RXINTR
460 | TULIP_STS_RXNOBUF
461 | TULIP_STS_TXINTR
462 | TULIP_STS_ABNRMLINTR
463 | TULIP_STS_SYSERROR
464 | TULIP_STS_TXSTOPPED
465 | TULIP_STS_TXUNDERFLOW
466 | TULIP_STS_RXSTOPPED
467 );
468 LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);
469
470 sc->lmc_cmdmode |= TULIP_CMD_TXRUN;
471 sc->lmc_cmdmode |= TULIP_CMD_RXRUN;
472 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
473
474 sc->lmc_if.if_timer = 1;
475 }
476
477
478
479
480
481 static void
482 lmc_ifdown(lmc_softc_t * const sc)
483 {
484 sc->lmc_if.if_timer = 0;
485 sc->lmc_flags &= ~LMC_IFUP;
486
487 sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
488 lmc_led_off(sc, LMC_MII16_LED_ALL);
489
490 lmc_dec_reset(sc);
491 lmc_reset(sc);
492 sc->lmc_media->set_status(sc, NULL);
493 }
494
495 static void
496 lmc_rx_intr(lmc_softc_t * const sc)
497 {
498 lmc_ringinfo_t * const ri = &sc->lmc_rxinfo;
499 struct ifnet * const ifp = &sc->lmc_if;
500 u_int32_t status;
501 int fillok = 1;
502
503 sc->lmc_rxtick++;
504
505 for (;;) {
506 lmc_desc_t *eop = ri->ri_nextin;
507 int total_len = 0, last_offset = 0;
508 struct mbuf *ms = NULL, *me = NULL;
509 int accept = 0;
510 bus_dmamap_t map;
511 int error;
512
513 if (fillok && sc->lmc_rxq.ifq_len < LMC_RXQ_TARGET)
514 goto queue_mbuf;
515
516
517
518
519
520 if (eop == ri->ri_nextout)
521 break;
522
523
524
525
526
527 LMC_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
528 status = letoh32(((volatile lmc_desc_t *) eop)->d_status);
529 if ((status &
530 (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) ==
531 (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
532 IF_DEQUEUE(&sc->lmc_rxq, ms);
533 me = ms;
534 } else {
535
536
537
538 if (status & TULIP_DSTS_OWNER)
539 break;
540
541
542
543
544
545
546
547 while ((status & TULIP_DSTS_RxLASTDESC) == 0) {
548 if (++eop == ri->ri_last)
549 eop = ri->ri_first;
550 LMC_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
551 status = letoh32(((volatile lmc_desc_t *)
552 eop)->d_status);
553 if (eop == ri->ri_nextout ||
554 (status & TULIP_DSTS_OWNER)) {
555 return;
556 }
557 total_len++;
558 }
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573 IF_DEQUEUE(&sc->lmc_rxq, ms);
574 for (me = ms; total_len > 0; total_len--) {
575 map = LMC_GETCTX(me, bus_dmamap_t);
576 LMC_RXMAP_POSTSYNC(sc, map);
577 bus_dmamap_unload(sc->lmc_dmatag, map);
578 sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
579 #if defined(DIAGNOSTIC)
580 LMC_SETCTX(me, NULL);
581 #endif
582 me->m_len = LMC_RX_BUFLEN;
583 last_offset += LMC_RX_BUFLEN;
584 IF_DEQUEUE(&sc->lmc_rxq, me->m_next);
585 me = me->m_next;
586 }
587 }
588
589
590
591
592 total_len = ((status >> 16) & 0x7FFF);
593 if (sc->ictl.crc_length == 16)
594 total_len -= 2;
595 else
596 total_len -= 4;
597
598 if ((sc->lmc_flags & LMC_RXIGNORE) == 0
599 && ((status & LMC_DSTS_ERRSUM) == 0
600 #ifdef BIG_PACKET
601 || (total_len <= sc->lmc_if.if_mtu + PPP_HEADER_LEN
602 && (status & TULIP_DSTS_RxOVERFLOW) == 0)
603 #endif
604 )) {
605
606 map = LMC_GETCTX(me, bus_dmamap_t);
607 bus_dmamap_sync(sc->lmc_dmatag, map, 0, me->m_len,
608 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
609 bus_dmamap_unload(sc->lmc_dmatag, map);
610 sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
611 #if defined(DIAGNOSTIC)
612 LMC_SETCTX(me, NULL);
613 #endif
614
615 me->m_len = total_len - last_offset;
616 #if NBPFILTER > 0
617 if (sc->lmc_bpf != NULL) {
618 if (me == ms)
619 LMC_BPF_TAP(sc, mtod(ms, caddr_t),
620 total_len, BPF_DIRECTION_IN);
621 else
622 LMC_BPF_MTAP(sc, ms, BPF_DIRECTION_IN);
623 }
624 #endif
625 sc->lmc_flags |= LMC_RXACT;
626 accept = 1;
627 } else {
628 ifp->if_ierrors++;
629 if (status & TULIP_DSTS_RxOVERFLOW) {
630 sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
631 }
632 map = LMC_GETCTX(me, bus_dmamap_t);
633 bus_dmamap_unload(sc->lmc_dmatag, map);
634 sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
635 #if defined(DIAGNOSTIC)
636 LMC_SETCTX(me, NULL);
637 #endif
638 }
639
640 ifp->if_ipackets++;
641 if (++eop == ri->ri_last)
642 eop = ri->ri_first;
643 ri->ri_nextin = eop;
644
645 queue_mbuf:
646
647
648
649
650
651
652
653
654
655
656
657
658
659 if (accept || ms == NULL) {
660 struct mbuf *m0;
661 MGETHDR(m0, M_DONTWAIT, MT_DATA);
662 if (m0 != NULL) {
663 MCLGET(m0, M_DONTWAIT);
664 if ((m0->m_flags & M_EXT) == 0) {
665 m_freem(m0);
666 m0 = NULL;
667 }
668 }
669 if (accept) {
670 ms->m_pkthdr.len = total_len;
671 ms->m_pkthdr.rcvif = ifp;
672 sppp_input(ifp, ms);
673 }
674 ms = m0;
675 }
676 if (ms == NULL) {
677
678
679
680
681 fillok = 0;
682 sc->lmc_flags |= LMC_RXBUFSLOW;
683 continue;
684 }
685
686
687
688
689 do {
690 u_int32_t ctl;
691 lmc_desc_t * const nextout = ri->ri_nextout;
692
693 if (sc->lmc_rxmaps_free > 0) {
694 map = sc->lmc_rxmaps[--sc->lmc_rxmaps_free];
695 } else {
696 m_freem(ms);
697 sc->lmc_flags |= LMC_RXBUFSLOW;
698 #if defined(LMC_DEBUG)
699 sc->lmc_dbg.dbg_rxlowbufs++;
700 #endif
701 break;
702 }
703 LMC_SETCTX(ms, map);
704 error = bus_dmamap_load(sc->lmc_dmatag, map,
705 mtod(ms, void *), LMC_RX_BUFLEN,
706 NULL, BUS_DMA_NOWAIT);
707 if (error) {
708 printf(LMC_PRINTF_FMT
709 ": unable to load rx map, "
710 "error = %d\n",
711 LMC_PRINTF_ARGS, error);
712 panic("lmc_rx_intr");
713 }
714
715 ctl = letoh32(nextout->d_ctl);
716
717 if ((nextout+1) == ri->ri_last)
718 ctl = LMC_CTL(LMC_CTL_FLGS(ctl)|
719 TULIP_DFLAG_ENDRING, 0, 0);
720 nextout->d_addr1 = htole32(map->dm_segs[0].ds_addr);
721 if (map->dm_nsegs == 2) {
722 nextout->d_addr2 = htole32(map->dm_segs[1].ds_addr);
723 nextout->d_ctl =
724 htole32(LMC_CTL(LMC_CTL_FLGS(ctl),
725 map->dm_segs[0].ds_len,
726 map->dm_segs[1].ds_len));
727 } else {
728 nextout->d_addr2 = 0;
729 nextout->d_ctl =
730 htole32(LMC_CTL(LMC_CTL_FLGS(ctl),
731 map->dm_segs[0].ds_len, 0));
732 }
733 LMC_RXDESC_POSTSYNC(sc, nextout, sizeof(*nextout));
734 ri->ri_nextout->d_status = htole32(TULIP_DSTS_OWNER);
735 LMC_RXDESC_POSTSYNC(sc, nextout, sizeof(u_int32_t));
736 if (++ri->ri_nextout == ri->ri_last)
737 ri->ri_nextout = ri->ri_first;
738 me = ms->m_next;
739 ms->m_next = NULL;
740 IF_ENQUEUE(&sc->lmc_rxq, ms);
741 } while ((ms = me) != NULL);
742
743 if (sc->lmc_rxq.ifq_len >= LMC_RXQ_TARGET)
744 sc->lmc_flags &= ~LMC_RXBUFSLOW;
745 }
746 }
747
748 static int
749 lmc_tx_intr(lmc_softc_t * const sc)
750 {
751 lmc_ringinfo_t * const ri = &sc->lmc_txinfo;
752 struct mbuf *m;
753 int xmits = 0;
754 int descs = 0;
755 u_int32_t d_status;
756
757 sc->lmc_txtick++;
758
759 while (ri->ri_free < ri->ri_max) {
760 u_int32_t flag;
761
762 LMC_TXDESC_POSTSYNC(sc, ri->ri_nextin, sizeof(*ri->ri_nextin));
763 d_status = letoh32(((volatile lmc_desc_t *) ri->ri_nextin)->d_status);
764 if (d_status & TULIP_DSTS_OWNER)
765 break;
766
767 flag = LMC_CTL_FLGS(letoh32(ri->ri_nextin->d_ctl));
768 if (flag & TULIP_DFLAG_TxLASTSEG) {
769 IF_DEQUEUE(&sc->lmc_txq, m);
770 if (m != NULL) {
771 bus_dmamap_t map = LMC_GETCTX(m, bus_dmamap_t);
772 LMC_TXMAP_POSTSYNC(sc, map);
773 sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
774 #if NBPFILTER > 0
775 if (sc->lmc_bpf != NULL)
776 LMC_BPF_MTAP(sc, m, BPF_DIRECTION_OUT);
777 #endif
778 m_freem(m);
779 #if defined(LMC_DEBUG)
780 } else {
781 printf(LMC_PRINTF_FMT ": tx_intr: failed to dequeue mbuf?!?\n", LMC_PRINTF_ARGS);
782 #endif
783 }
784 xmits++;
785 if (d_status & LMC_DSTS_ERRSUM) {
786 sc->lmc_if.if_oerrors++;
787 if (d_status & TULIP_DSTS_TxUNDERFLOW) {
788 sc->lmc_dot3stats.dot3StatsInternalTransmitUnderflows++;
789 }
790 } else {
791 if (d_status & TULIP_DSTS_TxDEFERRED) {
792 sc->lmc_dot3stats.dot3StatsDeferredTransmissions++;
793 }
794 }
795 }
796
797 if (++ri->ri_nextin == ri->ri_last)
798 ri->ri_nextin = ri->ri_first;
799
800 ri->ri_free++;
801 descs++;
802 sc->lmc_if.if_flags &= ~IFF_OACTIVE;
803 }
804
805
806
807
808 sc->lmc_if.if_opackets += xmits;
809
810 return descs;
811 }
812
813 static void
814 lmc_print_abnormal_interrupt (lmc_softc_t * const sc, u_int32_t csr)
815 {
816 printf(LMC_PRINTF_FMT ": Abnormal interrupt\n", LMC_PRINTF_ARGS);
817 }
818
819 static const char * const lmc_system_errors[] = {
820 "parity error",
821 "master abort",
822 "target abort",
823 "reserved #3",
824 "reserved #4",
825 "reserved #5",
826 "reserved #6",
827 "reserved #7",
828 };
829
830 static void
831 lmc_intr_handler(lmc_softc_t * const sc, int *progress_p)
832 {
833 u_int32_t csr;
834
835 while ((csr = LMC_CSR_READ(sc, csr_status)) & sc->lmc_intrmask) {
836
837 *progress_p = 1;
838 LMC_CSR_WRITE(sc, csr_status, csr);
839
840 if (csr & TULIP_STS_SYSERROR) {
841 sc->lmc_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
842 if (sc->lmc_flags & LMC_NOMESSAGES) {
843 sc->lmc_flags |= LMC_SYSTEMERROR;
844 } else {
845 printf(LMC_PRINTF_FMT ": system error: %s\n",
846 LMC_PRINTF_ARGS,
847 lmc_system_errors[sc->lmc_last_system_error]);
848 }
849 sc->lmc_flags |= LMC_NEEDRESET;
850 sc->lmc_system_errors++;
851 break;
852 }
853 if (csr & (TULIP_STS_RXINTR | TULIP_STS_RXNOBUF)) {
854 u_int32_t misses = LMC_CSR_READ(sc, csr_missed_frames);
855 if (csr & TULIP_STS_RXNOBUF)
856 sc->lmc_dot3stats.dot3StatsMissedFrames += misses & 0xFFFF;
857
858
859
860
861 if ((misses & 0x0FFE0000) && (sc->lmc_features & LMC_HAVE_RXBADOVRFLW)) {
862 sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
863
864
865
866
867 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode & ~TULIP_CMD_RXRUN);
868 while ((LMC_CSR_READ(sc, csr_status) & TULIP_STS_RXSTOPPED) == 0)
869 ;
870 LMC_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
871 sc->lmc_flags |= LMC_RXIGNORE;
872 }
873 lmc_rx_intr(sc);
874 if (sc->lmc_flags & LMC_RXIGNORE) {
875
876
877
878 sc->lmc_flags &= ~LMC_RXIGNORE;
879 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
880 }
881 }
882 if (csr & TULIP_STS_ABNRMLINTR) {
883 u_int32_t tmp = csr & sc->lmc_intrmask
884 & ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
885 if (csr & TULIP_STS_TXUNDERFLOW) {
886 if ((sc->lmc_cmdmode & TULIP_CMD_THRESHOLDCTL) != TULIP_CMD_THRSHLD160) {
887 sc->lmc_cmdmode += TULIP_CMD_THRSHLD96;
888 sc->lmc_flags |= LMC_NEWTXTHRESH;
889 } else if (sc->lmc_features & LMC_HAVE_STOREFWD) {
890 sc->lmc_cmdmode |= TULIP_CMD_STOREFWD;
891 sc->lmc_flags |= LMC_NEWTXTHRESH;
892 }
893 }
894 if (sc->lmc_flags & LMC_NOMESSAGES) {
895 sc->lmc_statusbits |= tmp;
896 } else {
897 lmc_print_abnormal_interrupt(sc, tmp);
898 sc->lmc_flags |= LMC_NOMESSAGES;
899 }
900 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
901 }
902
903 if (csr & TULIP_STS_TXINTR)
904 lmc_tx_intr(sc);
905
906 if (sc->lmc_flags & LMC_WANTTXSTART)
907 lmc_ifstart(&sc->lmc_if);
908 }
909 }
910
911 lmc_intrfunc_t
912 lmc_intr_normal(void *arg)
913 {
914 lmc_softc_t * sc = (lmc_softc_t *) arg;
915 int progress = 0;
916
917 lmc_intr_handler(sc, &progress);
918
919 #if !defined(LMC_VOID_INTRFUNC)
920 return progress;
921 #endif
922 }
923
924 static struct mbuf *
925 lmc_mbuf_compress(struct mbuf *m)
926 {
927 struct mbuf *m0;
928 #if MCLBYTES >= LMC_MTU + PPP_HEADER_LEN && !defined(BIG_PACKET)
929 MGETHDR(m0, M_DONTWAIT, MT_DATA);
930 if (m0 != NULL) {
931 if (m->m_pkthdr.len > MHLEN) {
932 MCLGET(m0, M_DONTWAIT);
933 if ((m0->m_flags & M_EXT) == 0) {
934 m_freem(m);
935 m_freem(m0);
936 return NULL;
937 }
938 }
939 m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
940 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
941 }
942 #else
943 int mlen = MHLEN;
944 int len = m->m_pkthdr.len;
945 struct mbuf **mp = &m0;
946
947 while (len > 0) {
948 if (mlen == MHLEN) {
949 MGETHDR(*mp, M_DONTWAIT, MT_DATA);
950 } else {
951 MGET(*mp, M_DONTWAIT, MT_DATA);
952 }
953 if (*mp == NULL) {
954 m_freem(m0);
955 m0 = NULL;
956 break;
957 }
958 if (len > MLEN) {
959 MCLGET(*mp, M_DONTWAIT);
960 if (((*mp)->m_flags & M_EXT) == 0) {
961 m_freem(m0);
962 m0 = NULL;
963 break;
964 }
965 (*mp)->m_len = (len <= MCLBYTES ? len : MCLBYTES);
966 } else {
967 (*mp)->m_len = (len <= mlen ? len : mlen);
968 }
969 m_copydata(m, m->m_pkthdr.len - len,
970 (*mp)->m_len, mtod((*mp), caddr_t));
971 len -= (*mp)->m_len;
972 mp = &(*mp)->m_next;
973 mlen = MLEN;
974 }
975 #endif
976 m_freem(m);
977 return m0;
978 }
979
980
981
982
983
984 static struct mbuf *
985 lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
986 {
987 lmc_ringinfo_t * const ri = &sc->lmc_txinfo;
988 lmc_desc_t *eop, *nextout;
989 int segcnt, free;
990 u_int32_t d_status, ctl;
991 bus_dmamap_t map;
992 int error;
993
994 #if defined(LMC_DEBUG)
995 if ((sc->lmc_cmdmode & TULIP_CMD_TXRUN) == 0) {
996 printf(LMC_PRINTF_FMT ": txput: tx not running\n",
997 LMC_PRINTF_ARGS);
998 sc->lmc_flags |= LMC_WANTTXSTART;
999 goto finish;
1000 }
1001 #endif
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020 d_status = 0;
1021 eop = nextout = ri->ri_nextout;
1022 segcnt = 0;
1023 free = ri->ri_free;
1024
1025
1026
1027 if (sc->lmc_txmaps_free == 0) {
1028 #if defined(LMC_DEBUG)
1029 sc->lmc_dbg.dbg_no_txmaps++;
1030 #endif
1031 free += lmc_tx_intr(sc);
1032 }
1033 if (sc->lmc_txmaps_free > 0) {
1034 map = sc->lmc_txmaps[sc->lmc_txmaps_free-1];
1035 } else {
1036 sc->lmc_flags |= LMC_WANTTXSTART;
1037 #if defined(LMC_DEBUG)
1038 sc->lmc_dbg.dbg_txput_finishes[1]++;
1039 #endif
1040 goto finish;
1041 }
1042 error = bus_dmamap_load_mbuf(sc->lmc_dmatag, map, m, BUS_DMA_NOWAIT);
1043 if (error != 0) {
1044 if (error == EFBIG) {
1045
1046
1047
1048
1049
1050 m = lmc_mbuf_compress(m);
1051 if (m == NULL) {
1052 #if defined(LMC_DEBUG)
1053 sc->lmc_dbg.dbg_txput_finishes[2]++;
1054 #endif
1055 goto finish;
1056 }
1057 error = bus_dmamap_load_mbuf(sc->lmc_dmatag, map, m,
1058 BUS_DMA_NOWAIT);
1059 }
1060 if (error != 0) {
1061 printf(LMC_PRINTF_FMT ": unable to load tx map, "
1062 "error = %d\n", LMC_PRINTF_ARGS, error);
1063 #if defined(LMC_DEBUG)
1064 sc->lmc_dbg.dbg_txput_finishes[3]++;
1065 #endif
1066 goto finish;
1067 }
1068 }
1069 if ((free -= (map->dm_nsegs + 1) / 2) <= 0
1070
1071
1072
1073 && (free += lmc_tx_intr(sc)) <= 0) {
1074
1075
1076
1077
1078
1079
1080 sc->lmc_flags |= LMC_WANTTXSTART;
1081 #if defined(LMC_DEBUG)
1082 sc->lmc_dbg.dbg_txput_finishes[4]++;
1083 #endif
1084 bus_dmamap_unload(sc->lmc_dmatag, map);
1085 goto finish;
1086 }
1087 for (; map->dm_nsegs - segcnt > 1; segcnt += 2) {
1088 int flg;
1089
1090 eop = nextout;
1091 flg = LMC_CTL_FLGS(letoh32(eop->d_ctl));
1092 flg &= TULIP_DFLAG_ENDRING;
1093 flg |= TULIP_DFLAG_TxNOPADDING;
1094 if (sc->ictl.crc_length == 16)
1095 flg |= TULIP_DFLAG_TxHASCRC;
1096 eop->d_status = htole32(d_status);
1097 eop->d_addr1 = htole32(map->dm_segs[segcnt].ds_addr);
1098 eop->d_addr2 = htole32(map->dm_segs[segcnt+1].ds_addr);
1099 eop->d_ctl = htole32(LMC_CTL(flg,
1100 map->dm_segs[segcnt].ds_len,
1101 map->dm_segs[segcnt+1].ds_len));
1102 d_status = TULIP_DSTS_OWNER;
1103 if (++nextout == ri->ri_last)
1104 nextout = ri->ri_first;
1105 }
1106 if (segcnt < map->dm_nsegs) {
1107 int flg;
1108
1109 eop = nextout;
1110 flg = LMC_CTL_FLGS(letoh32(eop->d_ctl));
1111 flg &= TULIP_DFLAG_ENDRING;
1112 flg |= TULIP_DFLAG_TxNOPADDING;
1113 if (sc->ictl.crc_length == 16)
1114 flg |= TULIP_DFLAG_TxHASCRC;
1115 eop->d_status = htole32(d_status);
1116 eop->d_addr1 = htole32(map->dm_segs[segcnt].ds_addr);
1117 eop->d_addr2 = 0;
1118 eop->d_ctl = htole32(LMC_CTL(flg,
1119 map->dm_segs[segcnt].ds_len, 0));
1120 if (++nextout == ri->ri_last)
1121 nextout = ri->ri_first;
1122 }
1123 LMC_TXMAP_PRESYNC(sc, map);
1124 LMC_SETCTX(m, map);
1125 map = NULL;
1126 --sc->lmc_txmaps_free;
1127
1128
1129
1130
1131
1132 IF_ENQUEUE(&sc->lmc_txq, m);
1133 m = NULL;
1134
1135
1136
1137
1138
1139
1140 nextout->d_status = 0;
1141 LMC_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
1142
1143
1144
1145
1146
1147 ctl = letoh32(eop->d_ctl);
1148 eop->d_ctl = htole32(LMC_CTL(
1149 LMC_CTL_FLGS(ctl)|TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR,
1150 LMC_CTL_LEN1(ctl),
1151 LMC_CTL_LEN2(ctl)));
1152
1153
1154
1155
1156
1157
1158 ctl = letoh32(ri->ri_nextout->d_ctl);
1159 ri->ri_nextout->d_ctl = htole32(LMC_CTL(
1160 LMC_CTL_FLGS(ctl)|TULIP_DFLAG_TxFIRSTSEG,
1161 LMC_CTL_LEN1(ctl),
1162 LMC_CTL_LEN2(ctl)));
1163 if (eop < ri->ri_nextout) {
1164 LMC_TXDESC_PRESYNC(sc, ri->ri_nextout,
1165 (caddr_t) ri->ri_last - (caddr_t) ri->ri_nextout);
1166 LMC_TXDESC_PRESYNC(sc, ri->ri_first,
1167 (caddr_t) (eop + 1) - (caddr_t) ri->ri_first);
1168 } else {
1169 LMC_TXDESC_PRESYNC(sc, ri->ri_nextout,
1170 (caddr_t) (eop + 1) - (caddr_t) ri->ri_nextout);
1171 }
1172 ri->ri_nextout->d_status = htole32(TULIP_DSTS_OWNER);
1173 LMC_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
1174
1175 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1176
1177
1178
1179
1180 ri->ri_nextout = nextout;
1181 ri->ri_free = free;
1182
1183
1184
1185
1186 sc->lmc_flags &= ~LMC_WANTTXSTART;
1187 sc->lmc_if.if_start = lmc_ifstart_one;
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 finish:
1199 if (sc->lmc_flags & LMC_WANTTXSTART) {
1200 sc->lmc_if.if_flags |= IFF_OACTIVE;
1201 sc->lmc_if.if_start = lmc_ifstart;
1202 }
1203
1204 return m;
1205 }
1206
1207
1208
1209
1210
1211 static int
1212 lmc_ifioctl(struct ifnet * ifp, ioctl_cmd_t cmd, caddr_t data)
1213 {
1214 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1215 int s;
1216 struct proc *p = curproc;
1217 int error = 0;
1218 struct ifreq *ifr = (struct ifreq *)data;
1219 u_int32_t new_state;
1220 u_int32_t old_state;
1221 lmc_ctl_t ctl;
1222
1223 s = LMC_RAISESPL();
1224
1225 switch (cmd) {
1226 case LMCIOCGINFO:
1227 error = copyout(&sc->ictl, ifr->ifr_data, sizeof(lmc_ctl_t));
1228
1229 goto out;
1230 break;
1231
1232 case LMCIOCSINFO:
1233 error = suser(p, 0);
1234 if (error)
1235 goto out;
1236
1237 error = copyin(ifr->ifr_data, &ctl, sizeof(lmc_ctl_t));
1238 if (error != 0)
1239 goto out;
1240
1241 sc->lmc_media->set_status(sc, &ctl);
1242
1243 goto out;
1244 break;
1245
1246 case SIOCSIFMTU:
1247
1248
1249
1250 if (ifr->ifr_mtu > LMC_MTU) {
1251 error = EINVAL;
1252 goto out;
1253 } else {
1254 ifp->if_mtu = ifr->ifr_mtu;
1255 }
1256 break;
1257 }
1258
1259
1260
1261
1262 error = sppp_ioctl(ifp, cmd, data);
1263 if (error != 0)
1264 goto out;
1265
1266
1267
1268
1269
1270 new_state = ifp->if_flags & IFF_UP;
1271 old_state = sc->lmc_flags & LMC_IFUP;
1272
1273 if (new_state && !old_state)
1274 lmc_ifup(sc);
1275 else if (!new_state && old_state)
1276 lmc_ifdown(sc);
1277
1278 out:
1279 LMC_RESTORESPL(s);
1280
1281 return error;
1282 }
1283
1284
1285
1286
1287
1288 static ifnet_ret_t
1289 lmc_ifstart(struct ifnet * const ifp)
1290 {
1291 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1292 struct mbuf *m, *m0;
1293
1294 if (sc->lmc_flags & LMC_IFUP) {
1295 while (sppp_isempty(ifp) == 0) {
1296 m = sppp_pick(ifp);
1297 if (m == NULL)
1298 break;
1299 if ((m = lmc_txput(sc, m)) != NULL)
1300 break;
1301 m0 = sppp_dequeue(ifp);
1302 #if defined(LMC_DEBUG)
1303 if (m0 != m)
1304 printf("lmc_ifstart: mbuf mismatch!\n");
1305 #endif
1306 }
1307 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1308 }
1309 }
1310
1311 static ifnet_ret_t
1312 lmc_ifstart_one(struct ifnet * const ifp)
1313 {
1314 lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
1315 struct mbuf *m, *m0;
1316
1317 if ((sc->lmc_flags & LMC_IFUP) && (sppp_isempty(ifp) == 0)) {
1318 m = sppp_pick(ifp);
1319 if ((m = lmc_txput(sc, m)) != NULL)
1320 return;
1321 m0 = sppp_dequeue(ifp);
1322 #if defined(LMC_DEBUG)
1323 if (m0 != m)
1324 printf("lmc_ifstart: mbuf mismatch!\n");
1325 #endif
1326 LMC_CSR_WRITE(sc, csr_txpoll, 1);
1327 }
1328 }
1329
1330
1331
1332
1333
1334 void
1335 lmc_attach(lmc_softc_t * const sc)
1336 {
1337 struct ifnet * const ifp = &sc->lmc_if;
1338
1339 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
1340 ifp->if_ioctl = lmc_ifioctl;
1341 ifp->if_start = lmc_ifstart;
1342 ifp->if_watchdog = lmc_watchdog;
1343 ifp->if_timer = 1;
1344 ifp->if_mtu = LMC_MTU;
1345 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
1346 IFQ_SET_READY(&ifp->if_snd);
1347
1348 if_attach(ifp);
1349 if_alloc_sadl(ifp);
1350
1351 sppp_attach((struct ifnet *)&sc->lmc_sppp);
1352 sc->lmc_sppp.pp_flags = PP_CISCO | PP_KEEPALIVE;
1353 sc->lmc_sppp.pp_framebytes = 3;
1354
1355 #if NBPFILTER > 0
1356 LMC_BPF_ATTACH(sc);
1357 #endif
1358
1359
1360
1361
1362 sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
1363
1364
1365
1366 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
1367 sc->lmc_cardtype == LMC_CARDTYPE_T1)
1368 lmc_led_on (sc, LMC_MII16_LED2);
1369 else
1370 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
1371 }
1372
1373 void
1374 lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
1375 lmc_desc_t *descs, int ndescs)
1376 {
1377 ri->ri_max = ndescs;
1378 ri->ri_first = descs;
1379 ri->ri_last = ri->ri_first + ri->ri_max;
1380 bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
1381 ri->ri_last[-1].d_ctl = htole32(LMC_CTL(TULIP_DFLAG_ENDRING, 0, 0));
1382 }