Annotation of sys/dev/pci/if_ste.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_ste.c,v 1.40 2007/07/17 23:25:15 krw Exp $ */
2: /*
3: * Copyright (c) 1997, 1998, 1999
4: * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed by Bill Paul.
17: * 4. Neither the name of the author nor the names of any co-contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31: * THE POSSIBILITY OF SUCH DAMAGE.
32: *
33: * $FreeBSD: src/sys/pci/if_ste.c,v 1.14 1999/12/07 20:14:42 wpaul Exp $
34: */
35:
36: #include "bpfilter.h"
37:
38: #include <sys/param.h>
39: #include <sys/systm.h>
40: #include <sys/mbuf.h>
41: #include <sys/protosw.h>
42: #include <sys/socket.h>
43: #include <sys/ioctl.h>
44: #include <sys/errno.h>
45: #include <sys/malloc.h>
46: #include <sys/kernel.h>
47: #include <sys/timeout.h>
48:
49: #include <net/if.h>
50: #include <net/if_dl.h>
51: #include <net/if_types.h>
52:
53: #ifdef INET
54: #include <netinet/in.h>
55: #include <netinet/in_systm.h>
56: #include <netinet/in_var.h>
57: #include <netinet/ip.h>
58: #include <netinet/if_ether.h>
59: #endif
60:
61: #include <net/if_media.h>
62:
63: #if NBPFILTER > 0
64: #include <net/bpf.h>
65: #endif
66:
67: #include <uvm/uvm_extern.h> /* for vtophys */
68:
69: #include <sys/device.h>
70:
71: #include <dev/mii/mii.h>
72: #include <dev/mii/miivar.h>
73:
74: #include <dev/pci/pcireg.h>
75: #include <dev/pci/pcivar.h>
76: #include <dev/pci/pcidevs.h>
77:
78: #define STE_USEIOSPACE
79:
80: #include <dev/pci/if_stereg.h>
81:
82: int ste_probe(struct device *, void *, void *);
83: void ste_attach(struct device *, struct device *, void *);
84: int ste_intr(void *);
85: void ste_shutdown(void *);
86: void ste_init(void *);
87: void ste_rxeoc(struct ste_softc *);
88: void ste_rxeof(struct ste_softc *);
89: void ste_txeoc(struct ste_softc *);
90: void ste_txeof(struct ste_softc *);
91: void ste_stats_update(void *);
92: void ste_stop(struct ste_softc *);
93: void ste_reset(struct ste_softc *);
94: int ste_ioctl(struct ifnet *, u_long, caddr_t);
95: int ste_encap(struct ste_softc *, struct ste_chain *,
96: struct mbuf *);
97: void ste_start(struct ifnet *);
98: void ste_watchdog(struct ifnet *);
99: int ste_newbuf(struct ste_softc *,
100: struct ste_chain_onefrag *,
101: struct mbuf *);
102: int ste_ifmedia_upd(struct ifnet *);
103: void ste_ifmedia_sts(struct ifnet *, struct ifmediareq *);
104:
105: void ste_mii_sync(struct ste_softc *);
106: void ste_mii_send(struct ste_softc *, u_int32_t, int);
107: int ste_mii_readreg(struct ste_softc *,
108: struct ste_mii_frame *);
109: int ste_mii_writereg(struct ste_softc *,
110: struct ste_mii_frame *);
111: int ste_miibus_readreg(struct device *, int, int);
112: void ste_miibus_writereg(struct device *, int, int, int);
113: void ste_miibus_statchg(struct device *);
114:
115: int ste_eeprom_wait(struct ste_softc *);
116: int ste_read_eeprom(struct ste_softc *, caddr_t, int,
117: int, int);
118: void ste_wait(struct ste_softc *);
119: void ste_setmulti(struct ste_softc *);
120: int ste_init_rx_list(struct ste_softc *);
121: void ste_init_tx_list(struct ste_softc *);
122:
123: #define STE_SETBIT4(sc, reg, x) \
124: CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | x)
125:
126: #define STE_CLRBIT4(sc, reg, x) \
127: CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~x)
128:
129: #define STE_SETBIT2(sc, reg, x) \
130: CSR_WRITE_2(sc, reg, CSR_READ_2(sc, reg) | x)
131:
132: #define STE_CLRBIT2(sc, reg, x) \
133: CSR_WRITE_2(sc, reg, CSR_READ_2(sc, reg) & ~x)
134:
135: #define STE_SETBIT1(sc, reg, x) \
136: CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) | x)
137:
138: #define STE_CLRBIT1(sc, reg, x) \
139: CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) & ~x)
140:
141:
142: #define MII_SET(x) STE_SETBIT1(sc, STE_PHYCTL, x)
143: #define MII_CLR(x) STE_CLRBIT1(sc, STE_PHYCTL, x)
144:
145: struct cfattach ste_ca = {
146: sizeof(struct ste_softc), ste_probe, ste_attach
147: };
148:
149: struct cfdriver ste_cd = {
150: 0, "ste", DV_IFNET
151: };
152:
153: /*
154: * Sync the PHYs by setting data bit and strobing the clock 32 times.
155: */
156: void
157: ste_mii_sync(struct ste_softc *sc)
158: {
159: int i;
160:
161: MII_SET(STE_PHYCTL_MDIR|STE_PHYCTL_MDATA);
162:
163: for (i = 0; i < 32; i++) {
164: MII_SET(STE_PHYCTL_MCLK);
165: DELAY(1);
166: MII_CLR(STE_PHYCTL_MCLK);
167: DELAY(1);
168: }
169:
170: return;
171: }
172:
173: /*
174: * Clock a series of bits through the MII.
175: */
176: void
177: ste_mii_send(struct ste_softc *sc, u_int32_t bits, int cnt)
178: {
179: int i;
180:
181: MII_CLR(STE_PHYCTL_MCLK);
182:
183: for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
184: if (bits & i) {
185: MII_SET(STE_PHYCTL_MDATA);
186: } else {
187: MII_CLR(STE_PHYCTL_MDATA);
188: }
189: DELAY(1);
190: MII_CLR(STE_PHYCTL_MCLK);
191: DELAY(1);
192: MII_SET(STE_PHYCTL_MCLK);
193: }
194: }
195:
196: /*
197: * Read an PHY register through the MII.
198: */
199: int
200: ste_mii_readreg(struct ste_softc *sc, struct ste_mii_frame *frame)
201: {
202: int ack, i, s;
203:
204: s = splnet();
205:
206: /*
207: * Set up frame for RX.
208: */
209: frame->mii_stdelim = STE_MII_STARTDELIM;
210: frame->mii_opcode = STE_MII_READOP;
211: frame->mii_turnaround = 0;
212: frame->mii_data = 0;
213:
214: CSR_WRITE_2(sc, STE_PHYCTL, 0);
215: /*
216: * Turn on data xmit.
217: */
218: MII_SET(STE_PHYCTL_MDIR);
219:
220: ste_mii_sync(sc);
221:
222: /*
223: * Send command/address info.
224: */
225: ste_mii_send(sc, frame->mii_stdelim, 2);
226: ste_mii_send(sc, frame->mii_opcode, 2);
227: ste_mii_send(sc, frame->mii_phyaddr, 5);
228: ste_mii_send(sc, frame->mii_regaddr, 5);
229:
230: /* Turn off xmit. */
231: MII_CLR(STE_PHYCTL_MDIR);
232:
233: /* Idle bit */
234: MII_CLR((STE_PHYCTL_MCLK|STE_PHYCTL_MDATA));
235: DELAY(1);
236: MII_SET(STE_PHYCTL_MCLK);
237: DELAY(1);
238:
239: /* Check for ack */
240: MII_CLR(STE_PHYCTL_MCLK);
241: DELAY(1);
242: ack = CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA;
243: MII_SET(STE_PHYCTL_MCLK);
244: DELAY(1);
245:
246: /*
247: * Now try reading data bits. If the ack failed, we still
248: * need to clock through 16 cycles to keep the PHY(s) in sync.
249: */
250: if (ack) {
251: for(i = 0; i < 16; i++) {
252: MII_CLR(STE_PHYCTL_MCLK);
253: DELAY(1);
254: MII_SET(STE_PHYCTL_MCLK);
255: DELAY(1);
256: }
257: goto fail;
258: }
259:
260: for (i = 0x8000; i; i >>= 1) {
261: MII_CLR(STE_PHYCTL_MCLK);
262: DELAY(1);
263: if (!ack) {
264: if (CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA)
265: frame->mii_data |= i;
266: DELAY(1);
267: }
268: MII_SET(STE_PHYCTL_MCLK);
269: DELAY(1);
270: }
271:
272: fail:
273:
274: MII_CLR(STE_PHYCTL_MCLK);
275: DELAY(1);
276: MII_SET(STE_PHYCTL_MCLK);
277: DELAY(1);
278:
279: splx(s);
280:
281: if (ack)
282: return(1);
283: return(0);
284: }
285:
286: /*
287: * Write to a PHY register through the MII.
288: */
289: int
290: ste_mii_writereg(struct ste_softc *sc, struct ste_mii_frame *frame)
291: {
292: int s;
293:
294: s = splnet();
295: /*
296: * Set up frame for TX.
297: */
298:
299: frame->mii_stdelim = STE_MII_STARTDELIM;
300: frame->mii_opcode = STE_MII_WRITEOP;
301: frame->mii_turnaround = STE_MII_TURNAROUND;
302:
303: /*
304: * Turn on data output.
305: */
306: MII_SET(STE_PHYCTL_MDIR);
307:
308: ste_mii_sync(sc);
309:
310: ste_mii_send(sc, frame->mii_stdelim, 2);
311: ste_mii_send(sc, frame->mii_opcode, 2);
312: ste_mii_send(sc, frame->mii_phyaddr, 5);
313: ste_mii_send(sc, frame->mii_regaddr, 5);
314: ste_mii_send(sc, frame->mii_turnaround, 2);
315: ste_mii_send(sc, frame->mii_data, 16);
316:
317: /* Idle bit. */
318: MII_SET(STE_PHYCTL_MCLK);
319: DELAY(1);
320: MII_CLR(STE_PHYCTL_MCLK);
321: DELAY(1);
322:
323: /*
324: * Turn off xmit.
325: */
326: MII_CLR(STE_PHYCTL_MDIR);
327:
328: splx(s);
329:
330: return(0);
331: }
332:
333: int
334: ste_miibus_readreg(struct device *self, int phy, int reg)
335: {
336: struct ste_softc *sc = (struct ste_softc *)self;
337: struct ste_mii_frame frame;
338:
339: if (sc->ste_one_phy && phy != 0)
340: return (0);
341:
342: bzero((char *)&frame, sizeof(frame));
343:
344: frame.mii_phyaddr = phy;
345: frame.mii_regaddr = reg;
346: ste_mii_readreg(sc, &frame);
347:
348: return(frame.mii_data);
349: }
350:
351: void
352: ste_miibus_writereg(struct device *self, int phy, int reg, int data)
353: {
354: struct ste_softc *sc = (struct ste_softc *)self;
355: struct ste_mii_frame frame;
356:
357: bzero((char *)&frame, sizeof(frame));
358:
359: frame.mii_phyaddr = phy;
360: frame.mii_regaddr = reg;
361: frame.mii_data = data;
362:
363: ste_mii_writereg(sc, &frame);
364:
365: return;
366: }
367:
368: void
369: ste_miibus_statchg(struct device *self)
370: {
371: struct ste_softc *sc = (struct ste_softc *)self;
372: struct mii_data *mii;
373: int fdx, fcur;
374:
375: mii = &sc->sc_mii;
376:
377: fcur = CSR_READ_2(sc, STE_MACCTL0) & STE_MACCTL0_FULLDUPLEX;
378: fdx = (mii->mii_media_active & IFM_GMASK) == IFM_FDX;
379:
380: if ((fcur && fdx) || (! fcur && ! fdx))
381: return;
382:
383: STE_SETBIT4(sc, STE_DMACTL,
384: STE_DMACTL_RXDMA_STALL |STE_DMACTL_TXDMA_STALL);
385: ste_wait(sc);
386:
387: if (fdx)
388: STE_SETBIT2(sc, STE_MACCTL0, STE_MACCTL0_FULLDUPLEX);
389: else
390: STE_CLRBIT2(sc, STE_MACCTL0, STE_MACCTL0_FULLDUPLEX);
391:
392: STE_SETBIT4(sc, STE_DMACTL,
393: STE_DMACTL_RXDMA_UNSTALL | STE_DMACTL_TXDMA_UNSTALL);
394:
395: return;
396: }
397:
398: int
399: ste_ifmedia_upd(struct ifnet *ifp)
400: {
401: struct ste_softc *sc;
402: struct mii_data *mii;
403:
404: sc = ifp->if_softc;
405: mii = &sc->sc_mii;
406: sc->ste_link = 0;
407: if (mii->mii_instance) {
408: struct mii_softc *miisc;
409: LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
410: mii_phy_reset(miisc);
411: }
412: mii_mediachg(mii);
413:
414: return(0);
415: }
416:
417: void
418: ste_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
419: {
420: struct ste_softc *sc;
421: struct mii_data *mii;
422:
423: sc = ifp->if_softc;
424: mii = &sc->sc_mii;
425:
426: mii_pollstat(mii);
427: ifmr->ifm_active = mii->mii_media_active;
428: ifmr->ifm_status = mii->mii_media_status;
429:
430: return;
431: }
432:
433: void
434: ste_wait(struct ste_softc *sc)
435: {
436: int i;
437:
438: for (i = 0; i < STE_TIMEOUT; i++) {
439: if (!(CSR_READ_4(sc, STE_DMACTL) & STE_DMACTL_DMA_HALTINPROG))
440: break;
441: }
442:
443: if (i == STE_TIMEOUT)
444: printf("%s: command never completed!\n", sc->sc_dev.dv_xname);
445:
446: return;
447: }
448:
449: /*
450: * The EEPROM is slow: give it time to come ready after issuing
451: * it a command.
452: */
453: int
454: ste_eeprom_wait(struct ste_softc *sc)
455: {
456: int i;
457:
458: DELAY(1000);
459:
460: for (i = 0; i < 100; i++) {
461: if (CSR_READ_2(sc, STE_EEPROM_CTL) & STE_EECTL_BUSY)
462: DELAY(1000);
463: else
464: break;
465: }
466:
467: if (i == 100) {
468: printf("%s: eeprom failed to come ready\n",
469: sc->sc_dev.dv_xname);
470: return(1);
471: }
472:
473: return(0);
474: }
475:
476: /*
477: * Read a sequence of words from the EEPROM. Note that ethernet address
478: * data is stored in the EEPROM in network byte order.
479: */
480: int
481: ste_read_eeprom(struct ste_softc *sc, caddr_t dest, int off, int cnt, int swap)
482: {
483: int err = 0, i;
484: u_int16_t word = 0, *ptr;
485:
486: if (ste_eeprom_wait(sc))
487: return(1);
488:
489: for (i = 0; i < cnt; i++) {
490: CSR_WRITE_2(sc, STE_EEPROM_CTL, STE_EEOPCODE_READ | (off + i));
491: err = ste_eeprom_wait(sc);
492: if (err)
493: break;
494: word = CSR_READ_2(sc, STE_EEPROM_DATA);
495: ptr = (u_int16_t *)(dest + (i * 2));
496: if (swap)
497: *ptr = ntohs(word);
498: else
499: *ptr = word;
500: }
501:
502: return(err ? 1 : 0);
503: }
504:
505: void
506: ste_setmulti(struct ste_softc *sc)
507: {
508: struct ifnet *ifp;
509: struct arpcom *ac = &sc->arpcom;
510: struct ether_multi *enm;
511: struct ether_multistep step;
512: int h = 0;
513: u_int32_t hashes[2] = { 0, 0 };
514:
515: ifp = &sc->arpcom.ac_if;
516: allmulti:
517: if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
518: STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_ALLMULTI);
519: STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_MULTIHASH);
520: return;
521: }
522:
523: /* first, zot all the existing hash bits */
524: CSR_WRITE_2(sc, STE_MAR0, 0);
525: CSR_WRITE_2(sc, STE_MAR1, 0);
526: CSR_WRITE_2(sc, STE_MAR2, 0);
527: CSR_WRITE_2(sc, STE_MAR3, 0);
528:
529: /* now program new ones */
530: ETHER_FIRST_MULTI(step, ac, enm);
531: while (enm != NULL) {
532: if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
533: ifp->if_flags |= IFF_ALLMULTI;
534: goto allmulti;
535: }
536: h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3F;
537: if (h < 32)
538: hashes[0] |= (1 << h);
539: else
540: hashes[1] |= (1 << (h - 32));
541: ETHER_NEXT_MULTI(step, enm);
542: }
543:
544: CSR_WRITE_2(sc, STE_MAR0, hashes[0] & 0xFFFF);
545: CSR_WRITE_2(sc, STE_MAR1, (hashes[0] >> 16) & 0xFFFF);
546: CSR_WRITE_2(sc, STE_MAR2, hashes[1] & 0xFFFF);
547: CSR_WRITE_2(sc, STE_MAR3, (hashes[1] >> 16) & 0xFFFF);
548: STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_ALLMULTI);
549: STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_MULTIHASH);
550:
551: return;
552: }
553:
554: int
555: ste_intr(void *xsc)
556: {
557: struct ste_softc *sc;
558: struct ifnet *ifp;
559: u_int16_t status;
560: int claimed = 0;
561:
562: sc = xsc;
563: ifp = &sc->arpcom.ac_if;
564:
565: /* See if this is really our interrupt. */
566: if (!(CSR_READ_2(sc, STE_ISR) & STE_ISR_INTLATCH))
567: return claimed;
568:
569: for (;;) {
570: status = CSR_READ_2(sc, STE_ISR_ACK);
571:
572: if (!(status & STE_INTRS))
573: break;
574:
575: claimed = 1;
576:
577: if (status & STE_ISR_RX_DMADONE) {
578: ste_rxeoc(sc);
579: ste_rxeof(sc);
580: }
581:
582: if (status & STE_ISR_TX_DMADONE)
583: ste_txeof(sc);
584:
585: if (status & STE_ISR_TX_DONE)
586: ste_txeoc(sc);
587:
588: if (status & STE_ISR_STATS_OFLOW) {
589: timeout_del(&sc->sc_stats_tmo);
590: ste_stats_update(sc);
591: }
592:
593: if (status & STE_ISR_LINKEVENT)
594: mii_pollstat(&sc->sc_mii);
595:
596: if (status & STE_ISR_HOSTERR) {
597: ste_reset(sc);
598: ste_init(sc);
599: }
600: }
601:
602: /* Re-enable interrupts */
603: CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
604:
605: if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
606: ste_start(ifp);
607:
608: return claimed;
609: }
610:
611: void
612: ste_rxeoc(struct ste_softc *sc)
613: {
614: struct ste_chain_onefrag *cur_rx;
615:
616: if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
617: cur_rx = sc->ste_cdata.ste_rx_head;
618: do {
619: cur_rx = cur_rx->ste_next;
620: /* If the ring is empty, just return. */
621: if (cur_rx == sc->ste_cdata.ste_rx_head)
622: return;
623: } while (cur_rx->ste_ptr->ste_status == 0);
624: if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
625: /* We've fallen behind the chip: catch it. */
626: sc->ste_cdata.ste_rx_head = cur_rx;
627: }
628: }
629: }
630:
631: /*
632: * A frame has been uploaded: pass the resulting mbuf chain up to
633: * the higher level protocols.
634: */
635: void
636: ste_rxeof(struct ste_softc *sc)
637: {
638: struct mbuf *m;
639: struct ifnet *ifp;
640: struct ste_chain_onefrag *cur_rx;
641: int total_len = 0, count=0;
642: u_int32_t rxstat;
643:
644: ifp = &sc->arpcom.ac_if;
645:
646: while((rxstat = sc->ste_cdata.ste_rx_head->ste_ptr->ste_status)
647: & STE_RXSTAT_DMADONE) {
648: if ((STE_RX_LIST_CNT - count) < 3)
649: break;
650:
651: cur_rx = sc->ste_cdata.ste_rx_head;
652: sc->ste_cdata.ste_rx_head = cur_rx->ste_next;
653:
654: /*
655: * If an error occurs, update stats, clear the
656: * status word and leave the mbuf cluster in place:
657: * it should simply get re-used next time this descriptor
658: * comes up in the ring.
659: */
660: if (rxstat & STE_RXSTAT_FRAME_ERR) {
661: ifp->if_ierrors++;
662: cur_rx->ste_ptr->ste_status = 0;
663: continue;
664: }
665:
666: /*
667: * If there error bit was not set, the upload complete
668: * bit should be set which means we have a valid packet.
669: * If not, something truly strange has happened.
670: */
671: if (!(rxstat & STE_RXSTAT_DMADONE)) {
672: printf("%s: bad receive status -- packet dropped",
673: sc->sc_dev.dv_xname);
674: ifp->if_ierrors++;
675: cur_rx->ste_ptr->ste_status = 0;
676: continue;
677: }
678:
679: /* No errors; receive the packet. */
680: m = cur_rx->ste_mbuf;
681: total_len = cur_rx->ste_ptr->ste_status & STE_RXSTAT_FRAMELEN;
682:
683: /*
684: * Try to conjure up a new mbuf cluster. If that
685: * fails, it means we have an out of memory condition and
686: * should leave the buffer in place and continue. This will
687: * result in a lost packet, but there's little else we
688: * can do in this situation.
689: */
690: if (ste_newbuf(sc, cur_rx, NULL) == ENOBUFS) {
691: ifp->if_ierrors++;
692: cur_rx->ste_ptr->ste_status = 0;
693: continue;
694: }
695:
696: m->m_pkthdr.rcvif = ifp;
697: m->m_pkthdr.len = m->m_len = total_len;
698:
699: ifp->if_ipackets++;
700:
701: #if NBPFILTER > 0
702: if (ifp->if_bpf)
703: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
704: #endif
705:
706: /* pass it on. */
707: ether_input_mbuf(ifp, m);
708:
709: cur_rx->ste_ptr->ste_status = 0;
710: count++;
711: }
712:
713: return;
714: }
715:
716: void
717: ste_txeoc(struct ste_softc *sc)
718: {
719: u_int8_t txstat;
720: struct ifnet *ifp;
721:
722: ifp = &sc->arpcom.ac_if;
723:
724: while ((txstat = CSR_READ_1(sc, STE_TX_STATUS)) &
725: STE_TXSTATUS_TXDONE) {
726: if (txstat & STE_TXSTATUS_UNDERRUN ||
727: txstat & STE_TXSTATUS_EXCESSCOLLS ||
728: txstat & STE_TXSTATUS_RECLAIMERR) {
729: ifp->if_oerrors++;
730: printf("%s: transmission error: %x\n",
731: sc->sc_dev.dv_xname, txstat);
732:
733: ste_reset(sc);
734: ste_init(sc);
735:
736: if (txstat & STE_TXSTATUS_UNDERRUN &&
737: sc->ste_tx_thresh < ETHER_MAX_DIX_LEN) {
738: sc->ste_tx_thresh += STE_MIN_FRAMELEN;
739: printf("%s: tx underrun, increasing tx"
740: " start threshold to %d bytes\n",
741: sc->sc_dev.dv_xname, sc->ste_tx_thresh);
742: }
743: CSR_WRITE_2(sc, STE_TX_STARTTHRESH, sc->ste_tx_thresh);
744: CSR_WRITE_2(sc, STE_TX_RECLAIM_THRESH,
745: (ETHER_MAX_DIX_LEN >> 4));
746: }
747: ste_init(sc);
748: CSR_WRITE_2(sc, STE_TX_STATUS, txstat);
749: }
750:
751: return;
752: }
753:
754: void
755: ste_txeof(struct ste_softc *sc)
756: {
757: struct ste_chain *cur_tx = NULL;
758: struct ifnet *ifp;
759: int idx;
760:
761: ifp = &sc->arpcom.ac_if;
762:
763: idx = sc->ste_cdata.ste_tx_cons;
764: while(idx != sc->ste_cdata.ste_tx_prod) {
765: cur_tx = &sc->ste_cdata.ste_tx_chain[idx];
766:
767: if (!(cur_tx->ste_ptr->ste_ctl & STE_TXCTL_DMADONE))
768: break;
769:
770: m_freem(cur_tx->ste_mbuf);
771: cur_tx->ste_mbuf = NULL;
772: ifp->if_flags &= ~IFF_OACTIVE;
773: ifp->if_opackets++;
774:
775: STE_INC(idx, STE_TX_LIST_CNT);
776: }
777:
778: sc->ste_cdata.ste_tx_cons = idx;
779: if (idx == sc->ste_cdata.ste_tx_prod)
780: ifp->if_timer = 0;
781:
782: return;
783: }
784:
785: void
786: ste_stats_update(void *xsc)
787: {
788: struct ste_softc *sc;
789: struct ifnet *ifp;
790: struct mii_data *mii;
791: int s;
792:
793: s = splnet();
794:
795: sc = xsc;
796: ifp = &sc->arpcom.ac_if;
797: mii = &sc->sc_mii;
798:
799: ifp->if_collisions += CSR_READ_1(sc, STE_LATE_COLLS)
800: + CSR_READ_1(sc, STE_MULTI_COLLS)
801: + CSR_READ_1(sc, STE_SINGLE_COLLS);
802:
803: if (!sc->ste_link) {
804: mii_pollstat(mii);
805: if (mii->mii_media_status & IFM_ACTIVE &&
806: IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
807: sc->ste_link++;
808: /*
809: * we don't get a call-back on re-init so do it
810: * otherwise we get stuck in the wrong link state
811: */
812: ste_miibus_statchg((struct device *)sc);
813: if (!IFQ_IS_EMPTY(&ifp->if_snd))
814: ste_start(ifp);
815: }
816: }
817:
818: timeout_add(&sc->sc_stats_tmo, hz);
819: splx(s);
820:
821: return;
822: }
823:
824: const struct pci_matchid ste_devices[] = {
825: { PCI_VENDOR_SUNDANCE, PCI_PRODUCT_SUNDANCE_ST201_1 },
826: { PCI_VENDOR_SUNDANCE, PCI_PRODUCT_SUNDANCE_ST201_2 },
827: { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_550TX }
828: };
829:
830: /*
831: * Probe for a Sundance ST201 chip. Check the PCI vendor and device
832: * IDs against our list and return a device name if we find a match.
833: */
834: int
835: ste_probe(struct device *parent, void *match, void *aux)
836: {
837: return (pci_matchbyid((struct pci_attach_args *)aux, ste_devices,
838: sizeof(ste_devices)/sizeof(ste_devices[0])));
839: }
840:
841: /*
842: * Attach the interface. Allocate softc structures, do ifmedia
843: * setup and ethernet/BPF attach.
844: */
845: void
846: ste_attach(struct device *parent, struct device *self, void *aux)
847: {
848: const char *intrstr = NULL;
849: pcireg_t command;
850: struct ste_softc *sc = (struct ste_softc *)self;
851: struct pci_attach_args *pa = aux;
852: pci_chipset_tag_t pc = pa->pa_pc;
853: pci_intr_handle_t ih;
854: struct ifnet *ifp;
855: bus_size_t size;
856:
857: /*
858: * Handle power management nonsense.
859: */
860: command = pci_conf_read(pc, pa->pa_tag, STE_PCI_CAPID) & 0x000000FF;
861: if (command == 0x01) {
862:
863: command = pci_conf_read(pc, pa->pa_tag, STE_PCI_PWRMGMTCTRL);
864: if (command & STE_PSTATE_MASK) {
865: u_int32_t iobase, membase, irq;
866:
867: /* Save important PCI config data. */
868: iobase = pci_conf_read(pc, pa->pa_tag, STE_PCI_LOIO);
869: membase = pci_conf_read(pc, pa->pa_tag, STE_PCI_LOMEM);
870: irq = pci_conf_read(pc, pa->pa_tag, STE_PCI_INTLINE);
871:
872: /* Reset the power state. */
873: printf("%s: chip is in D%d power mode -- setting to D0\n",
874: sc->sc_dev.dv_xname, command & STE_PSTATE_MASK);
875: command &= 0xFFFFFFFC;
876: pci_conf_write(pc, pa->pa_tag, STE_PCI_PWRMGMTCTRL, command);
877:
878: /* Restore PCI config data. */
879: pci_conf_write(pc, pa->pa_tag, STE_PCI_LOIO, iobase);
880: pci_conf_write(pc, pa->pa_tag, STE_PCI_LOMEM, membase);
881: pci_conf_write(pc, pa->pa_tag, STE_PCI_INTLINE, irq);
882: }
883: }
884:
885: /*
886: * Only use one PHY since this chip reports multiple
887: * Note on the DFE-550 the PHY is at 1 on the DFE-580
888: * it is at 0 & 1. It is rev 0x12.
889: */
890: if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DLINK &&
891: PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DLINK_550TX &&
892: PCI_REVISION(pa->pa_class) == 0x12)
893: sc->ste_one_phy = 1;
894:
895: /*
896: * Map control/status registers.
897: */
898:
899: #ifdef STE_USEIOSPACE
900: if (pci_mapreg_map(pa, STE_PCI_LOIO,
901: PCI_MAPREG_TYPE_IO, 0,
902: &sc->ste_btag, &sc->ste_bhandle, NULL, &size, 0)) {
903: printf(": can't map i/o space\n");
904: return;
905: }
906: #else
907: if (pci_mapreg_map(pa, STE_PCI_LOMEM,
908: PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
909: &sc->ste_btag, &sc->ste_bhandle, NULL, &size, 0)) {
910: printf(": can't map mem space\n");
911: return;
912: }
913: #endif
914:
915: /* Allocate interrupt */
916: if (pci_intr_map(pa, &ih)) {
917: printf(": couldn't map interrupt\n");
918: goto fail_1;
919: }
920: intrstr = pci_intr_string(pc, ih);
921: sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ste_intr, sc,
922: self->dv_xname);
923: if (sc->sc_ih == NULL) {
924: printf(": couldn't establish interrupt");
925: if (intrstr != NULL)
926: printf(" at %s", intrstr);
927: printf("\n");
928: goto fail_1;
929: }
930: printf(": %s", intrstr);
931:
932: /* Reset the adapter. */
933: ste_reset(sc);
934:
935: /*
936: * Get station address from the EEPROM.
937: */
938: if (ste_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
939: STE_EEADDR_NODE0, 3, 0)) {
940: printf(": failed to read station address\n");
941: goto fail_2;
942: }
943:
944: printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
945:
946: sc->ste_ldata_ptr = malloc(sizeof(struct ste_list_data) + 8,
947: M_DEVBUF, M_DONTWAIT);
948: if (sc->ste_ldata_ptr == NULL) {
949: printf(": no memory for list buffers!\n");
950: goto fail_2;
951: }
952:
953: sc->ste_ldata = (struct ste_list_data *)sc->ste_ldata_ptr;
954: bzero(sc->ste_ldata, sizeof(struct ste_list_data));
955:
956: ifp = &sc->arpcom.ac_if;
957: ifp->if_softc = sc;
958: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
959: ifp->if_ioctl = ste_ioctl;
960: ifp->if_start = ste_start;
961: ifp->if_watchdog = ste_watchdog;
962: ifp->if_baudrate = 10000000;
963: IFQ_SET_MAXLEN(&ifp->if_snd, STE_TX_LIST_CNT - 1);
964: IFQ_SET_READY(&ifp->if_snd);
965: bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
966: ifp->if_capabilities = IFCAP_VLAN_MTU;
967:
968: sc->ste_tx_thresh = STE_TXSTART_THRESH;
969:
970: sc->sc_mii.mii_ifp = ifp;
971: sc->sc_mii.mii_readreg = ste_miibus_readreg;
972: sc->sc_mii.mii_writereg = ste_miibus_writereg;
973: sc->sc_mii.mii_statchg = ste_miibus_statchg;
974: ifmedia_init(&sc->sc_mii.mii_media, 0, ste_ifmedia_upd,ste_ifmedia_sts);
975: mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
976: 0);
977: if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
978: ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
979: ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
980: } else
981: ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
982:
983: /*
984: * Call MI attach routines.
985: */
986: if_attach(ifp);
987: ether_ifattach(ifp);
988:
989: shutdownhook_establish(ste_shutdown, sc);
990: return;
991:
992: fail_2:
993: pci_intr_disestablish(pc, sc->sc_ih);
994:
995: fail_1:
996: bus_space_unmap(sc->ste_btag, sc->ste_bhandle, size);
997: }
998:
999: int
1000: ste_newbuf(struct ste_softc *sc, struct ste_chain_onefrag *c, struct mbuf *m)
1001: {
1002: struct mbuf *m_new = NULL;
1003:
1004: if (m == NULL) {
1005: MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1006: if (m_new == NULL)
1007: return(ENOBUFS);
1008: MCLGET(m_new, M_DONTWAIT);
1009: if (!(m_new->m_flags & M_EXT)) {
1010: m_freem(m_new);
1011: return(ENOBUFS);
1012: }
1013: m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1014: } else {
1015: m_new = m;
1016: m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1017: m_new->m_data = m_new->m_ext.ext_buf;
1018: }
1019:
1020: m_adj(m_new, ETHER_ALIGN);
1021:
1022: c->ste_mbuf = m_new;
1023: c->ste_ptr->ste_status = 0;
1024: c->ste_ptr->ste_frag.ste_addr = vtophys(mtod(m_new, vaddr_t));
1025: c->ste_ptr->ste_frag.ste_len = (ETHER_MAX_DIX_LEN + ETHER_VLAN_ENCAP_LEN) | STE_FRAG_LAST;
1026:
1027: return(0);
1028: }
1029:
1030: int
1031: ste_init_rx_list(struct ste_softc *sc)
1032: {
1033: struct ste_chain_data *cd;
1034: struct ste_list_data *ld;
1035: int i;
1036:
1037: cd = &sc->ste_cdata;
1038: ld = sc->ste_ldata;
1039:
1040: for (i = 0; i < STE_RX_LIST_CNT; i++) {
1041: cd->ste_rx_chain[i].ste_ptr = &ld->ste_rx_list[i];
1042: if (ste_newbuf(sc, &cd->ste_rx_chain[i], NULL) == ENOBUFS)
1043: return(ENOBUFS);
1044: if (i == (STE_RX_LIST_CNT - 1)) {
1045: cd->ste_rx_chain[i].ste_next =
1046: &cd->ste_rx_chain[0];
1047: ld->ste_rx_list[i].ste_next =
1048: vtophys((vaddr_t)&ld->ste_rx_list[0]);
1049: } else {
1050: cd->ste_rx_chain[i].ste_next =
1051: &cd->ste_rx_chain[i + 1];
1052: ld->ste_rx_list[i].ste_next =
1053: vtophys((vaddr_t)&ld->ste_rx_list[i + 1]);
1054: }
1055: ld->ste_rx_list[i].ste_status = 0;
1056: }
1057:
1058: cd->ste_rx_head = &cd->ste_rx_chain[0];
1059:
1060: return(0);
1061: }
1062:
1063: void
1064: ste_init_tx_list(struct ste_softc *sc)
1065: {
1066: struct ste_chain_data *cd;
1067: struct ste_list_data *ld;
1068: int i;
1069:
1070: cd = &sc->ste_cdata;
1071: ld = sc->ste_ldata;
1072: for (i = 0; i < STE_TX_LIST_CNT; i++) {
1073: cd->ste_tx_chain[i].ste_ptr = &ld->ste_tx_list[i];
1074: cd->ste_tx_chain[i].ste_phys = vtophys((vaddr_t)&ld->ste_tx_list[i]);
1075: if (i == (STE_TX_LIST_CNT - 1))
1076: cd->ste_tx_chain[i].ste_next =
1077: &cd->ste_tx_chain[0];
1078: else
1079: cd->ste_tx_chain[i].ste_next =
1080: &cd->ste_tx_chain[i + 1];
1081: }
1082:
1083: bzero((char *)ld->ste_tx_list,
1084: sizeof(struct ste_desc) * STE_TX_LIST_CNT);
1085:
1086: cd->ste_tx_prod = 0;
1087: cd->ste_tx_cons = 0;
1088:
1089: return;
1090: }
1091:
1092: void
1093: ste_init(void *xsc)
1094: {
1095: struct ste_softc *sc = (struct ste_softc *)xsc;
1096: struct ifnet *ifp = &sc->arpcom.ac_if;
1097: struct mii_data *mii;
1098: int i, s;
1099:
1100: s = splnet();
1101:
1102: ste_stop(sc);
1103:
1104: mii = &sc->sc_mii;
1105:
1106: /* Init our MAC address */
1107: for (i = 0; i < ETHER_ADDR_LEN; i++) {
1108: CSR_WRITE_1(sc, STE_PAR0 + i, sc->arpcom.ac_enaddr[i]);
1109: }
1110:
1111: /* Init RX list */
1112: if (ste_init_rx_list(sc) == ENOBUFS) {
1113: printf("%s: initialization failed: no "
1114: "memory for RX buffers\n", sc->sc_dev.dv_xname);
1115: ste_stop(sc);
1116: splx(s);
1117: return;
1118: }
1119:
1120: /* Set RX polling interval */
1121: CSR_WRITE_1(sc, STE_RX_DMAPOLL_PERIOD, 64);
1122:
1123: /* Init TX descriptors */
1124: ste_init_tx_list(sc);
1125:
1126: /* Set the TX freethresh value */
1127: CSR_WRITE_1(sc, STE_TX_DMABURST_THRESH, ETHER_MAX_DIX_LEN >> 8);
1128:
1129: /* Set the TX start threshold for best performance. */
1130: CSR_WRITE_2(sc, STE_TX_STARTTHRESH, sc->ste_tx_thresh);
1131:
1132: /* Set the TX reclaim threshold. */
1133: CSR_WRITE_1(sc, STE_TX_RECLAIM_THRESH, (ETHER_MAX_DIX_LEN >> 4));
1134:
1135: /* Set up the RX filter. */
1136: CSR_WRITE_1(sc, STE_RX_MODE, STE_RXMODE_UNICAST);
1137:
1138: /* If we want promiscuous mode, set the allframes bit. */
1139: if (ifp->if_flags & IFF_PROMISC) {
1140: STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_PROMISC);
1141: } else {
1142: STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_PROMISC);
1143: }
1144:
1145: /* Set capture broadcast bit to accept broadcast frames. */
1146: if (ifp->if_flags & IFF_BROADCAST) {
1147: STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_BROADCAST);
1148: } else {
1149: STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_BROADCAST);
1150: }
1151:
1152: ste_setmulti(sc);
1153:
1154: /* Load the address of the RX list. */
1155: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_STALL);
1156: ste_wait(sc);
1157: CSR_WRITE_4(sc, STE_RX_DMALIST_PTR,
1158: vtophys((vaddr_t)&sc->ste_ldata->ste_rx_list[0]));
1159: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_UNSTALL);
1160: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_UNSTALL);
1161:
1162: /* Set TX polling interval (defer until we TX first packet) */
1163: CSR_WRITE_1(sc, STE_TX_DMAPOLL_PERIOD, 0);
1164:
1165: /* Load address of the TX list */
1166: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_STALL);
1167: ste_wait(sc);
1168: CSR_WRITE_4(sc, STE_TX_DMALIST_PTR, 0);
1169: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
1170: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
1171: ste_wait(sc);
1172: sc->ste_tx_prev=NULL;
1173:
1174: /* Enable receiver and transmitter */
1175: CSR_WRITE_2(sc, STE_MACCTL0, 0);
1176: CSR_WRITE_2(sc, STE_MACCTL1, 0);
1177: STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_TX_ENABLE);
1178: STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_RX_ENABLE);
1179:
1180: /* Enable stats counters. */
1181: STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_STATS_ENABLE);
1182:
1183: /* Enable interrupts. */
1184: CSR_WRITE_2(sc, STE_ISR, 0xFFFF);
1185: CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
1186:
1187: /* Accept VLAN length packets */
1188: CSR_WRITE_2(sc, STE_MAX_FRAMELEN,
1189: ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
1190:
1191: ste_ifmedia_upd(ifp);
1192:
1193: ifp->if_flags |= IFF_RUNNING;
1194: ifp->if_flags &= ~IFF_OACTIVE;
1195:
1196: splx(s);
1197:
1198: timeout_set(&sc->sc_stats_tmo, ste_stats_update, sc);
1199: timeout_add(&sc->sc_stats_tmo, hz);
1200:
1201: return;
1202: }
1203:
1204: void
1205: ste_stop(struct ste_softc *sc)
1206: {
1207: int i;
1208: struct ifnet *ifp;
1209:
1210: ifp = &sc->arpcom.ac_if;
1211:
1212: timeout_del(&sc->sc_stats_tmo);
1213:
1214: ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1215:
1216: CSR_WRITE_2(sc, STE_IMR, 0);
1217: STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_TX_DISABLE);
1218: STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_RX_DISABLE);
1219: STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_STATS_DISABLE);
1220: STE_SETBIT2(sc, STE_DMACTL, STE_DMACTL_TXDMA_STALL);
1221: STE_SETBIT2(sc, STE_DMACTL, STE_DMACTL_RXDMA_STALL);
1222: ste_wait(sc);
1223: /*
1224: * Try really hard to stop the RX engine or under heavy RX
1225: * data chip will write into de-allocated memory.
1226: */
1227: ste_reset(sc);
1228:
1229: sc->ste_link = 0;
1230:
1231: for (i = 0; i < STE_RX_LIST_CNT; i++) {
1232: if (sc->ste_cdata.ste_rx_chain[i].ste_mbuf != NULL) {
1233: m_freem(sc->ste_cdata.ste_rx_chain[i].ste_mbuf);
1234: sc->ste_cdata.ste_rx_chain[i].ste_mbuf = NULL;
1235: }
1236: }
1237:
1238: for (i = 0; i < STE_TX_LIST_CNT; i++) {
1239: if (sc->ste_cdata.ste_tx_chain[i].ste_mbuf != NULL) {
1240: m_freem(sc->ste_cdata.ste_tx_chain[i].ste_mbuf);
1241: sc->ste_cdata.ste_tx_chain[i].ste_mbuf = NULL;
1242: }
1243: }
1244:
1245: bzero(sc->ste_ldata, sizeof(struct ste_list_data));
1246:
1247: return;
1248: }
1249:
1250: void
1251: ste_reset(struct ste_softc *sc)
1252: {
1253: int i;
1254:
1255: STE_SETBIT4(sc, STE_ASICCTL,
1256: STE_ASICCTL_GLOBAL_RESET|STE_ASICCTL_RX_RESET|
1257: STE_ASICCTL_TX_RESET|STE_ASICCTL_DMA_RESET|
1258: STE_ASICCTL_FIFO_RESET|STE_ASICCTL_NETWORK_RESET|
1259: STE_ASICCTL_AUTOINIT_RESET|STE_ASICCTL_HOST_RESET|
1260: STE_ASICCTL_EXTRESET_RESET);
1261:
1262: DELAY(100000);
1263:
1264: for (i = 0; i < STE_TIMEOUT; i++) {
1265: if (!(CSR_READ_4(sc, STE_ASICCTL) & STE_ASICCTL_RESET_BUSY))
1266: break;
1267: }
1268:
1269: if (i == STE_TIMEOUT)
1270: printf("%s: global reset never completed\n",
1271: sc->sc_dev.dv_xname);
1272: }
1273:
1274: int
1275: ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1276: {
1277: struct ste_softc *sc = ifp->if_softc;
1278: struct ifreq *ifr = (struct ifreq *) data;
1279: struct ifaddr *ifa = (struct ifaddr *)data;
1280: struct mii_data *mii;
1281: int s, error = 0;
1282:
1283: s = splnet();
1284:
1285: if ((error = ether_ioctl(ifp, &sc->arpcom, command, data)) > 0) {
1286: splx(s);
1287: return error;
1288: }
1289:
1290: switch(command) {
1291: case SIOCSIFADDR:
1292: ifp->if_flags |= IFF_UP;
1293: switch (ifa->ifa_addr->sa_family) {
1294: case AF_INET:
1295: ste_init(sc);
1296: arp_ifinit(&sc->arpcom, ifa);
1297: break;
1298: default:
1299: ste_init(sc);
1300: break;
1301: }
1302: break;
1303: case SIOCSIFFLAGS:
1304: if (ifp->if_flags & IFF_UP) {
1305: if (ifp->if_flags & IFF_RUNNING &&
1306: ifp->if_flags & IFF_PROMISC &&
1307: !(sc->ste_if_flags & IFF_PROMISC)) {
1308: STE_SETBIT1(sc, STE_RX_MODE,
1309: STE_RXMODE_PROMISC);
1310: } else if (ifp->if_flags & IFF_RUNNING &&
1311: !(ifp->if_flags & IFF_PROMISC) &&
1312: sc->ste_if_flags & IFF_PROMISC) {
1313: STE_CLRBIT1(sc, STE_RX_MODE,
1314: STE_RXMODE_PROMISC);
1315: }
1316: if (ifp->if_flags & IFF_RUNNING &&
1317: (ifp->if_flags ^ sc->ste_if_flags) & IFF_ALLMULTI)
1318: ste_setmulti(sc);
1319: if (!(ifp->if_flags & IFF_RUNNING)) {
1320: sc->ste_tx_thresh = STE_TXSTART_THRESH;
1321: ste_init(sc);
1322: }
1323: } else {
1324: if (ifp->if_flags & IFF_RUNNING)
1325: ste_stop(sc);
1326: }
1327: sc->ste_if_flags = ifp->if_flags;
1328: error = 0;
1329: break;
1330: case SIOCADDMULTI:
1331: case SIOCDELMULTI:
1332: error = (command == SIOCADDMULTI) ?
1333: ether_addmulti(ifr, &sc->arpcom) :
1334: ether_delmulti(ifr, &sc->arpcom);
1335:
1336: if (error == ENETRESET) {
1337: /*
1338: * Multicast list has changed; set the hardware
1339: * filter accordingly.
1340: */
1341: if (ifp->if_flags & IFF_RUNNING)
1342: ste_setmulti(sc);
1343: error = 0;
1344: }
1345: break;
1346: case SIOCGIFMEDIA:
1347: case SIOCSIFMEDIA:
1348: mii = &sc->sc_mii;
1349: error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
1350: break;
1351: default:
1352: error = ENOTTY;
1353: break;
1354: }
1355:
1356: splx(s);
1357:
1358: return(error);
1359: }
1360:
1361: int
1362: ste_encap(struct ste_softc *sc, struct ste_chain *c, struct mbuf *m_head)
1363: {
1364: int frag = 0;
1365: struct ste_frag *f = NULL;
1366: struct mbuf *m;
1367: struct ste_desc *d;
1368:
1369: d = c->ste_ptr;
1370: d->ste_ctl = 0;
1371:
1372: encap_retry:
1373: for (m = m_head, frag = 0; m != NULL; m = m->m_next) {
1374: if (m->m_len != 0) {
1375: if (frag == STE_MAXFRAGS)
1376: break;
1377: f = &d->ste_frags[frag];
1378: f->ste_addr = vtophys(mtod(m, vaddr_t));
1379: f->ste_len = m->m_len;
1380: frag++;
1381: }
1382: }
1383:
1384: if (m != NULL) {
1385: struct mbuf *mn;
1386:
1387: /*
1388: * We ran out of segments. We have to recopy this
1389: * mbuf chain first. Bail out if we can't get the
1390: * new buffers.
1391: */
1392: MGETHDR(mn, M_DONTWAIT, MT_DATA);
1393: if (mn == NULL) {
1394: m_freem(m_head);
1395: return ENOMEM;
1396: }
1397: if (m_head->m_pkthdr.len > MHLEN) {
1398: MCLGET(mn, M_DONTWAIT);
1399: if ((mn->m_flags & M_EXT) == 0) {
1400: m_freem(mn);
1401: m_freem(m_head);
1402: return ENOMEM;
1403: }
1404: }
1405: m_copydata(m_head, 0, m_head->m_pkthdr.len,
1406: mtod(mn, caddr_t));
1407: mn->m_pkthdr.len = mn->m_len = m_head->m_pkthdr.len;
1408: m_freem(m_head);
1409: m_head = mn;
1410: goto encap_retry;
1411: }
1412:
1413: c->ste_mbuf = m_head;
1414: d->ste_frags[frag - 1].ste_len |= STE_FRAG_LAST;
1415: d->ste_ctl = 1;
1416:
1417: return(0);
1418: }
1419:
1420: void
1421: ste_start(struct ifnet *ifp)
1422: {
1423: struct ste_softc *sc;
1424: struct mbuf *m_head = NULL;
1425: struct ste_chain *cur_tx;
1426: int idx;
1427:
1428: sc = ifp->if_softc;
1429:
1430: if (!sc->ste_link)
1431: return;
1432:
1433: if (ifp->if_flags & IFF_OACTIVE)
1434: return;
1435:
1436: idx = sc->ste_cdata.ste_tx_prod;
1437:
1438: while(sc->ste_cdata.ste_tx_chain[idx].ste_mbuf == NULL) {
1439: /*
1440: * We cannot re-use the last (free) descriptor;
1441: * the chip may not have read its ste_next yet.
1442: */
1443: if (STE_NEXT(idx, STE_TX_LIST_CNT) ==
1444: sc->ste_cdata.ste_tx_cons) {
1445: ifp->if_flags |= IFF_OACTIVE;
1446: break;
1447: }
1448:
1449: IFQ_DEQUEUE(&ifp->if_snd, m_head);
1450: if (m_head == NULL)
1451: break;
1452:
1453: cur_tx = &sc->ste_cdata.ste_tx_chain[idx];
1454:
1455: if (ste_encap(sc, cur_tx, m_head) != 0)
1456: break;
1457:
1458: cur_tx->ste_ptr->ste_next = 0;
1459:
1460: if (sc->ste_tx_prev == NULL) {
1461: cur_tx->ste_ptr->ste_ctl = STE_TXCTL_DMAINTR | 1;
1462: /* Load address of the TX list */
1463: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_STALL);
1464: ste_wait(sc);
1465:
1466: CSR_WRITE_4(sc, STE_TX_DMALIST_PTR,
1467: vtophys((vaddr_t)&sc->ste_ldata->ste_tx_list[0]));
1468:
1469: /* Set TX polling interval to start TX engine */
1470: CSR_WRITE_1(sc, STE_TX_DMAPOLL_PERIOD, 64);
1471:
1472: STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
1473: ste_wait(sc);
1474: }else{
1475: cur_tx->ste_ptr->ste_ctl = STE_TXCTL_DMAINTR | 1;
1476: sc->ste_tx_prev->ste_ptr->ste_next
1477: = cur_tx->ste_phys;
1478: }
1479:
1480: sc->ste_tx_prev = cur_tx;
1481:
1482: #if NBPFILTER > 0
1483: /*
1484: * If there's a BPF listener, bounce a copy of this frame
1485: * to him.
1486: */
1487: if (ifp->if_bpf)
1488: bpf_mtap(ifp->if_bpf, cur_tx->ste_mbuf,
1489: BPF_DIRECTION_OUT);
1490: #endif
1491:
1492: STE_INC(idx, STE_TX_LIST_CNT);
1493: ifp->if_timer = 5;
1494: }
1495: sc->ste_cdata.ste_tx_prod = idx;
1496:
1497: return;
1498: }
1499:
1500: void
1501: ste_watchdog(struct ifnet *ifp)
1502: {
1503: struct ste_softc *sc;
1504:
1505: sc = ifp->if_softc;
1506:
1507: ifp->if_oerrors++;
1508: printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
1509:
1510: ste_txeoc(sc);
1511: ste_txeof(sc);
1512: ste_rxeoc(sc);
1513: ste_rxeof(sc);
1514: ste_reset(sc);
1515: ste_init(sc);
1516:
1517: if (!IFQ_IS_EMPTY(&ifp->if_snd))
1518: ste_start(ifp);
1519:
1520: return;
1521: }
1522:
1523: void
1524: ste_shutdown(void *v)
1525: {
1526: struct ste_softc *sc = (struct ste_softc *)v;
1527:
1528: ste_stop(sc);
1529: }
CVSweb