Annotation of sys/dev/pci/if_msk.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_msk.c,v 1.56 2007/06/27 19:15:47 kettenis Exp $ */
2:
3: /*
4: * Copyright (c) 1997, 1998, 1999, 2000
5: * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by Bill Paul.
18: * 4. Neither the name of the author nor the names of any co-contributors
19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32: * THE POSSIBILITY OF SUCH DAMAGE.
33: *
34: * $FreeBSD: /c/ncvs/src/sys/pci/if_sk.c,v 1.20 2000/04/22 02:16:37 wpaul Exp $
35: */
36:
37: /*
38: * Copyright (c) 2003 Nathan L. Binkert <binkertn@umich.edu>
39: *
40: * Permission to use, copy, modify, and distribute this software for any
41: * purpose with or without fee is hereby granted, provided that the above
42: * copyright notice and this permission notice appear in all copies.
43: *
44: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
45: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
46: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
47: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
48: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
49: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
50: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51: */
52:
53: /*
54: * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports
55: * the SK-984x series adapters, both single port and dual port.
56: * References:
57: * The XaQti XMAC II datasheet,
58: * http://www.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf
59: * The SysKonnect GEnesis manual, http://www.syskonnect.com
60: *
61: * Note: XaQti has been acquired by Vitesse, and Vitesse does not have the
62: * XMAC II datasheet online. I have put my copy at people.freebsd.org as a
63: * convenience to others until Vitesse corrects this problem:
64: *
65: * http://people.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf
66: *
67: * Written by Bill Paul <wpaul@ee.columbia.edu>
68: * Department of Electrical Engineering
69: * Columbia University, New York City
70: */
71:
72: /*
73: * The SysKonnect gigabit ethernet adapters consist of two main
74: * components: the SysKonnect GEnesis controller chip and the XaQti Corp.
75: * XMAC II gigabit ethernet MAC. The XMAC provides all of the MAC
76: * components and a PHY while the GEnesis controller provides a PCI
77: * interface with DMA support. Each card may have between 512K and
78: * 2MB of SRAM on board depending on the configuration.
79: *
80: * The SysKonnect GEnesis controller can have either one or two XMAC
81: * chips connected to it, allowing single or dual port NIC configurations.
82: * SysKonnect has the distinction of being the only vendor on the market
83: * with a dual port gigabit ethernet NIC. The GEnesis provides dual FIFOs,
84: * dual DMA queues, packet/MAC/transmit arbiters and direct access to the
85: * XMAC registers. This driver takes advantage of these features to allow
86: * both XMACs to operate as independent interfaces.
87: */
88:
89: #include "bpfilter.h"
90:
91: #include <sys/param.h>
92: #include <sys/systm.h>
93: #include <sys/sockio.h>
94: #include <sys/mbuf.h>
95: #include <sys/malloc.h>
96: #include <sys/kernel.h>
97: #include <sys/socket.h>
98: #include <sys/timeout.h>
99: #include <sys/device.h>
100: #include <sys/queue.h>
101:
102: #include <net/if.h>
103: #include <net/if_dl.h>
104: #include <net/if_types.h>
105:
106: #ifdef INET
107: #include <netinet/in.h>
108: #include <netinet/in_systm.h>
109: #include <netinet/in_var.h>
110: #include <netinet/ip.h>
111: #include <netinet/udp.h>
112: #include <netinet/tcp.h>
113: #include <netinet/if_ether.h>
114: #endif
115:
116: #include <net/if_media.h>
117: #include <net/if_vlan_var.h>
118:
119: #if NBPFILTER > 0
120: #include <net/bpf.h>
121: #endif
122:
123: #include <dev/mii/mii.h>
124: #include <dev/mii/miivar.h>
125: #include <dev/mii/brgphyreg.h>
126:
127: #include <dev/pci/pcireg.h>
128: #include <dev/pci/pcivar.h>
129: #include <dev/pci/pcidevs.h>
130:
131: #include <dev/pci/if_skreg.h>
132: #include <dev/pci/if_mskvar.h>
133:
134: int mskc_probe(struct device *, void *, void *);
135: void mskc_attach(struct device *, struct device *self, void *aux);
136: void mskc_reset(struct sk_softc *);
137: void mskc_shutdown(void *);
138: int msk_probe(struct device *, void *, void *);
139: void msk_attach(struct device *, struct device *self, void *aux);
140: void msk_reset(struct sk_if_softc *);
141: int mskcprint(void *, const char *);
142: int msk_intr(void *);
143: void msk_intr_yukon(struct sk_if_softc *);
144: static __inline int msk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t);
145: void msk_rxeof(struct sk_if_softc *, u_int16_t, u_int32_t);
146: void msk_txeof(struct sk_if_softc *);
147: int msk_encap(struct sk_if_softc *, struct mbuf *, u_int32_t *);
148: void msk_start(struct ifnet *);
149: int msk_ioctl(struct ifnet *, u_long, caddr_t);
150: void msk_init(void *);
151: void msk_init_yukon(struct sk_if_softc *);
152: void msk_stop(struct sk_if_softc *);
153: void msk_watchdog(struct ifnet *);
154: int msk_ifmedia_upd(struct ifnet *);
155: void msk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
156: int msk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
157: int msk_alloc_jumbo_mem(struct sk_if_softc *);
158: void *msk_jalloc(struct sk_if_softc *);
159: void msk_jfree(caddr_t, u_int, void *);
160: int msk_init_rx_ring(struct sk_if_softc *);
161: int msk_init_tx_ring(struct sk_if_softc *);
162:
163: int msk_miibus_readreg(struct device *, int, int);
164: void msk_miibus_writereg(struct device *, int, int, int);
165: void msk_miibus_statchg(struct device *);
166:
167: void msk_setfilt(struct sk_if_softc *, caddr_t, int);
168: void msk_setmulti(struct sk_if_softc *);
169: void msk_setpromisc(struct sk_if_softc *);
170: void msk_tick(void *);
171:
172: #ifdef MSK_DEBUG
173: #define DPRINTF(x) if (mskdebug) printf x
174: #define DPRINTFN(n,x) if (mskdebug >= (n)) printf x
175: int mskdebug = 0;
176:
177: void msk_dump_txdesc(struct msk_tx_desc *, int);
178: void msk_dump_mbuf(struct mbuf *);
179: void msk_dump_bytes(const char *, int);
180: #else
181: #define DPRINTF(x)
182: #define DPRINTFN(n,x)
183: #endif
184:
185: /* supported device vendors */
186: const struct pci_matchid mskc_devices[] = {
187: { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE550SX },
188: { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE550T_B1 },
189: { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE560SX },
190: { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE560T },
191: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C032 },
192: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C033 },
193: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C034 },
194: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C036 },
195: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C042 },
196: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8021CU },
197: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8021X },
198: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8022CU },
199: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8022X },
200: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8035 },
201: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8036 },
202: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8038 },
203: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8039 },
204: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8050 },
205: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8052 },
206: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8053 },
207: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8055 },
208: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8056 },
209: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8058 },
210: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8061CU },
211: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8061X },
212: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8062CU },
213: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8062X },
214: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8070 },
215: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8071 },
216: { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK9Sxx },
217: { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK9Exx }
218: };
219:
220: static inline u_int32_t
221: sk_win_read_4(struct sk_softc *sc, u_int32_t reg)
222: {
223: return CSR_READ_4(sc, reg);
224: }
225:
226: static inline u_int16_t
227: sk_win_read_2(struct sk_softc *sc, u_int32_t reg)
228: {
229: return CSR_READ_2(sc, reg);
230: }
231:
232: static inline u_int8_t
233: sk_win_read_1(struct sk_softc *sc, u_int32_t reg)
234: {
235: return CSR_READ_1(sc, reg);
236: }
237:
238: static inline void
239: sk_win_write_4(struct sk_softc *sc, u_int32_t reg, u_int32_t x)
240: {
241: CSR_WRITE_4(sc, reg, x);
242: }
243:
244: static inline void
245: sk_win_write_2(struct sk_softc *sc, u_int32_t reg, u_int16_t x)
246: {
247: CSR_WRITE_2(sc, reg, x);
248: }
249:
250: static inline void
251: sk_win_write_1(struct sk_softc *sc, u_int32_t reg, u_int8_t x)
252: {
253: CSR_WRITE_1(sc, reg, x);
254: }
255:
256: int
257: msk_miibus_readreg(struct device *dev, int phy, int reg)
258: {
259: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
260: u_int16_t val;
261: int i;
262:
263: SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
264: YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ);
265:
266: for (i = 0; i < SK_TIMEOUT; i++) {
267: DELAY(1);
268: val = SK_YU_READ_2(sc_if, YUKON_SMICR);
269: if (val & YU_SMICR_READ_VALID)
270: break;
271: }
272:
273: if (i == SK_TIMEOUT) {
274: printf("%s: phy failed to come ready\n",
275: sc_if->sk_dev.dv_xname);
276: return (0);
277: }
278:
279: DPRINTFN(9, ("msk_miibus_readreg: i=%d, timeout=%d\n", i,
280: SK_TIMEOUT));
281:
282: val = SK_YU_READ_2(sc_if, YUKON_SMIDR);
283:
284: DPRINTFN(9, ("msk_miibus_readreg phy=%d, reg=%#x, val=%#x\n",
285: phy, reg, val));
286:
287: return (val);
288: }
289:
290: void
291: msk_miibus_writereg(struct device *dev, int phy, int reg, int val)
292: {
293: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
294: int i;
295:
296: DPRINTFN(9, ("msk_miibus_writereg phy=%d reg=%#x val=%#x\n",
297: phy, reg, val));
298:
299: SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val);
300: SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
301: YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE);
302:
303: for (i = 0; i < SK_TIMEOUT; i++) {
304: DELAY(1);
305: if (!(SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY))
306: break;
307: }
308:
309: if (i == SK_TIMEOUT)
310: printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname);
311: }
312:
313: void
314: msk_miibus_statchg(struct device *dev)
315: {
316: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
317: struct mii_data *mii = &sc_if->sk_mii;
318: struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
319: int gpcr;
320:
321: gpcr = SK_YU_READ_2(sc_if, YUKON_GPCR);
322: gpcr &= (YU_GPCR_TXEN | YU_GPCR_RXEN);
323:
324: if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
325: /* Set speed. */
326: gpcr |= YU_GPCR_SPEED_DIS;
327: switch (IFM_SUBTYPE(mii->mii_media_active)) {
328: case IFM_1000_SX:
329: case IFM_1000_LX:
330: case IFM_1000_CX:
331: case IFM_1000_T:
332: gpcr |= (YU_GPCR_GIG | YU_GPCR_SPEED);
333: break;
334: case IFM_100_TX:
335: gpcr |= YU_GPCR_SPEED;
336: break;
337: }
338:
339: /* Set duplex. */
340: gpcr |= YU_GPCR_DPLX_DIS;
341: if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
342: gpcr |= YU_GPCR_DUPLEX;
343:
344: /* Disable flow control. */
345: gpcr |= YU_GPCR_FCTL_DIS;
346: gpcr |= (YU_GPCR_FCTL_TX_DIS | YU_GPCR_FCTL_RX_DIS);
347: }
348:
349: SK_YU_WRITE_2(sc_if, YUKON_GPCR, gpcr);
350:
351: DPRINTFN(9, ("msk_miibus_statchg: gpcr=%x\n",
352: SK_YU_READ_2(((struct sk_if_softc *)dev), YUKON_GPCR)));
353: }
354:
355: void
356: msk_setfilt(struct sk_if_softc *sc_if, caddr_t addr, int slot)
357: {
358: int base = XM_RXFILT_ENTRY(slot);
359:
360: SK_XM_WRITE_2(sc_if, base, *(u_int16_t *)(&addr[0]));
361: SK_XM_WRITE_2(sc_if, base + 2, *(u_int16_t *)(&addr[2]));
362: SK_XM_WRITE_2(sc_if, base + 4, *(u_int16_t *)(&addr[4]));
363: }
364:
365: void
366: msk_setmulti(struct sk_if_softc *sc_if)
367: {
368: struct ifnet *ifp= &sc_if->arpcom.ac_if;
369: u_int32_t hashes[2] = { 0, 0 };
370: int h;
371: struct arpcom *ac = &sc_if->arpcom;
372: struct ether_multi *enm;
373: struct ether_multistep step;
374:
375: /* First, zot all the existing filters. */
376: SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
377: SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
378: SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
379: SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0);
380:
381:
382: /* Now program new ones. */
383: allmulti:
384: if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
385: hashes[0] = 0xFFFFFFFF;
386: hashes[1] = 0xFFFFFFFF;
387: } else {
388: /* First find the tail of the list. */
389: ETHER_FIRST_MULTI(step, ac, enm);
390: while (enm != NULL) {
391: if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
392: ETHER_ADDR_LEN)) {
393: ifp->if_flags |= IFF_ALLMULTI;
394: goto allmulti;
395: }
396: h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) &
397: ((1 << SK_HASH_BITS) - 1);
398: if (h < 32)
399: hashes[0] |= (1 << h);
400: else
401: hashes[1] |= (1 << (h - 32));
402:
403: ETHER_NEXT_MULTI(step, enm);
404: }
405: }
406:
407: SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
408: SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
409: SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
410: SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff);
411: }
412:
413: void
414: msk_setpromisc(struct sk_if_softc *sc_if)
415: {
416: struct ifnet *ifp = &sc_if->arpcom.ac_if;
417:
418: if (ifp->if_flags & IFF_PROMISC)
419: SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
420: YU_RCR_UFLEN | YU_RCR_MUFLEN);
421: else
422: SK_YU_SETBIT_2(sc_if, YUKON_RCR,
423: YU_RCR_UFLEN | YU_RCR_MUFLEN);
424: }
425:
426: int
427: msk_init_rx_ring(struct sk_if_softc *sc_if)
428: {
429: struct msk_chain_data *cd = &sc_if->sk_cdata;
430: struct msk_ring_data *rd = sc_if->sk_rdata;
431: int i, nexti;
432:
433: bzero((char *)rd->sk_rx_ring,
434: sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT);
435:
436: for (i = 0; i < MSK_RX_RING_CNT; i++) {
437: cd->sk_rx_chain[i].sk_le = &rd->sk_rx_ring[i];
438: if (i == (MSK_RX_RING_CNT - 1))
439: nexti = 0;
440: else
441: nexti = i + 1;
442: cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[nexti];
443: }
444:
445: for (i = 0; i < MSK_RX_RING_CNT; i++) {
446: if (msk_newbuf(sc_if, i, NULL,
447: sc_if->sk_cdata.sk_rx_jumbo_map) == ENOBUFS) {
448: printf("%s: failed alloc of %dth mbuf\n",
449: sc_if->sk_dev.dv_xname, i);
450: return (ENOBUFS);
451: }
452: }
453:
454: sc_if->sk_cdata.sk_rx_prod = MSK_RX_RING_CNT - 1;
455: sc_if->sk_cdata.sk_rx_cons = 0;
456:
457: return (0);
458: }
459:
460: int
461: msk_init_tx_ring(struct sk_if_softc *sc_if)
462: {
463: struct sk_softc *sc = sc_if->sk_softc;
464: struct msk_chain_data *cd = &sc_if->sk_cdata;
465: struct msk_ring_data *rd = sc_if->sk_rdata;
466: bus_dmamap_t dmamap;
467: struct sk_txmap_entry *entry;
468: int i, nexti;
469:
470: bzero((char *)sc_if->sk_rdata->sk_tx_ring,
471: sizeof(struct msk_tx_desc) * MSK_TX_RING_CNT);
472:
473: SIMPLEQ_INIT(&sc_if->sk_txmap_head);
474: for (i = 0; i < MSK_TX_RING_CNT; i++) {
475: cd->sk_tx_chain[i].sk_le = &rd->sk_tx_ring[i];
476: if (i == (MSK_TX_RING_CNT - 1))
477: nexti = 0;
478: else
479: nexti = i + 1;
480: cd->sk_tx_chain[i].sk_next = &cd->sk_tx_chain[nexti];
481:
482: if (bus_dmamap_create(sc->sc_dmatag, SK_JLEN, SK_NTXSEG,
483: SK_JLEN, 0, BUS_DMA_NOWAIT, &dmamap))
484: return (ENOBUFS);
485:
486: entry = malloc(sizeof(*entry), M_DEVBUF, M_NOWAIT);
487: if (!entry) {
488: bus_dmamap_destroy(sc->sc_dmatag, dmamap);
489: return (ENOBUFS);
490: }
491: entry->dmamap = dmamap;
492: SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head, entry, link);
493: }
494:
495: sc_if->sk_cdata.sk_tx_prod = 0;
496: sc_if->sk_cdata.sk_tx_cons = 0;
497: sc_if->sk_cdata.sk_tx_cnt = 0;
498:
499: MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT,
500: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
501:
502: return (0);
503: }
504:
505: int
506: msk_newbuf(struct sk_if_softc *sc_if, int i, struct mbuf *m,
507: bus_dmamap_t dmamap)
508: {
509: struct mbuf *m_new = NULL;
510: struct sk_chain *c;
511: struct msk_rx_desc *r;
512:
513: if (m == NULL) {
514: caddr_t buf = NULL;
515:
516: MGETHDR(m_new, M_DONTWAIT, MT_DATA);
517: if (m_new == NULL)
518: return (ENOBUFS);
519:
520: /* Allocate the jumbo buffer */
521: buf = msk_jalloc(sc_if);
522: if (buf == NULL) {
523: m_freem(m_new);
524: DPRINTFN(1, ("%s jumbo allocation failed -- packet "
525: "dropped!\n", sc_if->arpcom.ac_if.if_xname));
526: return (ENOBUFS);
527: }
528:
529: /* Attach the buffer to the mbuf */
530: m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
531: MEXTADD(m_new, buf, SK_JLEN, 0, msk_jfree, sc_if);
532: } else {
533: /*
534: * We're re-using a previously allocated mbuf;
535: * be sure to re-init pointers and lengths to
536: * default values.
537: */
538: m_new = m;
539: m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
540: m_new->m_data = m_new->m_ext.ext_buf;
541: }
542: m_adj(m_new, ETHER_ALIGN);
543:
544: c = &sc_if->sk_cdata.sk_rx_chain[i];
545: r = c->sk_le;
546: c->sk_mbuf = m_new;
547: r->sk_addr = htole32(dmamap->dm_segs[0].ds_addr +
548: (((vaddr_t)m_new->m_data
549: - (vaddr_t)sc_if->sk_cdata.sk_jumbo_buf)));
550: r->sk_len = htole16(SK_JLEN);
551: r->sk_ctl = 0;
552: r->sk_opcode = SK_Y2_RXOPC_PACKET | SK_Y2_RXOPC_OWN;
553:
554: MSK_CDRXSYNC(sc_if, i, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
555:
556: return (0);
557: }
558:
559: /*
560: * Memory management for jumbo frames.
561: */
562:
563: int
564: msk_alloc_jumbo_mem(struct sk_if_softc *sc_if)
565: {
566: struct sk_softc *sc = sc_if->sk_softc;
567: caddr_t ptr, kva;
568: bus_dma_segment_t seg;
569: int i, rseg, state, error;
570: struct sk_jpool_entry *entry;
571:
572: state = error = 0;
573:
574: /* Grab a big chunk o' storage. */
575: if (bus_dmamem_alloc(sc->sc_dmatag, MSK_JMEM, PAGE_SIZE, 0,
576: &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
577: printf(": can't alloc rx buffers");
578: return (ENOBUFS);
579: }
580:
581: state = 1;
582: if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg, MSK_JMEM, &kva,
583: BUS_DMA_NOWAIT)) {
584: printf(": can't map dma buffers (%d bytes)", MSK_JMEM);
585: error = ENOBUFS;
586: goto out;
587: }
588:
589: state = 2;
590: if (bus_dmamap_create(sc->sc_dmatag, MSK_JMEM, 1, MSK_JMEM, 0,
591: BUS_DMA_NOWAIT, &sc_if->sk_cdata.sk_rx_jumbo_map)) {
592: printf(": can't create dma map");
593: error = ENOBUFS;
594: goto out;
595: }
596:
597: state = 3;
598: if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_cdata.sk_rx_jumbo_map,
599: kva, MSK_JMEM, NULL, BUS_DMA_NOWAIT)) {
600: printf(": can't load dma map");
601: error = ENOBUFS;
602: goto out;
603: }
604:
605: state = 4;
606: sc_if->sk_cdata.sk_jumbo_buf = (caddr_t)kva;
607: DPRINTFN(1,("msk_jumbo_buf = 0x%08X\n", sc_if->sk_cdata.sk_jumbo_buf));
608:
609: LIST_INIT(&sc_if->sk_jfree_listhead);
610: LIST_INIT(&sc_if->sk_jinuse_listhead);
611:
612: /*
613: * Now divide it up into 9K pieces and save the addresses
614: * in an array.
615: */
616: ptr = sc_if->sk_cdata.sk_jumbo_buf;
617: for (i = 0; i < MSK_JSLOTS; i++) {
618: sc_if->sk_cdata.sk_jslots[i] = ptr;
619: ptr += SK_JLEN;
620: entry = malloc(sizeof(struct sk_jpool_entry),
621: M_DEVBUF, M_NOWAIT);
622: if (entry == NULL) {
623: sc_if->sk_cdata.sk_jumbo_buf = NULL;
624: printf(": no memory for jumbo buffer queue!");
625: error = ENOBUFS;
626: goto out;
627: }
628: entry->slot = i;
629: LIST_INSERT_HEAD(&sc_if->sk_jfree_listhead,
630: entry, jpool_entries);
631: }
632: out:
633: if (error != 0) {
634: switch (state) {
635: case 4:
636: bus_dmamap_unload(sc->sc_dmatag,
637: sc_if->sk_cdata.sk_rx_jumbo_map);
638: case 3:
639: bus_dmamap_destroy(sc->sc_dmatag,
640: sc_if->sk_cdata.sk_rx_jumbo_map);
641: case 2:
642: bus_dmamem_unmap(sc->sc_dmatag, kva, MSK_JMEM);
643: case 1:
644: bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
645: break;
646: default:
647: break;
648: }
649: }
650:
651: return (error);
652: }
653:
654: /*
655: * Allocate a jumbo buffer.
656: */
657: void *
658: msk_jalloc(struct sk_if_softc *sc_if)
659: {
660: struct sk_jpool_entry *entry;
661:
662: entry = LIST_FIRST(&sc_if->sk_jfree_listhead);
663:
664: if (entry == NULL)
665: return (NULL);
666:
667: LIST_REMOVE(entry, jpool_entries);
668: LIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead, entry, jpool_entries);
669: return (sc_if->sk_cdata.sk_jslots[entry->slot]);
670: }
671:
672: /*
673: * Release a jumbo buffer.
674: */
675: void
676: msk_jfree(caddr_t buf, u_int size, void *arg)
677: {
678: struct sk_jpool_entry *entry;
679: struct sk_if_softc *sc;
680: int i;
681:
682: /* Extract the softc struct pointer. */
683: sc = (struct sk_if_softc *)arg;
684:
685: if (sc == NULL)
686: panic("msk_jfree: can't find softc pointer!");
687:
688: /* calculate the slot this buffer belongs to */
689: i = ((vaddr_t)buf
690: - (vaddr_t)sc->sk_cdata.sk_jumbo_buf) / SK_JLEN;
691:
692: if ((i < 0) || (i >= MSK_JSLOTS))
693: panic("msk_jfree: asked to free buffer that we don't manage!");
694:
695: entry = LIST_FIRST(&sc->sk_jinuse_listhead);
696: if (entry == NULL)
697: panic("msk_jfree: buffer not in use!");
698: entry->slot = i;
699: LIST_REMOVE(entry, jpool_entries);
700: LIST_INSERT_HEAD(&sc->sk_jfree_listhead, entry, jpool_entries);
701: }
702:
703: /*
704: * Set media options.
705: */
706: int
707: msk_ifmedia_upd(struct ifnet *ifp)
708: {
709: struct sk_if_softc *sc_if = ifp->if_softc;
710:
711: mii_mediachg(&sc_if->sk_mii);
712: return (0);
713: }
714:
715: /*
716: * Report current media status.
717: */
718: void
719: msk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
720: {
721: struct sk_if_softc *sc_if = ifp->if_softc;
722:
723: mii_pollstat(&sc_if->sk_mii);
724: ifmr->ifm_active = sc_if->sk_mii.mii_media_active;
725: ifmr->ifm_status = sc_if->sk_mii.mii_media_status;
726: }
727:
728: int
729: msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
730: {
731: struct sk_if_softc *sc_if = ifp->if_softc;
732: struct ifreq *ifr = (struct ifreq *) data;
733: struct ifaddr *ifa = (struct ifaddr *) data;
734: struct mii_data *mii;
735: int s, error = 0;
736:
737: s = splnet();
738:
739: if ((error = ether_ioctl(ifp, &sc_if->arpcom, command, data)) > 0) {
740: splx(s);
741: return (error);
742: }
743:
744: switch(command) {
745: case SIOCSIFADDR:
746: ifp->if_flags |= IFF_UP;
747: if (!(ifp->if_flags & IFF_RUNNING))
748: msk_init(sc_if);
749: #ifdef INET
750: if (ifa->ifa_addr->sa_family == AF_INET)
751: arp_ifinit(&sc_if->arpcom, ifa);
752: #endif /* INET */
753: break;
754: case SIOCSIFMTU:
755: if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
756: error = EINVAL;
757: else if (ifp->if_mtu != ifr->ifr_mtu)
758: ifp->if_mtu = ifr->ifr_mtu;
759: break;
760: case SIOCSIFFLAGS:
761: if (ifp->if_flags & IFF_UP) {
762: if (ifp->if_flags & IFF_RUNNING &&
763: (sc_if->sk_if_flags ^ ifp->if_flags) &
764: IFF_PROMISC) {
765: msk_setpromisc(sc_if);
766: msk_setmulti(sc_if);
767: } else {
768: if (!(ifp->if_flags & IFF_RUNNING))
769: msk_init(sc_if);
770: }
771: } else {
772: if (ifp->if_flags & IFF_RUNNING)
773: msk_stop(sc_if);
774: }
775: sc_if->sk_if_flags = ifp->if_flags;
776: break;
777: case SIOCADDMULTI:
778: case SIOCDELMULTI:
779: error = (command == SIOCADDMULTI) ?
780: ether_addmulti(ifr, &sc_if->arpcom) :
781: ether_delmulti(ifr, &sc_if->arpcom);
782:
783: if (error == ENETRESET) {
784: /*
785: * Multicast list has changed; set the hardware
786: * filter accordingly.
787: */
788: if (ifp->if_flags & IFF_RUNNING)
789: msk_setmulti(sc_if);
790: error = 0;
791: }
792: break;
793: case SIOCGIFMEDIA:
794: case SIOCSIFMEDIA:
795: mii = &sc_if->sk_mii;
796: error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
797: break;
798: default:
799: error = ENOTTY;
800: break;
801: }
802:
803: splx(s);
804:
805: return (error);
806: }
807:
808: /*
809: * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device
810: * IDs against our list and return a device name if we find a match.
811: */
812: int
813: mskc_probe(struct device *parent, void *match, void *aux)
814: {
815: return (pci_matchbyid((struct pci_attach_args *)aux, mskc_devices,
816: sizeof(mskc_devices)/sizeof(mskc_devices[0])));
817: }
818:
819: /*
820: * Force the GEnesis into reset, then bring it out of reset.
821: */
822: void
823: mskc_reset(struct sk_softc *sc)
824: {
825: u_int32_t imtimer_ticks, reg1;
826: int reg;
827:
828: DPRINTFN(2, ("mskc_reset\n"));
829:
830: CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_RESET);
831: CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_RESET);
832:
833: DELAY(1000);
834: CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_UNRESET);
835: DELAY(2);
836: CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
837:
838: sk_win_write_1(sc, SK_TESTCTL1, 2);
839:
840: reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1));
841: if (sc->sk_type == SK_YUKON_XL && sc->sk_rev > SK_YUKON_XL_REV_A1)
842: reg1 |= (SK_Y2_REG1_PHY1_COMA | SK_Y2_REG1_PHY2_COMA);
843: else
844: reg1 &= ~(SK_Y2_REG1_PHY1_COMA | SK_Y2_REG1_PHY2_COMA);
845: sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1), reg1);
846:
847: if (sc->sk_type == SK_YUKON_XL && sc->sk_rev > SK_YUKON_XL_REV_A1)
848: sk_win_write_1(sc, SK_Y2_CLKGATE,
849: SK_Y2_CLKGATE_LINK1_GATE_DIS |
850: SK_Y2_CLKGATE_LINK2_GATE_DIS |
851: SK_Y2_CLKGATE_LINK1_CORE_DIS |
852: SK_Y2_CLKGATE_LINK2_CORE_DIS |
853: SK_Y2_CLKGATE_LINK1_PCI_DIS | SK_Y2_CLKGATE_LINK2_PCI_DIS);
854: else
855: sk_win_write_1(sc, SK_Y2_CLKGATE, 0);
856:
857: CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
858: CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_SET);
859: DELAY(1000);
860: CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
861: CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_CLEAR);
862:
863: sk_win_write_1(sc, SK_TESTCTL1, 1);
864:
865: DPRINTFN(2, ("mskc_reset: sk_csr=%x\n", CSR_READ_1(sc, SK_CSR)));
866: DPRINTFN(2, ("mskc_reset: sk_link_ctrl=%x\n",
867: CSR_READ_2(sc, SK_LINK_CTRL)));
868:
869: /* Disable ASF */
870: CSR_WRITE_1(sc, SK_Y2_ASF_CSR, SK_Y2_ASF_RESET);
871: CSR_WRITE_2(sc, SK_CSR, SK_CSR_ASF_OFF);
872:
873: /* Clear I2C IRQ noise */
874: CSR_WRITE_4(sc, SK_I2CHWIRQ, 1);
875:
876: /* Disable hardware timer */
877: CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_STOP);
878: CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_IRQ_CLEAR);
879:
880: /* Disable descriptor polling */
881: CSR_WRITE_4(sc, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP);
882:
883: /* Disable time stamps */
884: CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_STOP);
885: CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_IRQ_CLEAR);
886:
887: /* Enable RAM interface */
888: sk_win_write_1(sc, SK_RAMCTL, SK_RAMCTL_UNRESET);
889: for (reg = SK_TO0;reg <= SK_TO11; reg++)
890: sk_win_write_1(sc, reg, 36);
891: sk_win_write_1(sc, SK_RAMCTL + (SK_WIN_LEN / 2), SK_RAMCTL_UNRESET);
892: for (reg = SK_TO0;reg <= SK_TO11; reg++)
893: sk_win_write_1(sc, reg + (SK_WIN_LEN / 2), 36);
894:
895: /*
896: * Configure interrupt moderation. The moderation timer
897: * defers interrupts specified in the interrupt moderation
898: * timer mask based on the timeout specified in the interrupt
899: * moderation timer init register. Each bit in the timer
900: * register represents one tick, so to specify a timeout in
901: * microseconds, we have to multiply by the correct number of
902: * ticks-per-microsecond.
903: */
904: switch (sc->sk_type) {
905: case SK_YUKON_EC:
906: case SK_YUKON_XL:
907: case SK_YUKON_FE:
908: imtimer_ticks = SK_IMTIMER_TICKS_YUKON_EC;
909: break;
910: default:
911: imtimer_ticks = SK_IMTIMER_TICKS_YUKON;
912: }
913:
914: /* Reset status ring. */
915: bzero((char *)sc->sk_status_ring,
916: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
917: sc->sk_status_idx = 0;
918:
919: sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_RESET);
920: sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_UNRESET);
921:
922: sk_win_write_2(sc, SK_STAT_BMU_LIDX, MSK_STATUS_RING_CNT - 1);
923: sk_win_write_4(sc, SK_STAT_BMU_ADDRLO,
924: sc->sk_status_map->dm_segs[0].ds_addr);
925: sk_win_write_4(sc, SK_STAT_BMU_ADDRHI,
926: (u_int64_t)sc->sk_status_map->dm_segs[0].ds_addr >> 32);
927: sk_win_write_2(sc, SK_STAT_BMU_TX_THRESH, 10);
928: sk_win_write_1(sc, SK_STAT_BMU_FIFOWM, 16);
929: sk_win_write_1(sc, SK_STAT_BMU_FIFOIWM, 16);
930:
931: #if 0
932: sk_win_write_4(sc, SK_Y2_LEV_TIMERINIT, SK_IM_USECS(100));
933: sk_win_write_4(sc, 0x0ec0, SK_IM_USECS(1000));
934:
935: sk_win_write_4(sc, 0x0ed0, SK_IM_USECS(20));
936: #else
937: sk_win_write_4(sc, SK_Y2_ISR_ITIMERINIT, SK_IM_USECS(4));
938: #endif
939:
940: sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_ON);
941:
942: sk_win_write_1(sc, SK_Y2_LEV_ITIMERCTL, SK_IMCTL_START);
943: sk_win_write_1(sc, SK_Y2_TX_ITIMERCTL, SK_IMCTL_START);
944: sk_win_write_1(sc, SK_Y2_ISR_ITIMERCTL, SK_IMCTL_START);
945: }
946:
947: int
948: msk_probe(struct device *parent, void *match, void *aux)
949: {
950: struct skc_attach_args *sa = aux;
951:
952: if (sa->skc_port != SK_PORT_A && sa->skc_port != SK_PORT_B)
953: return (0);
954:
955: switch (sa->skc_type) {
956: case SK_YUKON_XL:
957: case SK_YUKON_EC_U:
958: case SK_YUKON_EX:
959: case SK_YUKON_EC:
960: case SK_YUKON_FE:
961: return (1);
962: }
963:
964: return (0);
965: }
966:
967: void
968: msk_reset(struct sk_if_softc *sc_if)
969: {
970: /* GMAC and GPHY Reset */
971: SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
972: SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
973: DELAY(1000);
974: SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_CLEAR);
975: SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
976: SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
977: }
978:
979: /*
980: * Each XMAC chip is attached as a separate logical IP interface.
981: * Single port cards will have only one logical interface of course.
982: */
983: void
984: msk_attach(struct device *parent, struct device *self, void *aux)
985: {
986: struct sk_if_softc *sc_if = (struct sk_if_softc *) self;
987: struct sk_softc *sc = (struct sk_softc *)parent;
988: struct skc_attach_args *sa = aux;
989: struct ifnet *ifp;
990: caddr_t kva;
991: bus_dma_segment_t seg;
992: int i, rseg;
993: u_int32_t chunk;
994: int mii_flags;
995:
996: sc_if->sk_port = sa->skc_port;
997: sc_if->sk_softc = sc;
998: sc->sk_if[sa->skc_port] = sc_if;
999:
1000: DPRINTFN(2, ("begin msk_attach: port=%d\n", sc_if->sk_port));
1001:
1002: /*
1003: * Get station address for this interface. Note that
1004: * dual port cards actually come with three station
1005: * addresses: one for each port, plus an extra. The
1006: * extra one is used by the SysKonnect driver software
1007: * as a 'virtual' station address for when both ports
1008: * are operating in failover mode. Currently we don't
1009: * use this extra address.
1010: */
1011: for (i = 0; i < ETHER_ADDR_LEN; i++)
1012: sc_if->arpcom.ac_enaddr[i] =
1013: sk_win_read_1(sc, SK_MAC0_0 + (sa->skc_port * 8) + i);
1014:
1015: printf(": address %s\n",
1016: ether_sprintf(sc_if->arpcom.ac_enaddr));
1017:
1018: /*
1019: * Set up RAM buffer addresses. The Yukon2 has a small amount
1020: * of SRAM on it, somewhere between 4K and 48K. We need to
1021: * divide this up between the transmitter and receiver. We
1022: * give the receiver 2/3 of the memory (rounded down), and the
1023: * transmitter whatever remains.
1024: */
1025: chunk = (2 * (sc->sk_ramsize / sizeof(u_int64_t)) / 3) & ~0xff;
1026: sc_if->sk_rx_ramstart = 0;
1027: sc_if->sk_rx_ramend = sc_if->sk_rx_ramstart + chunk - 1;
1028: chunk = (sc->sk_ramsize / sizeof(u_int64_t)) - chunk;
1029: sc_if->sk_tx_ramstart = sc_if->sk_rx_ramend + 1;
1030: sc_if->sk_tx_ramend = sc_if->sk_tx_ramstart + chunk - 1;
1031:
1032: DPRINTFN(2, ("msk_attach: rx_ramstart=%#x rx_ramend=%#x\n"
1033: " tx_ramstart=%#x tx_ramend=%#x\n",
1034: sc_if->sk_rx_ramstart, sc_if->sk_rx_ramend,
1035: sc_if->sk_tx_ramstart, sc_if->sk_tx_ramend));
1036:
1037: /* Allocate the descriptor queues. */
1038: if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct msk_ring_data),
1039: PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
1040: printf(": can't alloc rx buffers\n");
1041: goto fail;
1042: }
1043: if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
1044: sizeof(struct msk_ring_data), &kva, BUS_DMA_NOWAIT)) {
1045: printf(": can't map dma buffers (%lu bytes)\n",
1046: (ulong)sizeof(struct msk_ring_data));
1047: goto fail_1;
1048: }
1049: if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct msk_ring_data), 1,
1050: sizeof(struct msk_ring_data), 0, BUS_DMA_NOWAIT,
1051: &sc_if->sk_ring_map)) {
1052: printf(": can't create dma map\n");
1053: goto fail_2;
1054: }
1055: if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_ring_map, kva,
1056: sizeof(struct msk_ring_data), NULL, BUS_DMA_NOWAIT)) {
1057: printf(": can't load dma map\n");
1058: goto fail_3;
1059: }
1060: sc_if->sk_rdata = (struct msk_ring_data *)kva;
1061: bzero(sc_if->sk_rdata, sizeof(struct msk_ring_data));
1062:
1063: /* Try to allocate memory for jumbo buffers. */
1064: if (msk_alloc_jumbo_mem(sc_if)) {
1065: printf(": jumbo buffer allocation failed\n");
1066: goto fail_3;
1067: }
1068:
1069: ifp = &sc_if->arpcom.ac_if;
1070: ifp->if_softc = sc_if;
1071: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1072: ifp->if_ioctl = msk_ioctl;
1073: ifp->if_start = msk_start;
1074: ifp->if_watchdog = msk_watchdog;
1075: ifp->if_baudrate = 1000000000;
1076: if (sc->sk_type != SK_YUKON_FE)
1077: ifp->if_hardmtu = SK_JUMBO_MTU;
1078: IFQ_SET_MAXLEN(&ifp->if_snd, MSK_TX_RING_CNT - 1);
1079: IFQ_SET_READY(&ifp->if_snd);
1080: bcopy(sc_if->sk_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
1081:
1082: ifp->if_capabilities = IFCAP_VLAN_MTU;
1083:
1084: msk_reset(sc_if);
1085:
1086: /*
1087: * Do miibus setup.
1088: */
1089: msk_init_yukon(sc_if);
1090:
1091: DPRINTFN(2, ("msk_attach: 1\n"));
1092:
1093: sc_if->sk_mii.mii_ifp = ifp;
1094: sc_if->sk_mii.mii_readreg = msk_miibus_readreg;
1095: sc_if->sk_mii.mii_writereg = msk_miibus_writereg;
1096: sc_if->sk_mii.mii_statchg = msk_miibus_statchg;
1097:
1098: ifmedia_init(&sc_if->sk_mii.mii_media, 0,
1099: msk_ifmedia_upd, msk_ifmedia_sts);
1100: mii_flags = MIIF_DOPAUSE;
1101: if (sc->sk_fibertype)
1102: mii_flags |= MIIF_HAVEFIBER;
1103: mii_attach(self, &sc_if->sk_mii, 0xffffffff, 0,
1104: MII_OFFSET_ANY, mii_flags);
1105: if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
1106: printf("%s: no PHY found!\n", sc_if->sk_dev.dv_xname);
1107: ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL,
1108: 0, NULL);
1109: ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL);
1110: } else
1111: ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_AUTO);
1112:
1113: timeout_set(&sc_if->sk_tick_ch, msk_tick, sc_if);
1114:
1115: /*
1116: * Call MI attach routines.
1117: */
1118: if_attach(ifp);
1119: ether_ifattach(ifp);
1120:
1121: shutdownhook_establish(mskc_shutdown, sc);
1122:
1123: DPRINTFN(2, ("msk_attach: end\n"));
1124: return;
1125:
1126: fail_3:
1127: bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
1128: fail_2:
1129: bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct msk_ring_data));
1130: fail_1:
1131: bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
1132: fail:
1133: sc->sk_if[sa->skc_port] = NULL;
1134: }
1135:
1136: int
1137: mskcprint(void *aux, const char *pnp)
1138: {
1139: struct skc_attach_args *sa = aux;
1140:
1141: if (pnp)
1142: printf("sk port %c at %s",
1143: (sa->skc_port == SK_PORT_A) ? 'A' : 'B', pnp);
1144: else
1145: printf(" port %c", (sa->skc_port == SK_PORT_A) ? 'A' : 'B');
1146: return (UNCONF);
1147: }
1148:
1149: /*
1150: * Attach the interface. Allocate softc structures, do ifmedia
1151: * setup and ethernet/BPF attach.
1152: */
1153: void
1154: mskc_attach(struct device *parent, struct device *self, void *aux)
1155: {
1156: struct sk_softc *sc = (struct sk_softc *)self;
1157: struct pci_attach_args *pa = aux;
1158: struct skc_attach_args skca;
1159: pci_chipset_tag_t pc = pa->pa_pc;
1160: pcireg_t command, memtype;
1161: pci_intr_handle_t ih;
1162: const char *intrstr = NULL;
1163: bus_size_t size;
1164: u_int8_t hw, pmd;
1165: char *revstr = NULL;
1166: caddr_t kva;
1167: bus_dma_segment_t seg;
1168: int rseg;
1169:
1170: DPRINTFN(2, ("begin mskc_attach\n"));
1171:
1172: /*
1173: * Handle power management nonsense.
1174: */
1175: command = pci_conf_read(pc, pa->pa_tag, SK_PCI_CAPID) & 0x000000FF;
1176:
1177: if (command == 0x01) {
1178: command = pci_conf_read(pc, pa->pa_tag, SK_PCI_PWRMGMTCTRL);
1179: if (command & SK_PSTATE_MASK) {
1180: u_int32_t iobase, membase, irq;
1181:
1182: /* Save important PCI config data. */
1183: iobase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOIO);
1184: membase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOMEM);
1185: irq = pci_conf_read(pc, pa->pa_tag, SK_PCI_INTLINE);
1186:
1187: /* Reset the power state. */
1188: printf("%s chip is in D%d power mode "
1189: "-- setting to D0\n", sc->sk_dev.dv_xname,
1190: command & SK_PSTATE_MASK);
1191: command &= 0xFFFFFFFC;
1192: pci_conf_write(pc, pa->pa_tag,
1193: SK_PCI_PWRMGMTCTRL, command);
1194:
1195: /* Restore PCI config data. */
1196: pci_conf_write(pc, pa->pa_tag, SK_PCI_LOIO, iobase);
1197: pci_conf_write(pc, pa->pa_tag, SK_PCI_LOMEM, membase);
1198: pci_conf_write(pc, pa->pa_tag, SK_PCI_INTLINE, irq);
1199: }
1200: }
1201:
1202: /*
1203: * Map control/status registers.
1204: */
1205:
1206: memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM);
1207: switch (memtype) {
1208: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
1209: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
1210: if (pci_mapreg_map(pa, SK_PCI_LOMEM,
1211: memtype, 0, &sc->sk_btag, &sc->sk_bhandle,
1212: NULL, &size, 0) == 0)
1213: break;
1214: default:
1215: printf(": can't map mem space\n");
1216: return;
1217: }
1218:
1219: sc->sc_dmatag = pa->pa_dmat;
1220:
1221: sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
1222: sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);
1223:
1224: /* bail out here if chip is not recognized */
1225: if (!(SK_IS_YUKON2(sc))) {
1226: printf(": unknown chip type: %d\n", sc->sk_type);
1227: goto fail_1;
1228: }
1229: DPRINTFN(2, ("mskc_attach: allocate interrupt\n"));
1230:
1231: /* Allocate interrupt */
1232: if (pci_intr_map(pa, &ih)) {
1233: printf(": couldn't map interrupt\n");
1234: goto fail_1;
1235: }
1236:
1237: intrstr = pci_intr_string(pc, ih);
1238: sc->sk_intrhand = pci_intr_establish(pc, ih, IPL_NET, msk_intr, sc,
1239: self->dv_xname);
1240: if (sc->sk_intrhand == NULL) {
1241: printf(": couldn't establish interrupt");
1242: if (intrstr != NULL)
1243: printf(" at %s", intrstr);
1244: printf("\n");
1245: goto fail_1;
1246: }
1247:
1248: if (bus_dmamem_alloc(sc->sc_dmatag,
1249: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
1250: PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
1251: printf(": can't alloc status buffers\n");
1252: goto fail_2;
1253: }
1254:
1255: if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
1256: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
1257: &kva, BUS_DMA_NOWAIT)) {
1258: printf(": can't map dma buffers (%lu bytes)\n",
1259: (ulong)(MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc)));
1260: goto fail_3;
1261: }
1262: if (bus_dmamap_create(sc->sc_dmatag,
1263: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 1,
1264: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 0,
1265: BUS_DMA_NOWAIT, &sc->sk_status_map)) {
1266: printf(": can't create dma map\n");
1267: goto fail_4;
1268: }
1269: if (bus_dmamap_load(sc->sc_dmatag, sc->sk_status_map, kva,
1270: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
1271: NULL, BUS_DMA_NOWAIT)) {
1272: printf(": can't load dma map\n");
1273: goto fail_5;
1274: }
1275: sc->sk_status_ring = (struct msk_status_desc *)kva;
1276: bzero(sc->sk_status_ring,
1277: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
1278:
1279: /* Reset the adapter. */
1280: mskc_reset(sc);
1281:
1282: sc->sk_ramsize = sk_win_read_1(sc, SK_EPROM0) * 4096;
1283: DPRINTFN(2, ("mskc_attach: ramsize=%dK\n", sc->sk_ramsize / 1024));
1284:
1285: pmd = sk_win_read_1(sc, SK_PMDTYPE);
1286: if (pmd == 'L' || pmd == 'S' || pmd == 'P')
1287: sc->sk_fibertype = 1;
1288:
1289: switch (sc->sk_type) {
1290: case SK_YUKON_XL:
1291: sc->sk_name = "Yukon-2 XL";
1292: break;
1293: case SK_YUKON_EC_U:
1294: sc->sk_name = "Yukon-2 EC Ultra";
1295: break;
1296: case SK_YUKON_EX:
1297: sc->sk_name = "Yukon-2 Extreme";
1298: break;
1299: case SK_YUKON_EC:
1300: sc->sk_name = "Yukon-2 EC";
1301: break;
1302: case SK_YUKON_FE:
1303: sc->sk_name = "Yukon-2 FE";
1304: break;
1305: default:
1306: sc->sk_name = "Yukon (Unknown)";
1307: }
1308:
1309: if (sc->sk_type == SK_YUKON_XL) {
1310: switch (sc->sk_rev) {
1311: case SK_YUKON_XL_REV_A0:
1312: revstr = "A0";
1313: break;
1314: case SK_YUKON_XL_REV_A1:
1315: revstr = "A1";
1316: break;
1317: case SK_YUKON_XL_REV_A2:
1318: revstr = "A2";
1319: break;
1320: case SK_YUKON_XL_REV_A3:
1321: revstr = "A3";
1322: break;
1323: default:
1324: ;
1325: }
1326: }
1327:
1328: if (sc->sk_type == SK_YUKON_EC) {
1329: switch (sc->sk_rev) {
1330: case SK_YUKON_EC_REV_A1:
1331: revstr = "A1";
1332: break;
1333: case SK_YUKON_EC_REV_A2:
1334: revstr = "A2";
1335: break;
1336: case SK_YUKON_EC_REV_A3:
1337: revstr = "A3";
1338: break;
1339: default:
1340: ;
1341: }
1342: }
1343:
1344: if (sc->sk_type == SK_YUKON_EC_U) {
1345: switch (sc->sk_rev) {
1346: case SK_YUKON_EC_U_REV_A0:
1347: revstr = "A0";
1348: break;
1349: case SK_YUKON_EC_U_REV_A1:
1350: revstr = "A1";
1351: break;
1352: default:
1353: ;
1354: }
1355: }
1356:
1357: /* Announce the product name. */
1358: printf(", %s", sc->sk_name);
1359: if (revstr != NULL)
1360: printf(" rev. %s", revstr);
1361: printf(" (0x%x): %s\n", sc->sk_rev, intrstr);
1362:
1363: sc->sk_macs = 1;
1364:
1365: hw = sk_win_read_1(sc, SK_Y2_HWRES);
1366: if ((hw & SK_Y2_HWRES_LINK_MASK) == SK_Y2_HWRES_LINK_DUAL) {
1367: if ((sk_win_read_1(sc, SK_Y2_CLKGATE) &
1368: SK_Y2_CLKGATE_LINK2_INACTIVE) == 0)
1369: sc->sk_macs++;
1370: }
1371:
1372: skca.skc_port = SK_PORT_A;
1373: skca.skc_type = sc->sk_type;
1374: skca.skc_rev = sc->sk_rev;
1375: (void)config_found(&sc->sk_dev, &skca, mskcprint);
1376:
1377: if (sc->sk_macs > 1) {
1378: skca.skc_port = SK_PORT_B;
1379: skca.skc_type = sc->sk_type;
1380: skca.skc_rev = sc->sk_rev;
1381: (void)config_found(&sc->sk_dev, &skca, mskcprint);
1382: }
1383:
1384: /* Turn on the 'driver is loaded' LED. */
1385: CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
1386:
1387: return;
1388:
1389: fail_5:
1390: bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
1391: fail_4:
1392: bus_dmamem_unmap(sc->sc_dmatag, kva,
1393: MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
1394: fail_3:
1395: bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
1396: fail_2:
1397: pci_intr_disestablish(pc, sc->sk_intrhand);
1398: fail_1:
1399: bus_space_unmap(sc->sk_btag, sc->sk_bhandle, size);
1400: }
1401:
1402: int
1403: msk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx)
1404: {
1405: struct sk_softc *sc = sc_if->sk_softc;
1406: struct msk_tx_desc *f = NULL;
1407: u_int32_t frag, cur;
1408: int i;
1409: struct sk_txmap_entry *entry;
1410: bus_dmamap_t txmap;
1411:
1412: DPRINTFN(2, ("msk_encap\n"));
1413:
1414: entry = SIMPLEQ_FIRST(&sc_if->sk_txmap_head);
1415: if (entry == NULL) {
1416: DPRINTFN(2, ("msk_encap: no txmap available\n"));
1417: return (ENOBUFS);
1418: }
1419: txmap = entry->dmamap;
1420:
1421: cur = frag = *txidx;
1422:
1423: #ifdef MSK_DEBUG
1424: if (mskdebug >= 2)
1425: msk_dump_mbuf(m_head);
1426: #endif
1427:
1428: /*
1429: * Start packing the mbufs in this chain into
1430: * the fragment pointers. Stop when we run out
1431: * of fragments or hit the end of the mbuf chain.
1432: */
1433: if (bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head,
1434: BUS_DMA_NOWAIT)) {
1435: DPRINTFN(2, ("msk_encap: dmamap failed\n"));
1436: return (ENOBUFS);
1437: }
1438:
1439: if (txmap->dm_nsegs > (MSK_TX_RING_CNT - sc_if->sk_cdata.sk_tx_cnt - 2)) {
1440: DPRINTFN(2, ("msk_encap: too few descriptors free\n"));
1441: bus_dmamap_unload(sc->sc_dmatag, txmap);
1442: return (ENOBUFS);
1443: }
1444:
1445: DPRINTFN(2, ("msk_encap: dm_nsegs=%d\n", txmap->dm_nsegs));
1446:
1447: /* Sync the DMA map. */
1448: bus_dmamap_sync(sc->sc_dmatag, txmap, 0, txmap->dm_mapsize,
1449: BUS_DMASYNC_PREWRITE);
1450:
1451: for (i = 0; i < txmap->dm_nsegs; i++) {
1452: f = &sc_if->sk_rdata->sk_tx_ring[frag];
1453: f->sk_addr = htole32(txmap->dm_segs[i].ds_addr);
1454: f->sk_len = htole16(txmap->dm_segs[i].ds_len);
1455: f->sk_ctl = 0;
1456: if (i == 0)
1457: f->sk_opcode = SK_Y2_TXOPC_PACKET;
1458: else
1459: f->sk_opcode = SK_Y2_TXOPC_BUFFER | SK_Y2_TXOPC_OWN;
1460: cur = frag;
1461: SK_INC(frag, MSK_TX_RING_CNT);
1462: }
1463:
1464: sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head;
1465: SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
1466:
1467: sc_if->sk_cdata.sk_tx_map[cur] = entry;
1468: sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |= SK_Y2_TXCTL_LASTFRAG;
1469:
1470: /* Sync descriptors before handing to chip */
1471: MSK_CDTXSYNC(sc_if, *txidx, txmap->dm_nsegs,
1472: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1473:
1474: sc_if->sk_rdata->sk_tx_ring[*txidx].sk_opcode |= SK_Y2_TXOPC_OWN;
1475:
1476: /* Sync first descriptor to hand it off */
1477: MSK_CDTXSYNC(sc_if, *txidx, 1,
1478: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1479:
1480: sc_if->sk_cdata.sk_tx_cnt += txmap->dm_nsegs;
1481:
1482: #ifdef MSK_DEBUG
1483: if (mskdebug >= 2) {
1484: struct msk_tx_desc *le;
1485: u_int32_t idx;
1486: for (idx = *txidx; idx != frag; SK_INC(idx, MSK_TX_RING_CNT)) {
1487: le = &sc_if->sk_rdata->sk_tx_ring[idx];
1488: msk_dump_txdesc(le, idx);
1489: }
1490: }
1491: #endif
1492:
1493: *txidx = frag;
1494:
1495: DPRINTFN(2, ("msk_encap: completed successfully\n"));
1496:
1497: return (0);
1498: }
1499:
1500: void
1501: msk_start(struct ifnet *ifp)
1502: {
1503: struct sk_if_softc *sc_if = ifp->if_softc;
1504: struct mbuf *m_head = NULL;
1505: u_int32_t idx = sc_if->sk_cdata.sk_tx_prod;
1506: int pkts = 0;
1507:
1508: DPRINTFN(2, ("msk_start\n"));
1509:
1510: while (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
1511: IFQ_POLL(&ifp->if_snd, m_head);
1512: if (m_head == NULL)
1513: break;
1514:
1515: /*
1516: * Pack the data into the transmit ring. If we
1517: * don't have room, set the OACTIVE flag and wait
1518: * for the NIC to drain the ring.
1519: */
1520: if (msk_encap(sc_if, m_head, &idx)) {
1521: ifp->if_flags |= IFF_OACTIVE;
1522: break;
1523: }
1524:
1525: /* now we are committed to transmit the packet */
1526: IFQ_DEQUEUE(&ifp->if_snd, m_head);
1527: pkts++;
1528:
1529: /*
1530: * If there's a BPF listener, bounce a copy of this frame
1531: * to him.
1532: */
1533: #if NBPFILTER > 0
1534: if (ifp->if_bpf)
1535: bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
1536: #endif
1537: }
1538: if (pkts == 0)
1539: return;
1540:
1541: /* Transmit */
1542: if (idx != sc_if->sk_cdata.sk_tx_prod) {
1543: sc_if->sk_cdata.sk_tx_prod = idx;
1544: SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_PUTIDX, idx);
1545:
1546: /* Set a timeout in case the chip goes out to lunch. */
1547: ifp->if_timer = 5;
1548: }
1549: }
1550:
1551: void
1552: msk_watchdog(struct ifnet *ifp)
1553: {
1554: struct sk_if_softc *sc_if = ifp->if_softc;
1555:
1556: /*
1557: * Reclaim first as there is a possibility of losing Tx completion
1558: * interrupts.
1559: */
1560: msk_txeof(sc_if);
1561: if (sc_if->sk_cdata.sk_tx_cnt != 0) {
1562: printf("%s: watchdog timeout\n", sc_if->sk_dev.dv_xname);
1563:
1564: ifp->if_oerrors++;
1565:
1566: /* XXX Resets both ports; we shouldn't do that. */
1567: mskc_reset(sc_if->sk_softc);
1568: msk_reset(sc_if);
1569: msk_init(sc_if);
1570: }
1571: }
1572:
1573: void
1574: mskc_shutdown(void *v)
1575: {
1576: struct sk_softc *sc = v;
1577:
1578: DPRINTFN(2, ("msk_shutdown\n"));
1579:
1580: /* Turn off the 'driver is loaded' LED. */
1581: CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF);
1582:
1583: /*
1584: * Reset the GEnesis controller. Doing this should also
1585: * assert the resets on the attached XMAC(s).
1586: */
1587: mskc_reset(sc);
1588: }
1589:
1590: static __inline int
1591: msk_rxvalid(struct sk_softc *sc, u_int32_t stat, u_int32_t len)
1592: {
1593: if ((stat & (YU_RXSTAT_CRCERR | YU_RXSTAT_LONGERR |
1594: YU_RXSTAT_MIIERR | YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC |
1595: YU_RXSTAT_JABBER)) != 0 ||
1596: (stat & YU_RXSTAT_RXOK) != YU_RXSTAT_RXOK ||
1597: YU_RXSTAT_BYTES(stat) != len)
1598: return (0);
1599:
1600: return (1);
1601: }
1602:
1603: void
1604: msk_rxeof(struct sk_if_softc *sc_if, u_int16_t len, u_int32_t rxstat)
1605: {
1606: struct sk_softc *sc = sc_if->sk_softc;
1607: struct ifnet *ifp = &sc_if->arpcom.ac_if;
1608: struct mbuf *m;
1609: struct sk_chain *cur_rx;
1610: int cur, total_len = len;
1611: bus_dmamap_t dmamap;
1612:
1613: DPRINTFN(2, ("msk_rxeof\n"));
1614:
1615: cur = sc_if->sk_cdata.sk_rx_cons;
1616: SK_INC(sc_if->sk_cdata.sk_rx_cons, MSK_RX_RING_CNT);
1617: SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
1618:
1619: /* Sync the descriptor */
1620: MSK_CDRXSYNC(sc_if, cur, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1621:
1622: cur_rx = &sc_if->sk_cdata.sk_rx_chain[cur];
1623: dmamap = sc_if->sk_cdata.sk_rx_jumbo_map;
1624:
1625: bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
1626: dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1627:
1628: m = cur_rx->sk_mbuf;
1629: cur_rx->sk_mbuf = NULL;
1630:
1631: if (total_len < SK_MIN_FRAMELEN ||
1632: total_len > SK_JUMBO_FRAMELEN ||
1633: msk_rxvalid(sc, rxstat, total_len) == 0) {
1634: ifp->if_ierrors++;
1635: msk_newbuf(sc_if, cur, m, dmamap);
1636: return;
1637: }
1638:
1639: /*
1640: * Try to allocate a new jumbo buffer. If that fails, copy the
1641: * packet to mbufs and put the jumbo buffer back in the ring
1642: * so it can be re-used. If allocating mbufs fails, then we
1643: * have to drop the packet.
1644: */
1645: if (msk_newbuf(sc_if, cur, NULL, dmamap) == ENOBUFS) {
1646: struct mbuf *m0;
1647: m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
1648: total_len + ETHER_ALIGN, 0, ifp, NULL);
1649: msk_newbuf(sc_if, cur, m, dmamap);
1650: if (m0 == NULL) {
1651: ifp->if_ierrors++;
1652: return;
1653: }
1654: m_adj(m0, ETHER_ALIGN);
1655: m = m0;
1656: } else {
1657: m->m_pkthdr.rcvif = ifp;
1658: m->m_pkthdr.len = m->m_len = total_len;
1659: }
1660:
1661: ifp->if_ipackets++;
1662:
1663: #if NBPFILTER > 0
1664: if (ifp->if_bpf)
1665: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1666: #endif
1667:
1668: /* pass it on. */
1669: ether_input_mbuf(ifp, m);
1670: }
1671:
1672: void
1673: msk_txeof(struct sk_if_softc *sc_if)
1674: {
1675: struct sk_softc *sc = sc_if->sk_softc;
1676: struct msk_tx_desc *cur_tx;
1677: struct ifnet *ifp = &sc_if->arpcom.ac_if;
1678: u_int32_t idx, reg, sk_ctl;
1679: struct sk_txmap_entry *entry;
1680:
1681: DPRINTFN(2, ("msk_txeof\n"));
1682:
1683: if (sc_if->sk_port == SK_PORT_A)
1684: reg = SK_STAT_BMU_TXA1_RIDX;
1685: else
1686: reg = SK_STAT_BMU_TXA2_RIDX;
1687:
1688: /*
1689: * Go through our tx ring and free mbufs for those
1690: * frames that have been sent.
1691: */
1692: idx = sc_if->sk_cdata.sk_tx_cons;
1693: while (idx != sk_win_read_2(sc, reg)) {
1694: MSK_CDTXSYNC(sc_if, idx, 1,
1695: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1696:
1697: cur_tx = &sc_if->sk_rdata->sk_tx_ring[idx];
1698: sk_ctl = cur_tx->sk_ctl;
1699: #ifdef MSK_DEBUG
1700: if (mskdebug >= 2)
1701: msk_dump_txdesc(cur_tx, idx);
1702: #endif
1703: if (sk_ctl & SK_Y2_TXCTL_LASTFRAG)
1704: ifp->if_opackets++;
1705: if (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf != NULL) {
1706: entry = sc_if->sk_cdata.sk_tx_map[idx];
1707:
1708: m_freem(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf);
1709: sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf = NULL;
1710:
1711: bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0,
1712: entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1713:
1714: bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
1715: SIMPLEQ_INSERT_TAIL(&sc_if->sk_txmap_head, entry,
1716: link);
1717: sc_if->sk_cdata.sk_tx_map[idx] = NULL;
1718: }
1719: sc_if->sk_cdata.sk_tx_cnt--;
1720: SK_INC(idx, MSK_TX_RING_CNT);
1721: }
1722: ifp->if_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? 5 : 0;
1723:
1724: if (sc_if->sk_cdata.sk_tx_cnt < MSK_TX_RING_CNT - 2)
1725: ifp->if_flags &= ~IFF_OACTIVE;
1726:
1727: sc_if->sk_cdata.sk_tx_cons = idx;
1728: }
1729:
1730: void
1731: msk_tick(void *xsc_if)
1732: {
1733: struct sk_if_softc *sc_if = xsc_if;
1734: struct mii_data *mii = &sc_if->sk_mii;
1735: int s;
1736:
1737: s = splnet();
1738: mii_tick(mii);
1739: splx(s);
1740: timeout_add(&sc_if->sk_tick_ch, hz);
1741: }
1742:
1743: void
1744: msk_intr_yukon(struct sk_if_softc *sc_if)
1745: {
1746: u_int8_t status;
1747:
1748: status = SK_IF_READ_1(sc_if, 0, SK_GMAC_ISR);
1749: /* RX overrun */
1750: if ((status & SK_GMAC_INT_RX_OVER) != 0) {
1751: SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST,
1752: SK_RFCTL_RX_FIFO_OVER);
1753: }
1754: /* TX underrun */
1755: if ((status & SK_GMAC_INT_TX_UNDER) != 0) {
1756: SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST,
1757: SK_TFCTL_TX_FIFO_UNDER);
1758: }
1759:
1760: DPRINTFN(2, ("msk_intr_yukon status=%#x\n", status));
1761: }
1762:
1763: int
1764: msk_intr(void *xsc)
1765: {
1766: struct sk_softc *sc = xsc;
1767: struct sk_if_softc *sc_if0 = sc->sk_if[SK_PORT_A];
1768: struct sk_if_softc *sc_if1 = sc->sk_if[SK_PORT_B];
1769: struct ifnet *ifp0 = NULL, *ifp1 = NULL;
1770: int claimed = 0;
1771: u_int32_t status;
1772: struct msk_status_desc *cur_st;
1773:
1774: status = CSR_READ_4(sc, SK_Y2_ISSR2);
1775: if (status == 0) {
1776: CSR_WRITE_4(sc, SK_Y2_ICR, 2);
1777: return (0);
1778: }
1779:
1780: status = CSR_READ_4(sc, SK_ISR);
1781:
1782: if (sc_if0 != NULL)
1783: ifp0 = &sc_if0->arpcom.ac_if;
1784: if (sc_if1 != NULL)
1785: ifp1 = &sc_if1->arpcom.ac_if;
1786:
1787: if (sc_if0 && (status & SK_Y2_IMR_MAC1) &&
1788: (ifp0->if_flags & IFF_RUNNING)) {
1789: msk_intr_yukon(sc_if0);
1790: }
1791:
1792: if (sc_if1 && (status & SK_Y2_IMR_MAC2) &&
1793: (ifp1->if_flags & IFF_RUNNING)) {
1794: msk_intr_yukon(sc_if1);
1795: }
1796:
1797: MSK_CDSTSYNC(sc, sc->sk_status_idx,
1798: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1799: cur_st = &sc->sk_status_ring[sc->sk_status_idx];
1800:
1801: while (cur_st->sk_opcode & SK_Y2_STOPC_OWN) {
1802: cur_st->sk_opcode &= ~SK_Y2_STOPC_OWN;
1803: switch (cur_st->sk_opcode) {
1804: case SK_Y2_STOPC_RXSTAT:
1805: msk_rxeof(sc->sk_if[cur_st->sk_link],
1806: letoh16(cur_st->sk_len),
1807: letoh32(cur_st->sk_status));
1808: SK_IF_WRITE_2(sc->sk_if[cur_st->sk_link], 0,
1809: SK_RXQ1_Y2_PREF_PUTIDX,
1810: sc->sk_if[cur_st->sk_link]->sk_cdata.sk_rx_prod);
1811: break;
1812: case SK_Y2_STOPC_TXSTAT:
1813: if (sc_if0)
1814: msk_txeof(sc_if0);
1815: if (sc_if1)
1816: msk_txeof(sc_if1);
1817: break;
1818: default:
1819: printf("opcode=0x%x\n", cur_st->sk_opcode);
1820: break;
1821: }
1822: SK_INC(sc->sk_status_idx, MSK_STATUS_RING_CNT);
1823:
1824: MSK_CDSTSYNC(sc, sc->sk_status_idx,
1825: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1826: cur_st = &sc->sk_status_ring[sc->sk_status_idx];
1827: }
1828:
1829: if (status & SK_Y2_IMR_BMU) {
1830: CSR_WRITE_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_IRQ_CLEAR);
1831: claimed = 1;
1832: }
1833:
1834: CSR_WRITE_4(sc, SK_Y2_ICR, 2);
1835:
1836: if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd))
1837: msk_start(ifp0);
1838: if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd))
1839: msk_start(ifp1);
1840:
1841: return (claimed);
1842: }
1843:
1844: void
1845: msk_init_yukon(struct sk_if_softc *sc_if)
1846: {
1847: u_int32_t v;
1848: u_int16_t reg;
1849: struct sk_softc *sc;
1850: int i;
1851:
1852: sc = sc_if->sk_softc;
1853:
1854: DPRINTFN(2, ("msk_init_yukon: start: sk_csr=%#x\n",
1855: CSR_READ_4(sc_if->sk_softc, SK_CSR)));
1856:
1857: DPRINTFN(6, ("msk_init_yukon: 1\n"));
1858:
1859: DPRINTFN(3, ("msk_init_yukon: gmac_ctrl=%#x\n",
1860: SK_IF_READ_4(sc_if, 0, SK_GMAC_CTRL)));
1861:
1862: DPRINTFN(6, ("msk_init_yukon: 3\n"));
1863:
1864: /* unused read of the interrupt source register */
1865: DPRINTFN(6, ("msk_init_yukon: 4\n"));
1866: SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR);
1867:
1868: DPRINTFN(6, ("msk_init_yukon: 4a\n"));
1869: reg = SK_YU_READ_2(sc_if, YUKON_PAR);
1870: DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg));
1871:
1872: /* MIB Counter Clear Mode set */
1873: reg |= YU_PAR_MIB_CLR;
1874: DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg));
1875: DPRINTFN(6, ("msk_init_yukon: 4b\n"));
1876: SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
1877:
1878: /* MIB Counter Clear Mode clear */
1879: DPRINTFN(6, ("msk_init_yukon: 5\n"));
1880: reg &= ~YU_PAR_MIB_CLR;
1881: SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
1882:
1883: /* receive control reg */
1884: DPRINTFN(6, ("msk_init_yukon: 7\n"));
1885: SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
1886:
1887: /* transmit parameter register */
1888: DPRINTFN(6, ("msk_init_yukon: 8\n"));
1889: SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
1890: YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) );
1891:
1892: /* serial mode register */
1893: DPRINTFN(6, ("msk_init_yukon: 9\n"));
1894: reg = YU_SMR_DATA_BLIND(0x1c) |
1895: YU_SMR_MFL_VLAN |
1896: YU_SMR_IPG_DATA(0x1e);
1897:
1898: if (sc->sk_type != SK_YUKON_FE)
1899: reg |= YU_SMR_MFL_JUMBO;
1900:
1901: SK_YU_WRITE_2(sc_if, YUKON_SMR, reg);
1902:
1903: DPRINTFN(6, ("msk_init_yukon: 10\n"));
1904: /* Setup Yukon's address */
1905: for (i = 0; i < 3; i++) {
1906: /* Write Source Address 1 (unicast filter) */
1907: SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4,
1908: sc_if->arpcom.ac_enaddr[i * 2] |
1909: sc_if->arpcom.ac_enaddr[i * 2 + 1] << 8);
1910: }
1911:
1912: for (i = 0; i < 3; i++) {
1913: reg = sk_win_read_2(sc_if->sk_softc,
1914: SK_MAC1_0 + i * 2 + sc_if->sk_port * 8);
1915: SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
1916: }
1917:
1918: /* Set promiscuous mode */
1919: msk_setpromisc(sc_if);
1920:
1921: /* Set multicast filter */
1922: DPRINTFN(6, ("msk_init_yukon: 11\n"));
1923: msk_setmulti(sc_if);
1924:
1925: /* enable interrupt mask for counter overflows */
1926: DPRINTFN(6, ("msk_init_yukon: 12\n"));
1927: SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
1928: SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0);
1929: SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0);
1930:
1931: /* Configure RX MAC FIFO Flush Mask */
1932: v = YU_RXSTAT_FOFL | YU_RXSTAT_CRCERR | YU_RXSTAT_MIIERR |
1933: YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC | YU_RXSTAT_RUNT |
1934: YU_RXSTAT_JABBER;
1935: SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_MASK, v);
1936:
1937: /* Configure RX MAC FIFO */
1938: SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR);
1939: SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_OPERATION_ON |
1940: SK_RFCTL_FIFO_FLUSH_ON);
1941:
1942: /* Increase flush threshould to 64 bytes */
1943: SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_THRESHOLD,
1944: SK_RFCTL_FIFO_THRESHOLD + 1);
1945:
1946: /* Configure TX MAC FIFO */
1947: SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR);
1948: SK_IF_WRITE_2(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON);
1949:
1950: #if 1
1951: SK_YU_WRITE_2(sc_if, YUKON_GPCR, YU_GPCR_TXEN | YU_GPCR_RXEN);
1952: #endif
1953: DPRINTFN(6, ("msk_init_yukon: end\n"));
1954: }
1955:
1956: /*
1957: * Note that to properly initialize any part of the GEnesis chip,
1958: * you first have to take it out of reset mode.
1959: */
1960: void
1961: msk_init(void *xsc_if)
1962: {
1963: struct sk_if_softc *sc_if = xsc_if;
1964: struct sk_softc *sc = sc_if->sk_softc;
1965: struct ifnet *ifp = &sc_if->arpcom.ac_if;
1966: struct mii_data *mii = &sc_if->sk_mii;
1967: int s;
1968:
1969: DPRINTFN(2, ("msk_init\n"));
1970:
1971: s = splnet();
1972:
1973: /* Cancel pending I/O and free all RX/TX buffers. */
1974: msk_stop(sc_if);
1975:
1976: /* Configure I2C registers */
1977:
1978: /* Configure XMAC(s) */
1979: msk_init_yukon(sc_if);
1980: mii_mediachg(mii);
1981:
1982: /* Configure transmit arbiter(s) */
1983: SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_ON);
1984: #if 0
1985: SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON);
1986: #endif
1987:
1988: /* Configure RAMbuffers */
1989: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET);
1990: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart);
1991: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart);
1992: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart);
1993: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend);
1994: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON);
1995:
1996: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_UNRESET);
1997: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_STORENFWD_ON);
1998: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_START, sc_if->sk_tx_ramstart);
1999: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_WR_PTR, sc_if->sk_tx_ramstart);
2000: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_RD_PTR, sc_if->sk_tx_ramstart);
2001: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_END, sc_if->sk_tx_ramend);
2002: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_ON);
2003:
2004: /* Configure BMUs */
2005: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000016);
2006: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000d28);
2007: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000080);
2008: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_WATERMARK, 0x00000600);
2009:
2010: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000016);
2011: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000d28);
2012: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000080);
2013: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_WATERMARK, 0x00000600);
2014:
2015: /* Make sure the sync transmit queue is disabled. */
2016: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET);
2017:
2018: /* Init descriptors */
2019: if (msk_init_rx_ring(sc_if) == ENOBUFS) {
2020: printf("%s: initialization failed: no "
2021: "memory for rx buffers\n", sc_if->sk_dev.dv_xname);
2022: msk_stop(sc_if);
2023: splx(s);
2024: return;
2025: }
2026:
2027: if (msk_init_tx_ring(sc_if) == ENOBUFS) {
2028: printf("%s: initialization failed: no "
2029: "memory for tx buffers\n", sc_if->sk_dev.dv_xname);
2030: msk_stop(sc_if);
2031: splx(s);
2032: return;
2033: }
2034:
2035: /* Initialize prefetch engine. */
2036: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
2037: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000002);
2038: SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_LIDX, MSK_RX_RING_CNT - 1);
2039: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRLO,
2040: MSK_RX_RING_ADDR(sc_if, 0));
2041: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRHI,
2042: (u_int64_t)MSK_RX_RING_ADDR(sc_if, 0) >> 32);
2043: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000008);
2044: SK_IF_READ_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR);
2045:
2046: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
2047: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000002);
2048: SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_LIDX, MSK_TX_RING_CNT - 1);
2049: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRLO,
2050: MSK_TX_RING_ADDR(sc_if, 0));
2051: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRHI,
2052: (u_int64_t)MSK_TX_RING_ADDR(sc_if, 0) >> 32);
2053: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000008);
2054: SK_IF_READ_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR);
2055:
2056: SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,
2057: sc_if->sk_cdata.sk_rx_prod);
2058:
2059: /* Configure interrupt handling */
2060: if (sc_if->sk_port == SK_PORT_A)
2061: sc->sk_intrmask |= SK_Y2_INTRS1;
2062: else
2063: sc->sk_intrmask |= SK_Y2_INTRS2;
2064: sc->sk_intrmask |= SK_Y2_IMR_BMU;
2065: CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2066:
2067: ifp->if_flags |= IFF_RUNNING;
2068: ifp->if_flags &= ~IFF_OACTIVE;
2069:
2070: timeout_add(&sc_if->sk_tick_ch, hz);
2071:
2072: splx(s);
2073: }
2074:
2075: void
2076: msk_stop(struct sk_if_softc *sc_if)
2077: {
2078: struct sk_softc *sc = sc_if->sk_softc;
2079: struct ifnet *ifp = &sc_if->arpcom.ac_if;
2080: struct sk_txmap_entry *dma;
2081: int i;
2082:
2083: DPRINTFN(2, ("msk_stop\n"));
2084:
2085: timeout_del(&sc_if->sk_tick_ch);
2086:
2087: ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
2088:
2089: /* Stop transfer of Tx descriptors */
2090:
2091: /* Stop transfer of Rx descriptors */
2092:
2093: /* Turn off various components of this interface. */
2094: SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
2095: SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
2096: SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
2097: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
2098: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2099: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE);
2100: SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2101: SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
2102: SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
2103: SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP);
2104: SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
2105: SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
2106:
2107: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
2108: SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
2109:
2110: /* Disable interrupts */
2111: if (sc_if->sk_port == SK_PORT_A)
2112: sc->sk_intrmask &= ~SK_Y2_INTRS1;
2113: else
2114: sc->sk_intrmask &= ~SK_Y2_INTRS2;
2115: CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2116:
2117: SK_XM_READ_2(sc_if, XM_ISR);
2118: SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
2119:
2120: /* Free RX and TX mbufs still in the queues. */
2121: for (i = 0; i < MSK_RX_RING_CNT; i++) {
2122: if (sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf != NULL) {
2123: m_freem(sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf);
2124: sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL;
2125: }
2126: }
2127:
2128: for (i = 0; i < MSK_TX_RING_CNT; i++) {
2129: if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) {
2130: m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf);
2131: sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL;
2132: SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head,
2133: sc_if->sk_cdata.sk_tx_map[i], link);
2134: sc_if->sk_cdata.sk_tx_map[i] = 0;
2135: }
2136: }
2137:
2138: while ((dma = SIMPLEQ_FIRST(&sc_if->sk_txmap_head))) {
2139: SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
2140: bus_dmamap_destroy(sc->sc_dmatag, dma->dmamap);
2141: free(dma, M_DEVBUF);
2142: }
2143: }
2144:
2145: struct cfattach mskc_ca = {
2146: sizeof(struct sk_softc), mskc_probe, mskc_attach,
2147: };
2148:
2149: struct cfdriver mskc_cd = {
2150: 0, "mskc", DV_DULL
2151: };
2152:
2153: struct cfattach msk_ca = {
2154: sizeof(struct sk_if_softc), msk_probe, msk_attach,
2155: };
2156:
2157: struct cfdriver msk_cd = {
2158: 0, "msk", DV_IFNET
2159: };
2160:
2161: #ifdef MSK_DEBUG
2162: void
2163: msk_dump_txdesc(struct msk_tx_desc *le, int idx)
2164: {
2165: #define DESC_PRINT(X) \
2166: if (X) \
2167: printf("txdesc[%d]." #X "=%#x\n", \
2168: idx, X);
2169:
2170: DESC_PRINT(letoh32(le->sk_addr));
2171: DESC_PRINT(letoh16(le->sk_len));
2172: DESC_PRINT(le->sk_ctl);
2173: DESC_PRINT(le->sk_opcode);
2174: #undef DESC_PRINT
2175: }
2176:
2177: void
2178: msk_dump_bytes(const char *data, int len)
2179: {
2180: int c, i, j;
2181:
2182: for (i = 0; i < len; i += 16) {
2183: printf("%08x ", i);
2184: c = len - i;
2185: if (c > 16) c = 16;
2186:
2187: for (j = 0; j < c; j++) {
2188: printf("%02x ", data[i + j] & 0xff);
2189: if ((j & 0xf) == 7 && j > 0)
2190: printf(" ");
2191: }
2192:
2193: for (; j < 16; j++)
2194: printf(" ");
2195: printf(" ");
2196:
2197: for (j = 0; j < c; j++) {
2198: int ch = data[i + j] & 0xff;
2199: printf("%c", ' ' <= ch && ch <= '~' ? ch : ' ');
2200: }
2201:
2202: printf("\n");
2203:
2204: if (c < 16)
2205: break;
2206: }
2207: }
2208:
2209: void
2210: msk_dump_mbuf(struct mbuf *m)
2211: {
2212: int count = m->m_pkthdr.len;
2213:
2214: printf("m=%#lx, m->m_pkthdr.len=%#d\n", m, m->m_pkthdr.len);
2215:
2216: while (count > 0 && m) {
2217: printf("m=%#lx, m->m_data=%#lx, m->m_len=%d\n",
2218: m, m->m_data, m->m_len);
2219: msk_dump_bytes(mtod(m, char *), m->m_len);
2220:
2221: count -= m->m_len;
2222: m = m->m_next;
2223: }
2224: }
2225: #endif
CVSweb