Annotation of sys/dev/pci/if_sk.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_sk.c,v 1.142 2007/05/26 16:44:21 reyk 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_skvar.h>
133:
134: int skc_probe(struct device *, void *, void *);
135: void skc_attach(struct device *, struct device *self, void *aux);
136: void skc_shutdown(void *);
137: int sk_probe(struct device *, void *, void *);
138: void sk_attach(struct device *, struct device *self, void *aux);
139: int skcprint(void *, const char *);
140: int sk_intr(void *);
141: void sk_intr_bcom(struct sk_if_softc *);
142: void sk_intr_xmac(struct sk_if_softc *);
143: void sk_intr_yukon(struct sk_if_softc *);
144: static __inline int sk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t);
145: void sk_rxeof(struct sk_if_softc *);
146: void sk_txeof(struct sk_if_softc *);
147: int sk_encap(struct sk_if_softc *, struct mbuf *, u_int32_t *);
148: void sk_start(struct ifnet *);
149: int sk_ioctl(struct ifnet *, u_long, caddr_t);
150: void sk_init(void *);
151: void sk_init_xmac(struct sk_if_softc *);
152: void sk_init_yukon(struct sk_if_softc *);
153: void sk_stop(struct sk_if_softc *);
154: void sk_watchdog(struct ifnet *);
155: int sk_ifmedia_upd(struct ifnet *);
156: void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
157: void sk_reset(struct sk_softc *);
158: int sk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
159: int sk_alloc_jumbo_mem(struct sk_if_softc *);
160: void *sk_jalloc(struct sk_if_softc *);
161: void sk_jfree(caddr_t, u_int, void *);
162: int sk_init_rx_ring(struct sk_if_softc *);
163: int sk_init_tx_ring(struct sk_if_softc *);
164:
165: int sk_xmac_miibus_readreg(struct device *, int, int);
166: void sk_xmac_miibus_writereg(struct device *, int, int, int);
167: void sk_xmac_miibus_statchg(struct device *);
168:
169: int sk_marv_miibus_readreg(struct device *, int, int);
170: void sk_marv_miibus_writereg(struct device *, int, int, int);
171: void sk_marv_miibus_statchg(struct device *);
172:
173: u_int32_t sk_xmac_hash(caddr_t);
174: u_int32_t sk_yukon_hash(caddr_t);
175: void sk_setfilt(struct sk_if_softc *, caddr_t, int);
176: void sk_setmulti(struct sk_if_softc *);
177: void sk_setpromisc(struct sk_if_softc *);
178: void sk_tick(void *);
179: void sk_yukon_tick(void *);
180: void sk_rxcsum(struct ifnet *, struct mbuf *, const u_int16_t, const u_int16_t);
181:
182: #ifdef SK_DEBUG
183: #define DPRINTF(x) if (skdebug) printf x
184: #define DPRINTFN(n,x) if (skdebug >= (n)) printf x
185: int skdebug = 0;
186:
187: void sk_dump_txdesc(struct sk_tx_desc *, int);
188: void sk_dump_mbuf(struct mbuf *);
189: void sk_dump_bytes(const char *, int);
190: #else
191: #define DPRINTF(x)
192: #define DPRINTFN(n,x)
193: #endif
194:
195: /* supported device vendors */
196: const struct pci_matchid skc_devices[] = {
197: { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C940 },
198: { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C940B },
199: { PCI_VENDOR_CNET, PCI_PRODUCT_CNET_GIGACARD },
200: { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE530T_A1 },
201: { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE530T_B1 },
202: { PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_EG1064 },
203: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON },
204: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_BELKIN },
205: { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK98XX },
206: { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK98XX2 },
207: };
208:
209: #define SK_LINKSYS_EG1032_SUBID 0x00151737
210:
211: static inline u_int32_t
212: sk_win_read_4(struct sk_softc *sc, u_int32_t reg)
213: {
214: return CSR_READ_4(sc, reg);
215: }
216:
217: static inline u_int16_t
218: sk_win_read_2(struct sk_softc *sc, u_int32_t reg)
219: {
220: return CSR_READ_2(sc, reg);
221: }
222:
223: static inline u_int8_t
224: sk_win_read_1(struct sk_softc *sc, u_int32_t reg)
225: {
226: return CSR_READ_1(sc, reg);
227: }
228:
229: static inline void
230: sk_win_write_4(struct sk_softc *sc, u_int32_t reg, u_int32_t x)
231: {
232: CSR_WRITE_4(sc, reg, x);
233: }
234:
235: static inline void
236: sk_win_write_2(struct sk_softc *sc, u_int32_t reg, u_int16_t x)
237: {
238: CSR_WRITE_2(sc, reg, x);
239: }
240:
241: static inline void
242: sk_win_write_1(struct sk_softc *sc, u_int32_t reg, u_int8_t x)
243: {
244: CSR_WRITE_1(sc, reg, x);
245: }
246:
247: int
248: sk_xmac_miibus_readreg(struct device *dev, int phy, int reg)
249: {
250: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
251: int i;
252:
253: DPRINTFN(9, ("sk_xmac_miibus_readreg\n"));
254:
255: if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0)
256: return (0);
257:
258: SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
259: SK_XM_READ_2(sc_if, XM_PHY_DATA);
260: if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) {
261: for (i = 0; i < SK_TIMEOUT; i++) {
262: DELAY(1);
263: if (SK_XM_READ_2(sc_if, XM_MMUCMD) &
264: XM_MMUCMD_PHYDATARDY)
265: break;
266: }
267:
268: if (i == SK_TIMEOUT) {
269: printf("%s: phy failed to come ready\n",
270: sc_if->sk_dev.dv_xname);
271: return (0);
272: }
273: }
274: DELAY(1);
275: return (SK_XM_READ_2(sc_if, XM_PHY_DATA));
276: }
277:
278: void
279: sk_xmac_miibus_writereg(struct device *dev, int phy, int reg, int val)
280: {
281: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
282: int i;
283:
284: DPRINTFN(9, ("sk_xmac_miibus_writereg\n"));
285:
286: SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
287: for (i = 0; i < SK_TIMEOUT; i++) {
288: if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY))
289: break;
290: }
291:
292: if (i == SK_TIMEOUT) {
293: printf("%s: phy failed to come ready\n",
294: sc_if->sk_dev.dv_xname);
295: return;
296: }
297:
298: SK_XM_WRITE_2(sc_if, XM_PHY_DATA, val);
299: for (i = 0; i < SK_TIMEOUT; i++) {
300: DELAY(1);
301: if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY))
302: break;
303: }
304:
305: if (i == SK_TIMEOUT)
306: printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname);
307: }
308:
309: void
310: sk_xmac_miibus_statchg(struct device *dev)
311: {
312: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
313: struct mii_data *mii = &sc_if->sk_mii;
314:
315: DPRINTFN(9, ("sk_xmac_miibus_statchg\n"));
316:
317: /*
318: * If this is a GMII PHY, manually set the XMAC's
319: * duplex mode accordingly.
320: */
321: if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) {
322: if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
323: SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX);
324: else
325: SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX);
326: }
327: }
328:
329: int
330: sk_marv_miibus_readreg(struct device *dev, int phy, int reg)
331: {
332: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
333: u_int16_t val;
334: int i;
335:
336: if (phy != 0 ||
337: (sc_if->sk_phytype != SK_PHYTYPE_MARV_COPPER &&
338: sc_if->sk_phytype != SK_PHYTYPE_MARV_FIBER)) {
339: DPRINTFN(9, ("sk_marv_miibus_readreg (skip) phy=%d, reg=%#x\n",
340: phy, reg));
341: return (0);
342: }
343:
344: SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
345: YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ);
346:
347: for (i = 0; i < SK_TIMEOUT; i++) {
348: DELAY(1);
349: val = SK_YU_READ_2(sc_if, YUKON_SMICR);
350: if (val & YU_SMICR_READ_VALID)
351: break;
352: }
353:
354: if (i == SK_TIMEOUT) {
355: printf("%s: phy failed to come ready\n",
356: sc_if->sk_dev.dv_xname);
357: return (0);
358: }
359:
360: DPRINTFN(9, ("sk_marv_miibus_readreg: i=%d, timeout=%d\n", i,
361: SK_TIMEOUT));
362:
363: val = SK_YU_READ_2(sc_if, YUKON_SMIDR);
364:
365: DPRINTFN(9, ("sk_marv_miibus_readreg phy=%d, reg=%#x, val=%#x\n",
366: phy, reg, val));
367:
368: return (val);
369: }
370:
371: void
372: sk_marv_miibus_writereg(struct device *dev, int phy, int reg, int val)
373: {
374: struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
375: int i;
376:
377: DPRINTFN(9, ("sk_marv_miibus_writereg phy=%d reg=%#x val=%#x\n",
378: phy, reg, val));
379:
380: SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val);
381: SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
382: YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE);
383:
384: for (i = 0; i < SK_TIMEOUT; i++) {
385: DELAY(1);
386: if (!(SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY))
387: break;
388: }
389:
390: if (i == SK_TIMEOUT)
391: printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname);
392: }
393:
394: void
395: sk_marv_miibus_statchg(struct device *dev)
396: {
397: DPRINTFN(9, ("sk_marv_miibus_statchg: gpcr=%x\n",
398: SK_YU_READ_2(((struct sk_if_softc *)dev), YUKON_GPCR)));
399: }
400:
401: u_int32_t
402: sk_xmac_hash(caddr_t addr)
403: {
404: u_int32_t crc;
405:
406: crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
407: return (~crc & ((1 << SK_HASH_BITS) - 1));
408: }
409:
410: u_int32_t
411: sk_yukon_hash(caddr_t addr)
412: {
413: u_int32_t crc;
414:
415: crc = ether_crc32_be(addr, ETHER_ADDR_LEN);
416: return (crc & ((1 << SK_HASH_BITS) - 1));
417: }
418:
419: void
420: sk_setfilt(struct sk_if_softc *sc_if, caddr_t addr, int slot)
421: {
422: int base = XM_RXFILT_ENTRY(slot);
423:
424: SK_XM_WRITE_2(sc_if, base, letoh16(*(u_int16_t *)(&addr[0])));
425: SK_XM_WRITE_2(sc_if, base + 2, letoh16(*(u_int16_t *)(&addr[2])));
426: SK_XM_WRITE_2(sc_if, base + 4, letoh16(*(u_int16_t *)(&addr[4])));
427: }
428:
429: void
430: sk_setmulti(struct sk_if_softc *sc_if)
431: {
432: struct sk_softc *sc = sc_if->sk_softc;
433: struct ifnet *ifp= &sc_if->arpcom.ac_if;
434: u_int32_t hashes[2] = { 0, 0 };
435: int h, i;
436: struct arpcom *ac = &sc_if->arpcom;
437: struct ether_multi *enm;
438: struct ether_multistep step;
439: u_int8_t dummy[] = { 0, 0, 0, 0, 0 ,0 };
440:
441: /* First, zot all the existing filters. */
442: switch(sc->sk_type) {
443: case SK_GENESIS:
444: for (i = 1; i < XM_RXFILT_MAX; i++)
445: sk_setfilt(sc_if, (caddr_t)&dummy, i);
446:
447: SK_XM_WRITE_4(sc_if, XM_MAR0, 0);
448: SK_XM_WRITE_4(sc_if, XM_MAR2, 0);
449: break;
450: case SK_YUKON:
451: case SK_YUKON_LITE:
452: case SK_YUKON_LP:
453: SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
454: SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
455: SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
456: SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0);
457: break;
458: }
459:
460: /* Now program new ones. */
461: allmulti:
462: if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
463: hashes[0] = 0xFFFFFFFF;
464: hashes[1] = 0xFFFFFFFF;
465: } else {
466: i = 1;
467: /* First find the tail of the list. */
468: ETHER_FIRST_MULTI(step, ac, enm);
469: while (enm != NULL) {
470: if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
471: ETHER_ADDR_LEN)) {
472: ifp->if_flags |= IFF_ALLMULTI;
473: goto allmulti;
474: }
475: /*
476: * Program the first XM_RXFILT_MAX multicast groups
477: * into the perfect filter. For all others,
478: * use the hash table.
479: */
480: if (SK_IS_GENESIS(sc) && i < XM_RXFILT_MAX) {
481: sk_setfilt(sc_if, enm->enm_addrlo, i);
482: i++;
483: }
484: else {
485: switch(sc->sk_type) {
486: case SK_GENESIS:
487: h = sk_xmac_hash(enm->enm_addrlo);
488: break;
489:
490: case SK_YUKON:
491: case SK_YUKON_LITE:
492: case SK_YUKON_LP:
493: h = sk_yukon_hash(enm->enm_addrlo);
494: break;
495: }
496: if (h < 32)
497: hashes[0] |= (1 << h);
498: else
499: hashes[1] |= (1 << (h - 32));
500: }
501:
502: ETHER_NEXT_MULTI(step, enm);
503: }
504: }
505:
506: switch(sc->sk_type) {
507: case SK_GENESIS:
508: SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_HASH|
509: XM_MODE_RX_USE_PERFECT);
510: SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]);
511: SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]);
512: break;
513: case SK_YUKON:
514: case SK_YUKON_LITE:
515: case SK_YUKON_LP:
516: SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
517: SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
518: SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
519: SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff);
520: break;
521: }
522: }
523:
524: void
525: sk_setpromisc(struct sk_if_softc *sc_if)
526: {
527: struct sk_softc *sc = sc_if->sk_softc;
528: struct ifnet *ifp= &sc_if->arpcom.ac_if;
529:
530: switch(sc->sk_type) {
531: case SK_GENESIS:
532: if (ifp->if_flags & IFF_PROMISC)
533: SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
534: else
535: SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
536: break;
537: case SK_YUKON:
538: case SK_YUKON_LITE:
539: case SK_YUKON_LP:
540: if (ifp->if_flags & IFF_PROMISC) {
541: SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
542: YU_RCR_UFLEN | YU_RCR_MUFLEN);
543: } else {
544: SK_YU_SETBIT_2(sc_if, YUKON_RCR,
545: YU_RCR_UFLEN | YU_RCR_MUFLEN);
546: }
547: break;
548: }
549: }
550:
551: int
552: sk_init_rx_ring(struct sk_if_softc *sc_if)
553: {
554: struct sk_chain_data *cd = &sc_if->sk_cdata;
555: struct sk_ring_data *rd = sc_if->sk_rdata;
556: int i, nexti;
557:
558: bzero((char *)rd->sk_rx_ring,
559: sizeof(struct sk_rx_desc) * SK_RX_RING_CNT);
560:
561: for (i = 0; i < SK_RX_RING_CNT; i++) {
562: cd->sk_rx_chain[i].sk_desc = &rd->sk_rx_ring[i];
563: if (i == (SK_RX_RING_CNT - 1))
564: nexti = 0;
565: else
566: nexti = i + 1;
567: cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[nexti];
568: rd->sk_rx_ring[i].sk_next = htole32(SK_RX_RING_ADDR(sc_if, nexti));
569: rd->sk_rx_ring[i].sk_csum1_start = htole16(ETHER_HDR_LEN);
570: rd->sk_rx_ring[i].sk_csum2_start = htole16(ETHER_HDR_LEN +
571: sizeof(struct ip));
572: }
573:
574: for (i = 0; i < SK_RX_RING_CNT; i++) {
575: if (sk_newbuf(sc_if, i, NULL,
576: sc_if->sk_cdata.sk_rx_jumbo_map) == ENOBUFS) {
577: printf("%s: failed alloc of %dth mbuf\n",
578: sc_if->sk_dev.dv_xname, i);
579: return (ENOBUFS);
580: }
581: }
582:
583: sc_if->sk_cdata.sk_rx_prod = 0;
584: sc_if->sk_cdata.sk_rx_cons = 0;
585:
586: return (0);
587: }
588:
589: int
590: sk_init_tx_ring(struct sk_if_softc *sc_if)
591: {
592: struct sk_softc *sc = sc_if->sk_softc;
593: struct sk_chain_data *cd = &sc_if->sk_cdata;
594: struct sk_ring_data *rd = sc_if->sk_rdata;
595: bus_dmamap_t dmamap;
596: struct sk_txmap_entry *entry;
597: int i, nexti;
598:
599: bzero((char *)sc_if->sk_rdata->sk_tx_ring,
600: sizeof(struct sk_tx_desc) * SK_TX_RING_CNT);
601:
602: SIMPLEQ_INIT(&sc_if->sk_txmap_head);
603: for (i = 0; i < SK_TX_RING_CNT; i++) {
604: cd->sk_tx_chain[i].sk_desc = &rd->sk_tx_ring[i];
605: if (i == (SK_TX_RING_CNT - 1))
606: nexti = 0;
607: else
608: nexti = i + 1;
609: cd->sk_tx_chain[i].sk_next = &cd->sk_tx_chain[nexti];
610: rd->sk_tx_ring[i].sk_next = htole32(SK_TX_RING_ADDR(sc_if, nexti));
611:
612: if (bus_dmamap_create(sc->sc_dmatag, SK_JLEN, SK_NTXSEG,
613: SK_JLEN, 0, BUS_DMA_NOWAIT, &dmamap))
614: return (ENOBUFS);
615:
616: entry = malloc(sizeof(*entry), M_DEVBUF, M_NOWAIT);
617: if (!entry) {
618: bus_dmamap_destroy(sc->sc_dmatag, dmamap);
619: return (ENOBUFS);
620: }
621: entry->dmamap = dmamap;
622: SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head, entry, link);
623: }
624:
625: sc_if->sk_cdata.sk_tx_prod = 0;
626: sc_if->sk_cdata.sk_tx_cons = 0;
627: sc_if->sk_cdata.sk_tx_cnt = 0;
628:
629: SK_CDTXSYNC(sc_if, 0, SK_TX_RING_CNT,
630: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
631:
632: return (0);
633: }
634:
635: int
636: sk_newbuf(struct sk_if_softc *sc_if, int i, struct mbuf *m,
637: bus_dmamap_t dmamap)
638: {
639: struct mbuf *m_new = NULL;
640: struct sk_chain *c;
641: struct sk_rx_desc *r;
642:
643: if (m == NULL) {
644: caddr_t buf = NULL;
645:
646: MGETHDR(m_new, M_DONTWAIT, MT_DATA);
647: if (m_new == NULL)
648: return (ENOBUFS);
649:
650: /* Allocate the jumbo buffer */
651: buf = sk_jalloc(sc_if);
652: if (buf == NULL) {
653: m_freem(m_new);
654: DPRINTFN(1, ("%s jumbo allocation failed -- packet "
655: "dropped!\n", sc_if->arpcom.ac_if.if_xname));
656: return (ENOBUFS);
657: }
658:
659: /* Attach the buffer to the mbuf */
660: m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
661: MEXTADD(m_new, buf, SK_JLEN, 0, sk_jfree, sc_if);
662: } else {
663: /*
664: * We're re-using a previously allocated mbuf;
665: * be sure to re-init pointers and lengths to
666: * default values.
667: */
668: m_new = m;
669: m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
670: m_new->m_data = m_new->m_ext.ext_buf;
671: }
672: m_adj(m_new, ETHER_ALIGN);
673:
674: c = &sc_if->sk_cdata.sk_rx_chain[i];
675: r = c->sk_desc;
676: c->sk_mbuf = m_new;
677: r->sk_data_lo = htole32(dmamap->dm_segs[0].ds_addr +
678: (((vaddr_t)m_new->m_data
679: - (vaddr_t)sc_if->sk_cdata.sk_jumbo_buf)));
680: r->sk_ctl = htole32(SK_JLEN | SK_RXSTAT);
681:
682: SK_CDRXSYNC(sc_if, i, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
683:
684: return (0);
685: }
686:
687: /*
688: * Memory management for jumbo frames.
689: */
690:
691: int
692: sk_alloc_jumbo_mem(struct sk_if_softc *sc_if)
693: {
694: struct sk_softc *sc = sc_if->sk_softc;
695: caddr_t ptr, kva;
696: bus_dma_segment_t seg;
697: int i, rseg, state, error;
698: struct sk_jpool_entry *entry;
699:
700: state = error = 0;
701:
702: /* Grab a big chunk o' storage. */
703: if (bus_dmamem_alloc(sc->sc_dmatag, SK_JMEM, PAGE_SIZE, 0,
704: &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
705: printf(": can't alloc rx buffers");
706: return (ENOBUFS);
707: }
708:
709: state = 1;
710: if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg, SK_JMEM, &kva,
711: BUS_DMA_NOWAIT)) {
712: printf(": can't map dma buffers (%d bytes)", SK_JMEM);
713: error = ENOBUFS;
714: goto out;
715: }
716:
717: state = 2;
718: if (bus_dmamap_create(sc->sc_dmatag, SK_JMEM, 1, SK_JMEM, 0,
719: BUS_DMA_NOWAIT, &sc_if->sk_cdata.sk_rx_jumbo_map)) {
720: printf(": can't create dma map");
721: error = ENOBUFS;
722: goto out;
723: }
724:
725: state = 3;
726: if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_cdata.sk_rx_jumbo_map,
727: kva, SK_JMEM, NULL, BUS_DMA_NOWAIT)) {
728: printf(": can't load dma map");
729: error = ENOBUFS;
730: goto out;
731: }
732:
733: state = 4;
734: sc_if->sk_cdata.sk_jumbo_buf = (caddr_t)kva;
735: DPRINTFN(1,("sk_jumbo_buf = 0x%08X\n", sc_if->sk_cdata.sk_jumbo_buf));
736:
737: LIST_INIT(&sc_if->sk_jfree_listhead);
738: LIST_INIT(&sc_if->sk_jinuse_listhead);
739:
740: /*
741: * Now divide it up into 9K pieces and save the addresses
742: * in an array.
743: */
744: ptr = sc_if->sk_cdata.sk_jumbo_buf;
745: for (i = 0; i < SK_JSLOTS; i++) {
746: sc_if->sk_cdata.sk_jslots[i] = ptr;
747: ptr += SK_JLEN;
748: entry = malloc(sizeof(struct sk_jpool_entry),
749: M_DEVBUF, M_NOWAIT);
750: if (entry == NULL) {
751: sc_if->sk_cdata.sk_jumbo_buf = NULL;
752: printf(": no memory for jumbo buffer queue!");
753: error = ENOBUFS;
754: goto out;
755: }
756: entry->slot = i;
757: LIST_INSERT_HEAD(&sc_if->sk_jfree_listhead,
758: entry, jpool_entries);
759: }
760: out:
761: if (error != 0) {
762: switch (state) {
763: case 4:
764: bus_dmamap_unload(sc->sc_dmatag,
765: sc_if->sk_cdata.sk_rx_jumbo_map);
766: case 3:
767: bus_dmamap_destroy(sc->sc_dmatag,
768: sc_if->sk_cdata.sk_rx_jumbo_map);
769: case 2:
770: bus_dmamem_unmap(sc->sc_dmatag, kva, SK_JMEM);
771: case 1:
772: bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
773: break;
774: default:
775: break;
776: }
777: }
778:
779: return (error);
780: }
781:
782: /*
783: * Allocate a jumbo buffer.
784: */
785: void *
786: sk_jalloc(struct sk_if_softc *sc_if)
787: {
788: struct sk_jpool_entry *entry;
789:
790: entry = LIST_FIRST(&sc_if->sk_jfree_listhead);
791:
792: if (entry == NULL)
793: return (NULL);
794:
795: LIST_REMOVE(entry, jpool_entries);
796: LIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead, entry, jpool_entries);
797: return (sc_if->sk_cdata.sk_jslots[entry->slot]);
798: }
799:
800: /*
801: * Release a jumbo buffer.
802: */
803: void
804: sk_jfree(caddr_t buf, u_int size, void *arg)
805: {
806: struct sk_jpool_entry *entry;
807: struct sk_if_softc *sc;
808: int i;
809:
810: /* Extract the softc struct pointer. */
811: sc = (struct sk_if_softc *)arg;
812:
813: if (sc == NULL)
814: panic("sk_jfree: can't find softc pointer!");
815:
816: /* calculate the slot this buffer belongs to */
817: i = ((vaddr_t)buf
818: - (vaddr_t)sc->sk_cdata.sk_jumbo_buf) / SK_JLEN;
819:
820: if ((i < 0) || (i >= SK_JSLOTS))
821: panic("sk_jfree: asked to free buffer that we don't manage!");
822:
823: entry = LIST_FIRST(&sc->sk_jinuse_listhead);
824: if (entry == NULL)
825: panic("sk_jfree: buffer not in use!");
826: entry->slot = i;
827: LIST_REMOVE(entry, jpool_entries);
828: LIST_INSERT_HEAD(&sc->sk_jfree_listhead, entry, jpool_entries);
829: }
830:
831: /*
832: * Set media options.
833: */
834: int
835: sk_ifmedia_upd(struct ifnet *ifp)
836: {
837: struct sk_if_softc *sc_if = ifp->if_softc;
838:
839: mii_mediachg(&sc_if->sk_mii);
840: return (0);
841: }
842:
843: /*
844: * Report current media status.
845: */
846: void
847: sk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
848: {
849: struct sk_if_softc *sc_if = ifp->if_softc;
850:
851: mii_pollstat(&sc_if->sk_mii);
852: ifmr->ifm_active = sc_if->sk_mii.mii_media_active;
853: ifmr->ifm_status = sc_if->sk_mii.mii_media_status;
854: }
855:
856: int
857: sk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
858: {
859: struct sk_if_softc *sc_if = ifp->if_softc;
860: struct ifreq *ifr = (struct ifreq *) data;
861: struct ifaddr *ifa = (struct ifaddr *) data;
862: struct mii_data *mii;
863: int s, error = 0;
864:
865: s = splnet();
866:
867: if ((error = ether_ioctl(ifp, &sc_if->arpcom, command, data)) > 0) {
868: splx(s);
869: return (error);
870: }
871:
872: switch(command) {
873: case SIOCSIFADDR:
874: ifp->if_flags |= IFF_UP;
875: if (!(ifp->if_flags & IFF_RUNNING))
876: sk_init(sc_if);
877: #ifdef INET
878: if (ifa->ifa_addr->sa_family == AF_INET)
879: arp_ifinit(&sc_if->arpcom, ifa);
880: #endif /* INET */
881: break;
882: case SIOCSIFMTU:
883: if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
884: error = EINVAL;
885: else if (ifp->if_mtu != ifr->ifr_mtu)
886: ifp->if_mtu = ifr->ifr_mtu;
887: break;
888: case SIOCSIFFLAGS:
889: if (ifp->if_flags & IFF_UP) {
890: if (ifp->if_flags & IFF_RUNNING &&
891: (ifp->if_flags ^ sc_if->sk_if_flags)
892: & IFF_PROMISC) {
893: sk_setpromisc(sc_if);
894: sk_setmulti(sc_if);
895: } else {
896: if (!(ifp->if_flags & IFF_RUNNING))
897: sk_init(sc_if);
898: }
899: } else {
900: if (ifp->if_flags & IFF_RUNNING)
901: sk_stop(sc_if);
902: }
903: sc_if->sk_if_flags = ifp->if_flags;
904: break;
905: case SIOCADDMULTI:
906: case SIOCDELMULTI:
907: error = (command == SIOCADDMULTI) ?
908: ether_addmulti(ifr, &sc_if->arpcom) :
909: ether_delmulti(ifr, &sc_if->arpcom);
910:
911: if (error == ENETRESET) {
912: /*
913: * Multicast list has changed; set the hardware
914: * filter accordingly.
915: */
916: if (ifp->if_flags & IFF_RUNNING)
917: sk_setmulti(sc_if);
918: error = 0;
919: }
920: break;
921: case SIOCGIFMEDIA:
922: case SIOCSIFMEDIA:
923: mii = &sc_if->sk_mii;
924: error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
925: break;
926: default:
927: error = ENOTTY;
928: break;
929: }
930:
931: splx(s);
932:
933: return (error);
934: }
935:
936: /*
937: * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device
938: * IDs against our list and return a device name if we find a match.
939: */
940: int
941: skc_probe(struct device *parent, void *match, void *aux)
942: {
943: struct pci_attach_args *pa = aux;
944: pci_chipset_tag_t pc = pa->pa_pc;
945: pcireg_t subid;
946:
947: subid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
948:
949: if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LINKSYS &&
950: PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LINKSYS_EG1032 &&
951: subid == SK_LINKSYS_EG1032_SUBID)
952: return (1);
953:
954: return (pci_matchbyid((struct pci_attach_args *)aux, skc_devices,
955: sizeof(skc_devices)/sizeof(skc_devices[0])));
956: }
957:
958: /*
959: * Force the GEnesis into reset, then bring it out of reset.
960: */
961: void
962: sk_reset(struct sk_softc *sc)
963: {
964: u_int32_t imtimer_ticks;
965:
966: DPRINTFN(2, ("sk_reset\n"));
967:
968: CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET);
969: CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET);
970: if (SK_IS_YUKON(sc))
971: CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
972:
973: DELAY(1000);
974: CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET);
975: DELAY(2);
976: CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
977: if (SK_IS_YUKON(sc))
978: CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
979:
980: DPRINTFN(2, ("sk_reset: sk_csr=%x\n", CSR_READ_2(sc, SK_CSR)));
981: DPRINTFN(2, ("sk_reset: sk_link_ctrl=%x\n",
982: CSR_READ_2(sc, SK_LINK_CTRL)));
983:
984: if (SK_IS_GENESIS(sc)) {
985: /* Configure packet arbiter */
986: sk_win_write_2(sc, SK_PKTARB_CTL, SK_PKTARBCTL_UNRESET);
987: sk_win_write_2(sc, SK_RXPA1_TINIT, SK_PKTARB_TIMEOUT);
988: sk_win_write_2(sc, SK_TXPA1_TINIT, SK_PKTARB_TIMEOUT);
989: sk_win_write_2(sc, SK_RXPA2_TINIT, SK_PKTARB_TIMEOUT);
990: sk_win_write_2(sc, SK_TXPA2_TINIT, SK_PKTARB_TIMEOUT);
991: }
992:
993: /* Enable RAM interface */
994: sk_win_write_4(sc, SK_RAMCTL, SK_RAMCTL_UNRESET);
995:
996: /*
997: * Configure interrupt moderation. The moderation timer
998: * defers interrupts specified in the interrupt moderation
999: * timer mask based on the timeout specified in the interrupt
1000: * moderation timer init register. Each bit in the timer
1001: * register represents one tick, so to specify a timeout in
1002: * microseconds, we have to multiply by the correct number of
1003: * ticks-per-microsecond.
1004: */
1005: switch (sc->sk_type) {
1006: case SK_GENESIS:
1007: imtimer_ticks = SK_IMTIMER_TICKS_GENESIS;
1008: break;
1009: default:
1010: imtimer_ticks = SK_IMTIMER_TICKS_YUKON;
1011: }
1012: sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(100));
1013: sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF|
1014: SK_ISR_RX1_EOF|SK_ISR_RX2_EOF);
1015: sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START);
1016: }
1017:
1018: int
1019: sk_probe(struct device *parent, void *match, void *aux)
1020: {
1021: struct skc_attach_args *sa = aux;
1022:
1023: if (sa->skc_port != SK_PORT_A && sa->skc_port != SK_PORT_B)
1024: return (0);
1025:
1026: switch (sa->skc_type) {
1027: case SK_GENESIS:
1028: case SK_YUKON:
1029: case SK_YUKON_LITE:
1030: case SK_YUKON_LP:
1031: return (1);
1032: }
1033:
1034: return (0);
1035: }
1036:
1037: /*
1038: * Each XMAC chip is attached as a separate logical IP interface.
1039: * Single port cards will have only one logical interface of course.
1040: */
1041: void
1042: sk_attach(struct device *parent, struct device *self, void *aux)
1043: {
1044: struct sk_if_softc *sc_if = (struct sk_if_softc *) self;
1045: struct sk_softc *sc = (struct sk_softc *)parent;
1046: struct skc_attach_args *sa = aux;
1047: struct ifnet *ifp;
1048: caddr_t kva;
1049: bus_dma_segment_t seg;
1050: int i, rseg;
1051:
1052: sc_if->sk_port = sa->skc_port;
1053: sc_if->sk_softc = sc;
1054: sc->sk_if[sa->skc_port] = sc_if;
1055:
1056: if (sa->skc_port == SK_PORT_A)
1057: sc_if->sk_tx_bmu = SK_BMU_TXS_CSR0;
1058: if (sa->skc_port == SK_PORT_B)
1059: sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1;
1060:
1061: DPRINTFN(2, ("begin sk_attach: port=%d\n", sc_if->sk_port));
1062:
1063: /*
1064: * Get station address for this interface. Note that
1065: * dual port cards actually come with three station
1066: * addresses: one for each port, plus an extra. The
1067: * extra one is used by the SysKonnect driver software
1068: * as a 'virtual' station address for when both ports
1069: * are operating in failover mode. Currently we don't
1070: * use this extra address.
1071: */
1072: for (i = 0; i < ETHER_ADDR_LEN; i++)
1073: sc_if->arpcom.ac_enaddr[i] =
1074: sk_win_read_1(sc, SK_MAC0_0 + (sa->skc_port * 8) + i);
1075:
1076: printf(": address %s\n",
1077: ether_sprintf(sc_if->arpcom.ac_enaddr));
1078:
1079: /*
1080: * Set up RAM buffer addresses. The NIC will have a certain
1081: * amount of SRAM on it, somewhere between 512K and 2MB. We
1082: * need to divide this up a) between the transmitter and
1083: * receiver and b) between the two XMACs, if this is a
1084: * dual port NIC. Our algorithm is to divide up the memory
1085: * evenly so that everyone gets a fair share.
1086: */
1087: if (sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC) {
1088: u_int32_t chunk, val;
1089:
1090: chunk = sc->sk_ramsize / 2;
1091: val = sc->sk_rboff / sizeof(u_int64_t);
1092: sc_if->sk_rx_ramstart = val;
1093: val += (chunk / sizeof(u_int64_t));
1094: sc_if->sk_rx_ramend = val - 1;
1095: sc_if->sk_tx_ramstart = val;
1096: val += (chunk / sizeof(u_int64_t));
1097: sc_if->sk_tx_ramend = val - 1;
1098: } else {
1099: u_int32_t chunk, val;
1100:
1101: chunk = sc->sk_ramsize / 4;
1102: val = (sc->sk_rboff + (chunk * 2 * sc_if->sk_port)) /
1103: sizeof(u_int64_t);
1104: sc_if->sk_rx_ramstart = val;
1105: val += (chunk / sizeof(u_int64_t));
1106: sc_if->sk_rx_ramend = val - 1;
1107: sc_if->sk_tx_ramstart = val;
1108: val += (chunk / sizeof(u_int64_t));
1109: sc_if->sk_tx_ramend = val - 1;
1110: }
1111:
1112: DPRINTFN(2, ("sk_attach: rx_ramstart=%#x rx_ramend=%#x\n"
1113: " tx_ramstart=%#x tx_ramend=%#x\n",
1114: sc_if->sk_rx_ramstart, sc_if->sk_rx_ramend,
1115: sc_if->sk_tx_ramstart, sc_if->sk_tx_ramend));
1116:
1117: /* Read and save PHY type */
1118: sc_if->sk_phytype = sk_win_read_1(sc, SK_EPROM1) & 0xF;
1119:
1120: /* Set PHY address */
1121: if (SK_IS_GENESIS(sc)) {
1122: switch (sc_if->sk_phytype) {
1123: case SK_PHYTYPE_XMAC:
1124: sc_if->sk_phyaddr = SK_PHYADDR_XMAC;
1125: break;
1126: case SK_PHYTYPE_BCOM:
1127: sc_if->sk_phyaddr = SK_PHYADDR_BCOM;
1128: break;
1129: default:
1130: printf("%s: unsupported PHY type: %d\n",
1131: sc->sk_dev.dv_xname, sc_if->sk_phytype);
1132: return;
1133: }
1134: }
1135:
1136: if (SK_IS_YUKON(sc)) {
1137: if ((sc_if->sk_phytype < SK_PHYTYPE_MARV_COPPER &&
1138: sc->sk_pmd != 'L' && sc->sk_pmd != 'S')) {
1139: /* not initialized, punt */
1140: sc_if->sk_phytype = SK_PHYTYPE_MARV_COPPER;
1141:
1142: sc->sk_coppertype = 1;
1143: }
1144:
1145: sc_if->sk_phyaddr = SK_PHYADDR_MARV;
1146:
1147: if (!(sc->sk_coppertype))
1148: sc_if->sk_phytype = SK_PHYTYPE_MARV_FIBER;
1149: }
1150:
1151: /* Allocate the descriptor queues. */
1152: if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct sk_ring_data),
1153: PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
1154: printf(": can't alloc rx buffers\n");
1155: goto fail;
1156: }
1157: if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
1158: sizeof(struct sk_ring_data), &kva, BUS_DMA_NOWAIT)) {
1159: printf(": can't map dma buffers (%lu bytes)\n",
1160: (ulong)sizeof(struct sk_ring_data));
1161: goto fail_1;
1162: }
1163: if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct sk_ring_data), 1,
1164: sizeof(struct sk_ring_data), 0, BUS_DMA_NOWAIT,
1165: &sc_if->sk_ring_map)) {
1166: printf(": can't create dma map\n");
1167: goto fail_2;
1168: }
1169: if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_ring_map, kva,
1170: sizeof(struct sk_ring_data), NULL, BUS_DMA_NOWAIT)) {
1171: printf(": can't load dma map\n");
1172: goto fail_3;
1173: }
1174: sc_if->sk_rdata = (struct sk_ring_data *)kva;
1175: bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
1176:
1177: /* Try to allocate memory for jumbo buffers. */
1178: if (sk_alloc_jumbo_mem(sc_if)) {
1179: printf(": jumbo buffer allocation failed\n");
1180: goto fail_3;
1181: }
1182:
1183: ifp = &sc_if->arpcom.ac_if;
1184: ifp->if_softc = sc_if;
1185: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1186: ifp->if_ioctl = sk_ioctl;
1187: ifp->if_start = sk_start;
1188: ifp->if_watchdog = sk_watchdog;
1189: ifp->if_baudrate = 1000000000;
1190: ifp->if_hardmtu = SK_JUMBO_MTU;
1191: IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1);
1192: IFQ_SET_READY(&ifp->if_snd);
1193: bcopy(sc_if->sk_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
1194:
1195: ifp->if_capabilities = IFCAP_VLAN_MTU;
1196:
1197: /*
1198: * Do miibus setup.
1199: */
1200: switch (sc->sk_type) {
1201: case SK_GENESIS:
1202: sk_init_xmac(sc_if);
1203: break;
1204: case SK_YUKON:
1205: case SK_YUKON_LITE:
1206: case SK_YUKON_LP:
1207: sk_init_yukon(sc_if);
1208: break;
1209: default:
1210: printf(": unknown device type %d\n", sc->sk_type);
1211: /* dealloc jumbo on error */
1212: goto fail_3;
1213: }
1214:
1215: DPRINTFN(2, ("sk_attach: 1\n"));
1216:
1217: sc_if->sk_mii.mii_ifp = ifp;
1218: if (SK_IS_GENESIS(sc)) {
1219: sc_if->sk_mii.mii_readreg = sk_xmac_miibus_readreg;
1220: sc_if->sk_mii.mii_writereg = sk_xmac_miibus_writereg;
1221: sc_if->sk_mii.mii_statchg = sk_xmac_miibus_statchg;
1222: } else {
1223: sc_if->sk_mii.mii_readreg = sk_marv_miibus_readreg;
1224: sc_if->sk_mii.mii_writereg = sk_marv_miibus_writereg;
1225: sc_if->sk_mii.mii_statchg = sk_marv_miibus_statchg;
1226: }
1227:
1228: ifmedia_init(&sc_if->sk_mii.mii_media, 0,
1229: sk_ifmedia_upd, sk_ifmedia_sts);
1230: if (SK_IS_GENESIS(sc)) {
1231: mii_attach(self, &sc_if->sk_mii, 0xffffffff, MII_PHY_ANY,
1232: MII_OFFSET_ANY, 0);
1233: } else {
1234: mii_attach(self, &sc_if->sk_mii, 0xffffffff, MII_PHY_ANY,
1235: MII_OFFSET_ANY, MIIF_DOPAUSE);
1236: }
1237: if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
1238: printf("%s: no PHY found!\n", sc_if->sk_dev.dv_xname);
1239: ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL,
1240: 0, NULL);
1241: ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL);
1242: } else
1243: ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_AUTO);
1244:
1245: if (SK_IS_GENESIS(sc)) {
1246: timeout_set(&sc_if->sk_tick_ch, sk_tick, sc_if);
1247: timeout_add(&sc_if->sk_tick_ch, hz);
1248: } else
1249: timeout_set(&sc_if->sk_tick_ch, sk_yukon_tick, sc_if);
1250:
1251: /*
1252: * Call MI attach routines.
1253: */
1254: if_attach(ifp);
1255: ether_ifattach(ifp);
1256:
1257: shutdownhook_establish(skc_shutdown, sc);
1258:
1259: DPRINTFN(2, ("sk_attach: end\n"));
1260: return;
1261:
1262: fail_3:
1263: bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
1264: fail_2:
1265: bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct sk_ring_data));
1266: fail_1:
1267: bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
1268: fail:
1269: sc->sk_if[sa->skc_port] = NULL;
1270: }
1271:
1272: int
1273: skcprint(void *aux, const char *pnp)
1274: {
1275: struct skc_attach_args *sa = aux;
1276:
1277: if (pnp)
1278: printf("sk port %c at %s",
1279: (sa->skc_port == SK_PORT_A) ? 'A' : 'B', pnp);
1280: else
1281: printf(" port %c", (sa->skc_port == SK_PORT_A) ? 'A' : 'B');
1282: return (UNCONF);
1283: }
1284:
1285: /*
1286: * Attach the interface. Allocate softc structures, do ifmedia
1287: * setup and ethernet/BPF attach.
1288: */
1289: void
1290: skc_attach(struct device *parent, struct device *self, void *aux)
1291: {
1292: struct sk_softc *sc = (struct sk_softc *)self;
1293: struct pci_attach_args *pa = aux;
1294: struct skc_attach_args skca;
1295: pci_chipset_tag_t pc = pa->pa_pc;
1296: pcireg_t command, memtype;
1297: pci_intr_handle_t ih;
1298: const char *intrstr = NULL;
1299: bus_size_t size;
1300: u_int8_t skrs;
1301: char *revstr = NULL;
1302:
1303: DPRINTFN(2, ("begin skc_attach\n"));
1304:
1305: /*
1306: * Handle power management nonsense.
1307: */
1308: command = pci_conf_read(pc, pa->pa_tag, SK_PCI_CAPID) & 0x000000FF;
1309:
1310: if (command == 0x01) {
1311: command = pci_conf_read(pc, pa->pa_tag, SK_PCI_PWRMGMTCTRL);
1312: if (command & SK_PSTATE_MASK) {
1313: u_int32_t iobase, membase, irq;
1314:
1315: /* Save important PCI config data. */
1316: iobase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOIO);
1317: membase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOMEM);
1318: irq = pci_conf_read(pc, pa->pa_tag, SK_PCI_INTLINE);
1319:
1320: /* Reset the power state. */
1321: printf("%s chip is in D%d power mode "
1322: "-- setting to D0\n", sc->sk_dev.dv_xname,
1323: command & SK_PSTATE_MASK);
1324: command &= 0xFFFFFFFC;
1325: pci_conf_write(pc, pa->pa_tag,
1326: SK_PCI_PWRMGMTCTRL, command);
1327:
1328: /* Restore PCI config data. */
1329: pci_conf_write(pc, pa->pa_tag, SK_PCI_LOIO, iobase);
1330: pci_conf_write(pc, pa->pa_tag, SK_PCI_LOMEM, membase);
1331: pci_conf_write(pc, pa->pa_tag, SK_PCI_INTLINE, irq);
1332: }
1333: }
1334:
1335: /*
1336: * Map control/status registers.
1337: */
1338:
1339: memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM);
1340: switch (memtype) {
1341: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
1342: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
1343: if (pci_mapreg_map(pa, SK_PCI_LOMEM,
1344: memtype, 0, &sc->sk_btag, &sc->sk_bhandle,
1345: NULL, &size, 0) == 0)
1346: break;
1347: default:
1348: printf(": can't map mem space\n");
1349: return;
1350: }
1351:
1352: sc->sc_dmatag = pa->pa_dmat;
1353:
1354: sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
1355: sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);
1356:
1357: /* bail out here if chip is not recognized */
1358: if (! SK_IS_GENESIS(sc) && ! SK_IS_YUKON(sc)) {
1359: printf(": unknown chip type: %d\n", sc->sk_type);
1360: goto fail_1;
1361: }
1362: DPRINTFN(2, ("skc_attach: allocate interrupt\n"));
1363:
1364: /* Allocate interrupt */
1365: if (pci_intr_map(pa, &ih)) {
1366: printf(": couldn't map interrupt\n");
1367: goto fail_1;
1368: }
1369:
1370: intrstr = pci_intr_string(pc, ih);
1371: sc->sk_intrhand = pci_intr_establish(pc, ih, IPL_NET, sk_intr, sc,
1372: self->dv_xname);
1373: if (sc->sk_intrhand == NULL) {
1374: printf(": couldn't establish interrupt");
1375: if (intrstr != NULL)
1376: printf(" at %s", intrstr);
1377: printf("\n");
1378: goto fail_1;
1379: }
1380:
1381: /* Reset the adapter. */
1382: sk_reset(sc);
1383:
1384: skrs = sk_win_read_1(sc, SK_EPROM0);
1385: if (SK_IS_GENESIS(sc)) {
1386: /* Read and save RAM size and RAMbuffer offset */
1387: switch(skrs) {
1388: case SK_RAMSIZE_512K_64:
1389: sc->sk_ramsize = 0x80000;
1390: sc->sk_rboff = SK_RBOFF_0;
1391: break;
1392: case SK_RAMSIZE_1024K_64:
1393: sc->sk_ramsize = 0x100000;
1394: sc->sk_rboff = SK_RBOFF_80000;
1395: break;
1396: case SK_RAMSIZE_1024K_128:
1397: sc->sk_ramsize = 0x100000;
1398: sc->sk_rboff = SK_RBOFF_0;
1399: break;
1400: case SK_RAMSIZE_2048K_128:
1401: sc->sk_ramsize = 0x200000;
1402: sc->sk_rboff = SK_RBOFF_0;
1403: break;
1404: default:
1405: printf(": unknown ram size: %d\n", skrs);
1406: goto fail_2;
1407: break;
1408: }
1409: } else {
1410: if (skrs == 0x00)
1411: sc->sk_ramsize = 0x20000;
1412: else
1413: sc->sk_ramsize = skrs * (1<<12);
1414: sc->sk_rboff = SK_RBOFF_0;
1415: }
1416:
1417: DPRINTFN(2, ("skc_attach: ramsize=%d (%dk), rboff=%d\n",
1418: sc->sk_ramsize, sc->sk_ramsize / 1024,
1419: sc->sk_rboff));
1420:
1421: /* Read and save physical media type */
1422: sc->sk_pmd = sk_win_read_1(sc, SK_PMDTYPE);
1423:
1424: if (sc->sk_pmd == 'T' || sc->sk_pmd == '1')
1425: sc->sk_coppertype = 1;
1426: else
1427: sc->sk_coppertype = 0;
1428:
1429: switch (sc->sk_type) {
1430: case SK_GENESIS:
1431: sc->sk_name = "GEnesis";
1432: break;
1433: case SK_YUKON:
1434: sc->sk_name = "Yukon";
1435: break;
1436: case SK_YUKON_LITE:
1437: sc->sk_name = "Yukon Lite";
1438: break;
1439: case SK_YUKON_LP:
1440: sc->sk_name = "Yukon LP";
1441: break;
1442: default:
1443: sc->sk_name = "Yukon (Unknown)";
1444: }
1445:
1446: /* Yukon Lite Rev A0 needs special test, from sk98lin driver */
1447: if (sc->sk_type == SK_YUKON || sc->sk_type == SK_YUKON_LP) {
1448: u_int32_t flashaddr;
1449: u_int8_t testbyte;
1450:
1451: flashaddr = sk_win_read_4(sc, SK_EP_ADDR);
1452:
1453: /* test Flash-Address Register */
1454: sk_win_write_1(sc, SK_EP_ADDR+3, 0xff);
1455: testbyte = sk_win_read_1(sc, SK_EP_ADDR+3);
1456:
1457: if (testbyte != 0) {
1458: /* This is a Yukon Lite Rev A0 */
1459: sc->sk_type = SK_YUKON_LITE;
1460: sc->sk_rev = SK_YUKON_LITE_REV_A0;
1461: /* restore Flash-Address Register */
1462: sk_win_write_4(sc, SK_EP_ADDR, flashaddr);
1463: }
1464: }
1465:
1466: if (sc->sk_type == SK_YUKON_LITE) {
1467: switch (sc->sk_rev) {
1468: case SK_YUKON_LITE_REV_A0:
1469: revstr = "A0";
1470: break;
1471: case SK_YUKON_LITE_REV_A1:
1472: revstr = "A1";
1473: break;
1474: case SK_YUKON_LITE_REV_A3:
1475: revstr = "A3";
1476: break;
1477: default:
1478: ;
1479: }
1480: }
1481:
1482: /* Announce the product name. */
1483: printf(", %s", sc->sk_name);
1484: if (revstr != NULL)
1485: printf(" rev. %s", revstr);
1486: printf(" (0x%x): %s\n", sc->sk_rev, intrstr);
1487:
1488: sc->sk_macs = 1;
1489:
1490: if (!(sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC))
1491: sc->sk_macs++;
1492:
1493: skca.skc_port = SK_PORT_A;
1494: skca.skc_type = sc->sk_type;
1495: skca.skc_rev = sc->sk_rev;
1496: (void)config_found(&sc->sk_dev, &skca, skcprint);
1497:
1498: if (sc->sk_macs > 1) {
1499: skca.skc_port = SK_PORT_B;
1500: skca.skc_type = sc->sk_type;
1501: skca.skc_rev = sc->sk_rev;
1502: (void)config_found(&sc->sk_dev, &skca, skcprint);
1503: }
1504:
1505: /* Turn on the 'driver is loaded' LED. */
1506: CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
1507:
1508: return;
1509:
1510: fail_2:
1511: pci_intr_disestablish(pc, sc->sk_intrhand);
1512: fail_1:
1513: bus_space_unmap(sc->sk_btag, sc->sk_bhandle, size);
1514: }
1515:
1516: int
1517: sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx)
1518: {
1519: struct sk_softc *sc = sc_if->sk_softc;
1520: struct sk_tx_desc *f = NULL;
1521: u_int32_t frag, cur, sk_ctl;
1522: int i;
1523: struct sk_txmap_entry *entry;
1524: bus_dmamap_t txmap;
1525:
1526: DPRINTFN(2, ("sk_encap\n"));
1527:
1528: entry = SIMPLEQ_FIRST(&sc_if->sk_txmap_head);
1529: if (entry == NULL) {
1530: DPRINTFN(2, ("sk_encap: no txmap available\n"));
1531: return (ENOBUFS);
1532: }
1533: txmap = entry->dmamap;
1534:
1535: cur = frag = *txidx;
1536:
1537: #ifdef SK_DEBUG
1538: if (skdebug >= 2)
1539: sk_dump_mbuf(m_head);
1540: #endif
1541:
1542: /*
1543: * Start packing the mbufs in this chain into
1544: * the fragment pointers. Stop when we run out
1545: * of fragments or hit the end of the mbuf chain.
1546: */
1547: if (bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head,
1548: BUS_DMA_NOWAIT)) {
1549: DPRINTFN(2, ("sk_encap: dmamap failed\n"));
1550: return (ENOBUFS);
1551: }
1552:
1553: if (txmap->dm_nsegs > (SK_TX_RING_CNT - sc_if->sk_cdata.sk_tx_cnt - 2)) {
1554: DPRINTFN(2, ("sk_encap: too few descriptors free\n"));
1555: bus_dmamap_unload(sc->sc_dmatag, txmap);
1556: return (ENOBUFS);
1557: }
1558:
1559: DPRINTFN(2, ("sk_encap: dm_nsegs=%d\n", txmap->dm_nsegs));
1560:
1561: /* Sync the DMA map. */
1562: bus_dmamap_sync(sc->sc_dmatag, txmap, 0, txmap->dm_mapsize,
1563: BUS_DMASYNC_PREWRITE);
1564:
1565: for (i = 0; i < txmap->dm_nsegs; i++) {
1566: f = &sc_if->sk_rdata->sk_tx_ring[frag];
1567: f->sk_data_lo = htole32(txmap->dm_segs[i].ds_addr);
1568: sk_ctl = txmap->dm_segs[i].ds_len | SK_OPCODE_DEFAULT;
1569: if (i == 0)
1570: sk_ctl |= SK_TXCTL_FIRSTFRAG;
1571: else
1572: sk_ctl |= SK_TXCTL_OWN;
1573: f->sk_ctl = htole32(sk_ctl);
1574: cur = frag;
1575: SK_INC(frag, SK_TX_RING_CNT);
1576: }
1577:
1578: sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head;
1579: SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
1580:
1581: sc_if->sk_cdata.sk_tx_map[cur] = entry;
1582: sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |=
1583: htole32(SK_TXCTL_LASTFRAG|SK_TXCTL_EOF_INTR);
1584:
1585: /* Sync descriptors before handing to chip */
1586: SK_CDTXSYNC(sc_if, *txidx, txmap->dm_nsegs,
1587: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1588:
1589: sc_if->sk_rdata->sk_tx_ring[*txidx].sk_ctl |=
1590: htole32(SK_TXCTL_OWN);
1591:
1592: /* Sync first descriptor to hand it off */
1593: SK_CDTXSYNC(sc_if, *txidx, 1, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1594:
1595: sc_if->sk_cdata.sk_tx_cnt += txmap->dm_nsegs;
1596:
1597: #ifdef SK_DEBUG
1598: if (skdebug >= 2) {
1599: struct sk_tx_desc *desc;
1600: u_int32_t idx;
1601: for (idx = *txidx; idx != frag; SK_INC(idx, SK_TX_RING_CNT)) {
1602: desc = &sc_if->sk_rdata->sk_tx_ring[idx];
1603: sk_dump_txdesc(desc, idx);
1604: }
1605: }
1606: #endif
1607:
1608: *txidx = frag;
1609:
1610: DPRINTFN(2, ("sk_encap: completed successfully\n"));
1611:
1612: return (0);
1613: }
1614:
1615: void
1616: sk_start(struct ifnet *ifp)
1617: {
1618: struct sk_if_softc *sc_if = ifp->if_softc;
1619: struct sk_softc *sc = sc_if->sk_softc;
1620: struct mbuf *m_head = NULL;
1621: u_int32_t idx = sc_if->sk_cdata.sk_tx_prod;
1622: int pkts = 0;
1623:
1624: DPRINTFN(2, ("sk_start\n"));
1625:
1626: while (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
1627: IFQ_POLL(&ifp->if_snd, m_head);
1628: if (m_head == NULL)
1629: break;
1630:
1631: /*
1632: * Pack the data into the transmit ring. If we
1633: * don't have room, set the OACTIVE flag and wait
1634: * for the NIC to drain the ring.
1635: */
1636: if (sk_encap(sc_if, m_head, &idx)) {
1637: ifp->if_flags |= IFF_OACTIVE;
1638: break;
1639: }
1640:
1641: /* now we are committed to transmit the packet */
1642: IFQ_DEQUEUE(&ifp->if_snd, m_head);
1643: pkts++;
1644:
1645: /*
1646: * If there's a BPF listener, bounce a copy of this frame
1647: * to him.
1648: */
1649: #if NBPFILTER > 0
1650: if (ifp->if_bpf)
1651: bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
1652: #endif
1653: }
1654: if (pkts == 0)
1655: return;
1656:
1657: /* Transmit */
1658: if (idx != sc_if->sk_cdata.sk_tx_prod) {
1659: sc_if->sk_cdata.sk_tx_prod = idx;
1660: CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
1661:
1662: /* Set a timeout in case the chip goes out to lunch. */
1663: ifp->if_timer = 5;
1664: }
1665: }
1666:
1667:
1668: void
1669: sk_watchdog(struct ifnet *ifp)
1670: {
1671: struct sk_if_softc *sc_if = ifp->if_softc;
1672:
1673: /*
1674: * Reclaim first as there is a possibility of losing Tx completion
1675: * interrupts.
1676: */
1677: sk_txeof(sc_if);
1678: if (sc_if->sk_cdata.sk_tx_cnt != 0) {
1679: printf("%s: watchdog timeout\n", sc_if->sk_dev.dv_xname);
1680:
1681: ifp->if_oerrors++;
1682:
1683: sk_init(sc_if);
1684: }
1685: }
1686:
1687: void
1688: skc_shutdown(void *v)
1689: {
1690: struct sk_softc *sc = v;
1691:
1692: DPRINTFN(2, ("sk_shutdown\n"));
1693:
1694: /* Turn off the 'driver is loaded' LED. */
1695: CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF);
1696:
1697: /*
1698: * Reset the GEnesis controller. Doing this should also
1699: * assert the resets on the attached XMAC(s).
1700: */
1701: sk_reset(sc);
1702: }
1703:
1704: static __inline int
1705: sk_rxvalid(struct sk_softc *sc, u_int32_t stat, u_int32_t len)
1706: {
1707: if (sc->sk_type == SK_GENESIS) {
1708: if ((stat & XM_RXSTAT_ERRFRAME) == XM_RXSTAT_ERRFRAME ||
1709: XM_RXSTAT_BYTES(stat) != len)
1710: return (0);
1711: } else {
1712: if ((stat & (YU_RXSTAT_CRCERR | YU_RXSTAT_LONGERR |
1713: YU_RXSTAT_MIIERR | YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC |
1714: YU_RXSTAT_JABBER)) != 0 ||
1715: (stat & YU_RXSTAT_RXOK) != YU_RXSTAT_RXOK ||
1716: YU_RXSTAT_BYTES(stat) != len)
1717: return (0);
1718: }
1719:
1720: return (1);
1721: }
1722:
1723: void
1724: sk_rxeof(struct sk_if_softc *sc_if)
1725: {
1726: struct sk_softc *sc = sc_if->sk_softc;
1727: struct ifnet *ifp = &sc_if->arpcom.ac_if;
1728: struct mbuf *m;
1729: struct sk_chain *cur_rx;
1730: struct sk_rx_desc *cur_desc;
1731: int i, cur, total_len = 0;
1732: u_int32_t rxstat, sk_ctl;
1733: bus_dmamap_t dmamap;
1734: u_int16_t csum1, csum2;
1735:
1736: DPRINTFN(2, ("sk_rxeof\n"));
1737:
1738: i = sc_if->sk_cdata.sk_rx_prod;
1739:
1740: for (;;) {
1741: cur = i;
1742:
1743: /* Sync the descriptor */
1744: SK_CDRXSYNC(sc_if, cur,
1745: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1746:
1747: sk_ctl = letoh32(sc_if->sk_rdata->sk_rx_ring[i].sk_ctl);
1748: if ((sk_ctl & SK_RXCTL_OWN) != 0) {
1749: /* Invalidate the descriptor -- it's not ready yet */
1750: SK_CDRXSYNC(sc_if, cur, BUS_DMASYNC_PREREAD);
1751: sc_if->sk_cdata.sk_rx_prod = i;
1752: break;
1753: }
1754:
1755: cur_rx = &sc_if->sk_cdata.sk_rx_chain[cur];
1756: cur_desc = &sc_if->sk_rdata->sk_rx_ring[cur];
1757: dmamap = sc_if->sk_cdata.sk_rx_jumbo_map;
1758:
1759: bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
1760: dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1761:
1762: rxstat = letoh32(cur_desc->sk_xmac_rxstat);
1763: m = cur_rx->sk_mbuf;
1764: cur_rx->sk_mbuf = NULL;
1765: total_len = SK_RXBYTES(letoh32(cur_desc->sk_ctl));
1766:
1767: csum1 = letoh16(sc_if->sk_rdata->sk_rx_ring[i].sk_csum1);
1768: csum2 = letoh16(sc_if->sk_rdata->sk_rx_ring[i].sk_csum2);
1769:
1770: SK_INC(i, SK_RX_RING_CNT);
1771:
1772: if ((sk_ctl & (SK_RXCTL_STATUS_VALID | SK_RXCTL_FIRSTFRAG |
1773: SK_RXCTL_LASTFRAG)) != (SK_RXCTL_STATUS_VALID |
1774: SK_RXCTL_FIRSTFRAG | SK_RXCTL_LASTFRAG) ||
1775: total_len < SK_MIN_FRAMELEN ||
1776: total_len > SK_JUMBO_FRAMELEN ||
1777: sk_rxvalid(sc, rxstat, total_len) == 0) {
1778: ifp->if_ierrors++;
1779: sk_newbuf(sc_if, cur, m, dmamap);
1780: continue;
1781: }
1782:
1783: /*
1784: * Try to allocate a new jumbo buffer. If that
1785: * fails, copy the packet to mbufs and put the
1786: * jumbo buffer back in the ring so it can be
1787: * re-used. If allocating mbufs fails, then we
1788: * have to drop the packet.
1789: */
1790: if (sk_newbuf(sc_if, cur, NULL, dmamap) == ENOBUFS) {
1791: struct mbuf *m0;
1792: m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
1793: total_len + ETHER_ALIGN, 0, ifp, NULL);
1794: sk_newbuf(sc_if, cur, m, dmamap);
1795: if (m0 == NULL) {
1796: ifp->if_ierrors++;
1797: continue;
1798: }
1799: m_adj(m0, ETHER_ALIGN);
1800: m = m0;
1801: } else {
1802: m->m_pkthdr.rcvif = ifp;
1803: m->m_pkthdr.len = m->m_len = total_len;
1804: }
1805:
1806: ifp->if_ipackets++;
1807:
1808: sk_rxcsum(ifp, m, csum1, csum2);
1809:
1810: #if NBPFILTER > 0
1811: if (ifp->if_bpf)
1812: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1813: #endif
1814:
1815: /* pass it on. */
1816: ether_input_mbuf(ifp, m);
1817: }
1818: }
1819:
1820: void
1821: sk_rxcsum(struct ifnet *ifp, struct mbuf *m, const u_int16_t csum1, const u_int16_t csum2)
1822: {
1823: struct ether_header *eh;
1824: struct ip *ip;
1825: u_int8_t *pp;
1826: int hlen, len, plen;
1827: u_int16_t iph_csum, ipo_csum, ipd_csum, csum;
1828:
1829: pp = mtod(m, u_int8_t *);
1830: plen = m->m_pkthdr.len;
1831: if (plen < sizeof(*eh))
1832: return;
1833: eh = (struct ether_header *)pp;
1834: iph_csum = in_cksum_addword(csum1, (~csum2 & 0xffff));
1835:
1836: if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
1837: u_int16_t *xp = (u_int16_t *)pp;
1838:
1839: xp = (u_int16_t *)pp;
1840: if (xp[1] != htons(ETHERTYPE_IP))
1841: return;
1842: iph_csum = in_cksum_addword(iph_csum, (~xp[0] & 0xffff));
1843: iph_csum = in_cksum_addword(iph_csum, (~xp[1] & 0xffff));
1844: xp = (u_int16_t *)(pp + sizeof(struct ip));
1845: iph_csum = in_cksum_addword(iph_csum, xp[0]);
1846: iph_csum = in_cksum_addword(iph_csum, xp[1]);
1847: pp += EVL_ENCAPLEN;
1848: } else if (eh->ether_type != htons(ETHERTYPE_IP))
1849: return;
1850:
1851: pp += sizeof(*eh);
1852: plen -= sizeof(*eh);
1853:
1854: ip = (struct ip *)pp;
1855:
1856: if (ip->ip_v != IPVERSION)
1857: return;
1858:
1859: hlen = ip->ip_hl << 2;
1860: if (hlen < sizeof(struct ip))
1861: return;
1862: if (hlen > ntohs(ip->ip_len))
1863: return;
1864:
1865: /* Don't deal with truncated or padded packets. */
1866: if (plen != ntohs(ip->ip_len))
1867: return;
1868:
1869: len = hlen - sizeof(struct ip);
1870: if (len > 0) {
1871: u_int16_t *p;
1872:
1873: p = (u_int16_t *)(ip + 1);
1874: ipo_csum = 0;
1875: for (ipo_csum = 0; len > 0; len -= sizeof(*p), p++)
1876: ipo_csum = in_cksum_addword(ipo_csum, *p);
1877: iph_csum = in_cksum_addword(iph_csum, ipo_csum);
1878: ipd_csum = in_cksum_addword(csum2, (~ipo_csum & 0xffff));
1879: } else
1880: ipd_csum = csum2;
1881:
1882: if (iph_csum != 0xffff)
1883: return;
1884: m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
1885:
1886: if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
1887: return; /* ip frag, we're done for now */
1888:
1889: pp += hlen;
1890:
1891: /* Only know checksum protocol for udp/tcp */
1892: if (ip->ip_p == IPPROTO_UDP) {
1893: struct udphdr *uh = (struct udphdr *)pp;
1894:
1895: if (uh->uh_sum == 0) /* udp with no checksum */
1896: return;
1897: } else if (ip->ip_p != IPPROTO_TCP)
1898: return;
1899:
1900: csum = in_cksum_phdr(ip->ip_src.s_addr, ip->ip_dst.s_addr,
1901: htonl(ntohs(ip->ip_len) - hlen + ip->ip_p) + ipd_csum);
1902: if (csum == 0xffff) {
1903: m->m_pkthdr.csum_flags |= (ip->ip_p == IPPROTO_TCP) ?
1904: M_TCP_CSUM_IN_OK : M_UDP_CSUM_IN_OK;
1905: }
1906: }
1907:
1908: void
1909: sk_txeof(struct sk_if_softc *sc_if)
1910: {
1911: struct sk_softc *sc = sc_if->sk_softc;
1912: struct sk_tx_desc *cur_tx;
1913: struct ifnet *ifp = &sc_if->arpcom.ac_if;
1914: u_int32_t idx, sk_ctl;
1915: struct sk_txmap_entry *entry;
1916:
1917: DPRINTFN(2, ("sk_txeof\n"));
1918:
1919: /*
1920: * Go through our tx ring and free mbufs for those
1921: * frames that have been sent.
1922: */
1923: idx = sc_if->sk_cdata.sk_tx_cons;
1924: while (idx != sc_if->sk_cdata.sk_tx_prod) {
1925: SK_CDTXSYNC(sc_if, idx, 1,
1926: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1927:
1928: cur_tx = &sc_if->sk_rdata->sk_tx_ring[idx];
1929: sk_ctl = letoh32(cur_tx->sk_ctl);
1930: #ifdef SK_DEBUG
1931: if (skdebug >= 2)
1932: sk_dump_txdesc(cur_tx, idx);
1933: #endif
1934: if (sk_ctl & SK_TXCTL_OWN) {
1935: SK_CDTXSYNC(sc_if, idx, 1, BUS_DMASYNC_PREREAD);
1936: break;
1937: }
1938: if (sk_ctl & SK_TXCTL_LASTFRAG)
1939: ifp->if_opackets++;
1940: if (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf != NULL) {
1941: entry = sc_if->sk_cdata.sk_tx_map[idx];
1942:
1943: m_freem(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf);
1944: sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf = NULL;
1945:
1946: bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0,
1947: entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1948:
1949: bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
1950: SIMPLEQ_INSERT_TAIL(&sc_if->sk_txmap_head, entry,
1951: link);
1952: sc_if->sk_cdata.sk_tx_map[idx] = NULL;
1953: }
1954: sc_if->sk_cdata.sk_tx_cnt--;
1955: SK_INC(idx, SK_TX_RING_CNT);
1956: }
1957: ifp->if_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? 5 : 0;
1958:
1959: if (sc_if->sk_cdata.sk_tx_cnt < SK_TX_RING_CNT - 2)
1960: ifp->if_flags &= ~IFF_OACTIVE;
1961:
1962: sc_if->sk_cdata.sk_tx_cons = idx;
1963: }
1964:
1965: void
1966: sk_tick(void *xsc_if)
1967: {
1968: struct sk_if_softc *sc_if = xsc_if;
1969: struct mii_data *mii = &sc_if->sk_mii;
1970: struct ifnet *ifp = &sc_if->arpcom.ac_if;
1971: int i;
1972:
1973: DPRINTFN(2, ("sk_tick\n"));
1974:
1975: if (!(ifp->if_flags & IFF_UP))
1976: return;
1977:
1978: if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
1979: sk_intr_bcom(sc_if);
1980: return;
1981: }
1982:
1983: /*
1984: * According to SysKonnect, the correct way to verify that
1985: * the link has come back up is to poll bit 0 of the GPIO
1986: * register three times. This pin has the signal from the
1987: * link sync pin connected to it; if we read the same link
1988: * state 3 times in a row, we know the link is up.
1989: */
1990: for (i = 0; i < 3; i++) {
1991: if (SK_XM_READ_2(sc_if, XM_GPIO) & XM_GPIO_GP0_SET)
1992: break;
1993: }
1994:
1995: if (i != 3) {
1996: timeout_add(&sc_if->sk_tick_ch, hz);
1997: return;
1998: }
1999:
2000: /* Turn the GP0 interrupt back on. */
2001: SK_XM_CLRBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET);
2002: SK_XM_READ_2(sc_if, XM_ISR);
2003: mii_tick(mii);
2004: timeout_del(&sc_if->sk_tick_ch);
2005: }
2006:
2007: void
2008: sk_yukon_tick(void *xsc_if)
2009: {
2010: struct sk_if_softc *sc_if = xsc_if;
2011: struct mii_data *mii = &sc_if->sk_mii;
2012:
2013: mii_tick(mii);
2014: timeout_add(&sc_if->sk_tick_ch, hz);
2015: }
2016:
2017: void
2018: sk_intr_bcom(struct sk_if_softc *sc_if)
2019: {
2020: struct mii_data *mii = &sc_if->sk_mii;
2021: struct ifnet *ifp = &sc_if->arpcom.ac_if;
2022: int status;
2023:
2024: DPRINTFN(2, ("sk_intr_bcom\n"));
2025:
2026: SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
2027:
2028: /*
2029: * Read the PHY interrupt register to make sure
2030: * we clear any pending interrupts.
2031: */
2032: status = sk_xmac_miibus_readreg((struct device *)sc_if,
2033: SK_PHYADDR_BCOM, BRGPHY_MII_ISR);
2034:
2035: if (!(ifp->if_flags & IFF_RUNNING)) {
2036: sk_init_xmac(sc_if);
2037: return;
2038: }
2039:
2040: if (status & (BRGPHY_ISR_LNK_CHG|BRGPHY_ISR_AN_PR)) {
2041: int lstat;
2042: lstat = sk_xmac_miibus_readreg((struct device *)sc_if,
2043: SK_PHYADDR_BCOM, BRGPHY_MII_AUXSTS);
2044:
2045: if (!(lstat & BRGPHY_AUXSTS_LINK) && sc_if->sk_link) {
2046: mii_mediachg(mii);
2047: /* Turn off the link LED. */
2048: SK_IF_WRITE_1(sc_if, 0,
2049: SK_LINKLED1_CTL, SK_LINKLED_OFF);
2050: sc_if->sk_link = 0;
2051: } else if (status & BRGPHY_ISR_LNK_CHG) {
2052: sk_xmac_miibus_writereg((struct device *)sc_if,
2053: SK_PHYADDR_BCOM, BRGPHY_MII_IMR, 0xFF00);
2054: mii_tick(mii);
2055: sc_if->sk_link = 1;
2056: /* Turn on the link LED. */
2057: SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL,
2058: SK_LINKLED_ON|SK_LINKLED_LINKSYNC_OFF|
2059: SK_LINKLED_BLINK_OFF);
2060: } else {
2061: mii_tick(mii);
2062: timeout_add(&sc_if->sk_tick_ch, hz);
2063: }
2064: }
2065:
2066: SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
2067: }
2068:
2069: void
2070: sk_intr_xmac(struct sk_if_softc *sc_if)
2071: {
2072: u_int16_t status = SK_XM_READ_2(sc_if, XM_ISR);
2073:
2074: DPRINTFN(2, ("sk_intr_xmac\n"));
2075:
2076: if (sc_if->sk_phytype == SK_PHYTYPE_XMAC) {
2077: if (status & XM_ISR_GP0_SET) {
2078: SK_XM_SETBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET);
2079: timeout_add(&sc_if->sk_tick_ch, hz);
2080: }
2081:
2082: if (status & XM_ISR_AUTONEG_DONE) {
2083: timeout_add(&sc_if->sk_tick_ch, hz);
2084: }
2085: }
2086:
2087: if (status & XM_IMR_TX_UNDERRUN)
2088: SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_TXFIFO);
2089:
2090: if (status & XM_IMR_RX_OVERRUN)
2091: SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_RXFIFO);
2092: }
2093:
2094: void
2095: sk_intr_yukon(struct sk_if_softc *sc_if)
2096: {
2097: u_int8_t status;
2098:
2099: status = SK_IF_READ_1(sc_if, 0, SK_GMAC_ISR);
2100: /* RX overrun */
2101: if ((status & SK_GMAC_INT_RX_OVER) != 0) {
2102: SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST,
2103: SK_RFCTL_RX_FIFO_OVER);
2104: }
2105: /* TX underrun */
2106: if ((status & SK_GMAC_INT_TX_UNDER) != 0) {
2107: SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST,
2108: SK_TFCTL_TX_FIFO_UNDER);
2109: }
2110:
2111: DPRINTFN(2, ("sk_intr_yukon status=%#x\n", status));
2112: }
2113:
2114: int
2115: sk_intr(void *xsc)
2116: {
2117: struct sk_softc *sc = xsc;
2118: struct sk_if_softc *sc_if0 = sc->sk_if[SK_PORT_A];
2119: struct sk_if_softc *sc_if1 = sc->sk_if[SK_PORT_B];
2120: struct ifnet *ifp0 = NULL, *ifp1 = NULL;
2121: u_int32_t status;
2122: int claimed = 0;
2123:
2124: status = CSR_READ_4(sc, SK_ISSR);
2125: if (status == 0 || status == 0xffffffff)
2126: return (0);
2127:
2128: if (sc_if0 != NULL)
2129: ifp0 = &sc_if0->arpcom.ac_if;
2130: if (sc_if1 != NULL)
2131: ifp1 = &sc_if1->arpcom.ac_if;
2132:
2133: for (; (status &= sc->sk_intrmask) != 0;) {
2134: claimed = 1;
2135:
2136: /* Handle receive interrupts first. */
2137: if (sc_if0 && (status & SK_ISR_RX1_EOF)) {
2138: sk_rxeof(sc_if0);
2139: CSR_WRITE_4(sc, SK_BMU_RX_CSR0,
2140: SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START);
2141: }
2142: if (sc_if1 && (status & SK_ISR_RX2_EOF)) {
2143: sk_rxeof(sc_if1);
2144: CSR_WRITE_4(sc, SK_BMU_RX_CSR1,
2145: SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START);
2146: }
2147:
2148: /* Then transmit interrupts. */
2149: if (sc_if0 && (status & SK_ISR_TX1_S_EOF)) {
2150: sk_txeof(sc_if0);
2151: CSR_WRITE_4(sc, SK_BMU_TXS_CSR0,
2152: SK_TXBMU_CLR_IRQ_EOF);
2153: }
2154: if (sc_if1 && (status & SK_ISR_TX2_S_EOF)) {
2155: sk_txeof(sc_if1);
2156: CSR_WRITE_4(sc, SK_BMU_TXS_CSR1,
2157: SK_TXBMU_CLR_IRQ_EOF);
2158: }
2159:
2160: /* Then MAC interrupts. */
2161: if (sc_if0 && (status & SK_ISR_MAC1) &&
2162: (ifp0->if_flags & IFF_RUNNING)) {
2163: if (SK_IS_GENESIS(sc))
2164: sk_intr_xmac(sc_if0);
2165: else
2166: sk_intr_yukon(sc_if0);
2167: }
2168:
2169: if (sc_if1 && (status & SK_ISR_MAC2) &&
2170: (ifp1->if_flags & IFF_RUNNING)) {
2171: if (SK_IS_GENESIS(sc))
2172: sk_intr_xmac(sc_if1);
2173: else
2174: sk_intr_yukon(sc_if1);
2175:
2176: }
2177:
2178: if (status & SK_ISR_EXTERNAL_REG) {
2179: if (sc_if0 != NULL &&
2180: sc_if0->sk_phytype == SK_PHYTYPE_BCOM)
2181: sk_intr_bcom(sc_if0);
2182:
2183: if (sc_if1 != NULL &&
2184: sc_if1->sk_phytype == SK_PHYTYPE_BCOM)
2185: sk_intr_bcom(sc_if1);
2186: }
2187: status = CSR_READ_4(sc, SK_ISSR);
2188: }
2189:
2190: CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2191:
2192: if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd))
2193: sk_start(ifp0);
2194: if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd))
2195: sk_start(ifp1);
2196:
2197: return (claimed);
2198: }
2199:
2200: void
2201: sk_init_xmac(struct sk_if_softc *sc_if)
2202: {
2203: struct sk_softc *sc = sc_if->sk_softc;
2204: struct ifnet *ifp = &sc_if->arpcom.ac_if;
2205: struct sk_bcom_hack bhack[] = {
2206: { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
2207: { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
2208: { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
2209: { 0, 0 } };
2210:
2211: DPRINTFN(2, ("sk_init_xmac\n"));
2212:
2213: /* Unreset the XMAC. */
2214: SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_UNRESET);
2215: DELAY(1000);
2216:
2217: /* Reset the XMAC's internal state. */
2218: SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
2219:
2220: /* Save the XMAC II revision */
2221: sc_if->sk_xmac_rev = XM_XMAC_REV(SK_XM_READ_4(sc_if, XM_DEVID));
2222:
2223: /*
2224: * Perform additional initialization for external PHYs,
2225: * namely for the 1000baseTX cards that use the XMAC's
2226: * GMII mode.
2227: */
2228: if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
2229: int i = 0;
2230: u_int32_t val;
2231:
2232: /* Take PHY out of reset. */
2233: val = sk_win_read_4(sc, SK_GPIO);
2234: if (sc_if->sk_port == SK_PORT_A)
2235: val |= SK_GPIO_DIR0|SK_GPIO_DAT0;
2236: else
2237: val |= SK_GPIO_DIR2|SK_GPIO_DAT2;
2238: sk_win_write_4(sc, SK_GPIO, val);
2239:
2240: /* Enable GMII mode on the XMAC. */
2241: SK_XM_SETBIT_2(sc_if, XM_HWCFG, XM_HWCFG_GMIIMODE);
2242:
2243: sk_xmac_miibus_writereg((struct device *)sc_if,
2244: SK_PHYADDR_BCOM, BRGPHY_MII_BMCR, BRGPHY_BMCR_RESET);
2245: DELAY(10000);
2246: sk_xmac_miibus_writereg((struct device *)sc_if,
2247: SK_PHYADDR_BCOM, BRGPHY_MII_IMR, 0xFFF0);
2248:
2249: /*
2250: * Early versions of the BCM5400 apparently have
2251: * a bug that requires them to have their reserved
2252: * registers initialized to some magic values. I don't
2253: * know what the numbers do, I'm just the messenger.
2254: */
2255: if (sk_xmac_miibus_readreg((struct device *)sc_if,
2256: SK_PHYADDR_BCOM, 0x03) == 0x6041) {
2257: while(bhack[i].reg) {
2258: sk_xmac_miibus_writereg((struct device *)sc_if,
2259: SK_PHYADDR_BCOM, bhack[i].reg,
2260: bhack[i].val);
2261: i++;
2262: }
2263: }
2264: }
2265:
2266: /* Set station address */
2267: SK_XM_WRITE_2(sc_if, XM_PAR0,
2268: letoh16(*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[0])));
2269: SK_XM_WRITE_2(sc_if, XM_PAR1,
2270: letoh16(*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[2])));
2271: SK_XM_WRITE_2(sc_if, XM_PAR2,
2272: letoh16(*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[4])));
2273: SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_STATION);
2274:
2275: if (ifp->if_flags & IFF_BROADCAST)
2276: SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD);
2277: else
2278: SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD);
2279:
2280: /* We don't need the FCS appended to the packet. */
2281: SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_STRIPFCS);
2282:
2283: /* We want short frames padded to 60 bytes. */
2284: SK_XM_SETBIT_2(sc_if, XM_TXCMD, XM_TXCMD_AUTOPAD);
2285:
2286: /*
2287: * Enable the reception of all error frames. This is
2288: * a necessary evil due to the design of the XMAC. The
2289: * XMAC's receive FIFO is only 8K in size, however jumbo
2290: * frames can be up to 9000 bytes in length. When bad
2291: * frame filtering is enabled, the XMAC's RX FIFO operates
2292: * in 'store and forward' mode. For this to work, the
2293: * entire frame has to fit into the FIFO, but that means
2294: * that jumbo frames larger than 8192 bytes will be
2295: * truncated. Disabling all bad frame filtering causes
2296: * the RX FIFO to operate in streaming mode, in which
2297: * case the XMAC will start transfering frames out of the
2298: * RX FIFO as soon as the FIFO threshold is reached.
2299: */
2300: SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_BADFRAMES|
2301: XM_MODE_RX_GIANTS|XM_MODE_RX_RUNTS|XM_MODE_RX_CRCERRS|
2302: XM_MODE_RX_INRANGELEN);
2303:
2304: SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK);
2305:
2306: /*
2307: * Bump up the transmit threshold. This helps hold off transmit
2308: * underruns when we're blasting traffic from both ports at once.
2309: */
2310: SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH);
2311:
2312: /* Set promiscuous mode */
2313: sk_setpromisc(sc_if);
2314:
2315: /* Set multicast filter */
2316: sk_setmulti(sc_if);
2317:
2318: /* Clear and enable interrupts */
2319: SK_XM_READ_2(sc_if, XM_ISR);
2320: if (sc_if->sk_phytype == SK_PHYTYPE_XMAC)
2321: SK_XM_WRITE_2(sc_if, XM_IMR, XM_INTRS);
2322: else
2323: SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
2324:
2325: /* Configure MAC arbiter */
2326: switch(sc_if->sk_xmac_rev) {
2327: case XM_XMAC_REV_B2:
2328: sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_B2);
2329: sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_B2);
2330: sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_B2);
2331: sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_B2);
2332: sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_B2);
2333: sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_B2);
2334: sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_B2);
2335: sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_B2);
2336: sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2);
2337: break;
2338: case XM_XMAC_REV_C1:
2339: sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_C1);
2340: sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_C1);
2341: sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_C1);
2342: sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_C1);
2343: sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_C1);
2344: sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_C1);
2345: sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_C1);
2346: sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_C1);
2347: sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2);
2348: break;
2349: default:
2350: break;
2351: }
2352: sk_win_write_2(sc, SK_MACARB_CTL,
2353: SK_MACARBCTL_UNRESET|SK_MACARBCTL_FASTOE_OFF);
2354:
2355: sc_if->sk_link = 1;
2356: }
2357:
2358: void sk_init_yukon(struct sk_if_softc *sc_if)
2359: {
2360: u_int32_t phy, v;
2361: u_int16_t reg;
2362: struct sk_softc *sc;
2363: int i;
2364:
2365: sc = sc_if->sk_softc;
2366:
2367: DPRINTFN(2, ("sk_init_yukon: start: sk_csr=%#x\n",
2368: CSR_READ_4(sc_if->sk_softc, SK_CSR)));
2369:
2370: if (sc->sk_type == SK_YUKON_LITE &&
2371: sc->sk_rev >= SK_YUKON_LITE_REV_A3) {
2372: /*
2373: * Workaround code for COMA mode, set PHY reset.
2374: * Otherwise it will not correctly take chip out of
2375: * powerdown (coma)
2376: */
2377: v = sk_win_read_4(sc, SK_GPIO);
2378: v |= SK_GPIO_DIR9 | SK_GPIO_DAT9;
2379: sk_win_write_4(sc, SK_GPIO, v);
2380: }
2381:
2382: DPRINTFN(6, ("sk_init_yukon: 1\n"));
2383:
2384: /* GMAC and GPHY Reset */
2385: SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
2386: SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
2387: DELAY(1000);
2388:
2389: DPRINTFN(6, ("sk_init_yukon: 2\n"));
2390:
2391: if (sc->sk_type == SK_YUKON_LITE &&
2392: sc->sk_rev >= SK_YUKON_LITE_REV_A3) {
2393: /*
2394: * Workaround code for COMA mode, clear PHY reset
2395: */
2396: v = sk_win_read_4(sc, SK_GPIO);
2397: v |= SK_GPIO_DIR9;
2398: v &= ~SK_GPIO_DAT9;
2399: sk_win_write_4(sc, SK_GPIO, v);
2400: }
2401:
2402: phy = SK_GPHY_INT_POL_HI | SK_GPHY_DIS_FC | SK_GPHY_DIS_SLEEP |
2403: SK_GPHY_ENA_XC | SK_GPHY_ANEG_ALL | SK_GPHY_ENA_PAUSE;
2404:
2405: if (sc->sk_coppertype)
2406: phy |= SK_GPHY_COPPER;
2407: else
2408: phy |= SK_GPHY_FIBER;
2409:
2410: DPRINTFN(3, ("sk_init_yukon: phy=%#x\n", phy));
2411:
2412: SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_SET);
2413: DELAY(1000);
2414: SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_CLEAR);
2415: SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
2416: SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
2417:
2418: DPRINTFN(3, ("sk_init_yukon: gmac_ctrl=%#x\n",
2419: SK_IF_READ_4(sc_if, 0, SK_GMAC_CTRL)));
2420:
2421: DPRINTFN(6, ("sk_init_yukon: 3\n"));
2422:
2423: /* unused read of the interrupt source register */
2424: DPRINTFN(6, ("sk_init_yukon: 4\n"));
2425: SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR);
2426:
2427: DPRINTFN(6, ("sk_init_yukon: 4a\n"));
2428: reg = SK_YU_READ_2(sc_if, YUKON_PAR);
2429: DPRINTFN(6, ("sk_init_yukon: YUKON_PAR=%#x\n", reg));
2430:
2431: /* MIB Counter Clear Mode set */
2432: reg |= YU_PAR_MIB_CLR;
2433: DPRINTFN(6, ("sk_init_yukon: YUKON_PAR=%#x\n", reg));
2434: DPRINTFN(6, ("sk_init_yukon: 4b\n"));
2435: SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
2436:
2437: /* MIB Counter Clear Mode clear */
2438: DPRINTFN(6, ("sk_init_yukon: 5\n"));
2439: reg &= ~YU_PAR_MIB_CLR;
2440: SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
2441:
2442: /* receive control reg */
2443: DPRINTFN(6, ("sk_init_yukon: 7\n"));
2444: SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
2445:
2446: /* transmit parameter register */
2447: DPRINTFN(6, ("sk_init_yukon: 8\n"));
2448: SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
2449: YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) );
2450:
2451: /* serial mode register */
2452: DPRINTFN(6, ("sk_init_yukon: 9\n"));
2453: SK_YU_WRITE_2(sc_if, YUKON_SMR, YU_SMR_DATA_BLIND(0x1c) |
2454: YU_SMR_MFL_VLAN | YU_SMR_MFL_JUMBO |
2455: YU_SMR_IPG_DATA(0x1e));
2456:
2457: DPRINTFN(6, ("sk_init_yukon: 10\n"));
2458: /* Setup Yukon's address */
2459: for (i = 0; i < 3; i++) {
2460: /* Write Source Address 1 (unicast filter) */
2461: SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4,
2462: sc_if->arpcom.ac_enaddr[i * 2] |
2463: sc_if->arpcom.ac_enaddr[i * 2 + 1] << 8);
2464: }
2465:
2466: for (i = 0; i < 3; i++) {
2467: reg = sk_win_read_2(sc_if->sk_softc,
2468: SK_MAC1_0 + i * 2 + sc_if->sk_port * 8);
2469: SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
2470: }
2471:
2472: /* Set promiscuous mode */
2473: sk_setpromisc(sc_if);
2474:
2475: /* Set multicast filter */
2476: DPRINTFN(6, ("sk_init_yukon: 11\n"));
2477: sk_setmulti(sc_if);
2478:
2479: /* enable interrupt mask for counter overflows */
2480: DPRINTFN(6, ("sk_init_yukon: 12\n"));
2481: SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
2482: SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0);
2483: SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0);
2484:
2485: /* Configure RX MAC FIFO Flush Mask */
2486: v = YU_RXSTAT_FOFL | YU_RXSTAT_CRCERR | YU_RXSTAT_MIIERR |
2487: YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC | YU_RXSTAT_RUNT |
2488: YU_RXSTAT_JABBER;
2489: SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_MASK, v);
2490:
2491: /* Disable RX MAC FIFO Flush for YUKON-Lite Rev. A0 only */
2492: if (sc->sk_type == SK_YUKON_LITE && sc->sk_rev == SK_YUKON_LITE_REV_A0)
2493: v = SK_TFCTL_OPERATION_ON;
2494: else
2495: v = SK_TFCTL_OPERATION_ON | SK_RFCTL_FIFO_FLUSH_ON;
2496: /* Configure RX MAC FIFO */
2497: SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR);
2498: SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_CTRL_TEST, v);
2499:
2500: /* Increase flush threshould to 64 bytes */
2501: SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_THRESHOLD,
2502: SK_RFCTL_FIFO_THRESHOLD + 1);
2503:
2504: /* Configure TX MAC FIFO */
2505: SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR);
2506: SK_IF_WRITE_2(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON);
2507:
2508: DPRINTFN(6, ("sk_init_yukon: end\n"));
2509: }
2510:
2511: /*
2512: * Note that to properly initialize any part of the GEnesis chip,
2513: * you first have to take it out of reset mode.
2514: */
2515: void
2516: sk_init(void *xsc_if)
2517: {
2518: struct sk_if_softc *sc_if = xsc_if;
2519: struct sk_softc *sc = sc_if->sk_softc;
2520: struct ifnet *ifp = &sc_if->arpcom.ac_if;
2521: struct mii_data *mii = &sc_if->sk_mii;
2522: int s;
2523:
2524: DPRINTFN(2, ("sk_init\n"));
2525:
2526: s = splnet();
2527:
2528: /* Cancel pending I/O and free all RX/TX buffers. */
2529: sk_stop(sc_if);
2530:
2531: if (SK_IS_GENESIS(sc)) {
2532: /* Configure LINK_SYNC LED */
2533: SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_ON);
2534: SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL,
2535: SK_LINKLED_LINKSYNC_ON);
2536:
2537: /* Configure RX LED */
2538: SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL,
2539: SK_RXLEDCTL_COUNTER_START);
2540:
2541: /* Configure TX LED */
2542: SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL,
2543: SK_TXLEDCTL_COUNTER_START);
2544: }
2545:
2546: /*
2547: * Configure descriptor poll timer
2548: *
2549: * SK-NET GENESIS data sheet says that possibility of losing Start
2550: * transmit command due to CPU/cache related interim storage problems
2551: * under certain conditions. The document recommends a polling
2552: * mechanism to send a Start transmit command to initiate transfer
2553: * of ready descriptors regulary. To cope with this issue sk(4) now
2554: * enables descriptor poll timer to initiate descriptor processing
2555: * periodically as defined by SK_DPT_TIMER_MAX. However sk(4) still
2556: * issue SK_TXBMU_TX_START to Tx BMU to get fast execution of Tx
2557: * command instead of waiting for next descriptor polling time.
2558: * The same rule may apply to Rx side too but it seems that is not
2559: * needed at the moment.
2560: * Since sk(4) uses descriptor polling as a last resort there is no
2561: * need to set smaller polling time than maximum allowable one.
2562: */
2563: SK_IF_WRITE_4(sc_if, 0, SK_DPT_INIT, SK_DPT_TIMER_MAX);
2564:
2565: /* Configure I2C registers */
2566:
2567: /* Configure XMAC(s) */
2568: switch (sc->sk_type) {
2569: case SK_GENESIS:
2570: sk_init_xmac(sc_if);
2571: break;
2572: case SK_YUKON:
2573: case SK_YUKON_LITE:
2574: case SK_YUKON_LP:
2575: sk_init_yukon(sc_if);
2576: break;
2577: }
2578: mii_mediachg(mii);
2579:
2580: if (SK_IS_GENESIS(sc)) {
2581: /* Configure MAC FIFOs */
2582: SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET);
2583: SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END);
2584: SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON);
2585:
2586: SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET);
2587: SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END);
2588: SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON);
2589: }
2590:
2591: /* Configure transmit arbiter(s) */
2592: SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL,
2593: SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON);
2594:
2595: /* Configure RAMbuffers */
2596: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET);
2597: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart);
2598: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart);
2599: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart);
2600: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend);
2601: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON);
2602:
2603: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_UNRESET);
2604: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_STORENFWD_ON);
2605: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_START, sc_if->sk_tx_ramstart);
2606: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_WR_PTR, sc_if->sk_tx_ramstart);
2607: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_RD_PTR, sc_if->sk_tx_ramstart);
2608: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_END, sc_if->sk_tx_ramend);
2609: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_ON);
2610:
2611: /* Configure BMUs */
2612: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_ONLINE);
2613: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_LO,
2614: SK_RX_RING_ADDR(sc_if, 0));
2615: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_HI, 0);
2616:
2617: SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_ONLINE);
2618: SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_LO,
2619: SK_TX_RING_ADDR(sc_if, 0));
2620: SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_HI, 0);
2621:
2622: /* Init descriptors */
2623: if (sk_init_rx_ring(sc_if) == ENOBUFS) {
2624: printf("%s: initialization failed: no "
2625: "memory for rx buffers\n", sc_if->sk_dev.dv_xname);
2626: sk_stop(sc_if);
2627: splx(s);
2628: return;
2629: }
2630:
2631: if (sk_init_tx_ring(sc_if) == ENOBUFS) {
2632: printf("%s: initialization failed: no "
2633: "memory for tx buffers\n", sc_if->sk_dev.dv_xname);
2634: sk_stop(sc_if);
2635: splx(s);
2636: return;
2637: }
2638:
2639: /* Configure interrupt handling */
2640: CSR_READ_4(sc, SK_ISSR);
2641: if (sc_if->sk_port == SK_PORT_A)
2642: sc->sk_intrmask |= SK_INTRS1;
2643: else
2644: sc->sk_intrmask |= SK_INTRS2;
2645:
2646: sc->sk_intrmask |= SK_ISR_EXTERNAL_REG;
2647:
2648: CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2649:
2650: /* Start BMUs. */
2651: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_START);
2652:
2653: if (SK_IS_GENESIS(sc)) {
2654: /* Enable XMACs TX and RX state machines */
2655: SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_IGNPAUSE);
2656: SK_XM_SETBIT_2(sc_if, XM_MMUCMD,
2657: XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
2658: }
2659:
2660: if (SK_IS_YUKON(sc)) {
2661: u_int16_t reg = SK_YU_READ_2(sc_if, YUKON_GPCR);
2662: reg |= YU_GPCR_TXEN | YU_GPCR_RXEN;
2663: SK_YU_WRITE_2(sc_if, YUKON_GPCR, reg);
2664: }
2665:
2666: /* Activate descriptor polling timer */
2667: SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_START);
2668: /* start transfer of Tx descriptors */
2669: CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
2670:
2671: ifp->if_flags |= IFF_RUNNING;
2672: ifp->if_flags &= ~IFF_OACTIVE;
2673:
2674: if (SK_IS_YUKON(sc))
2675: timeout_add(&sc_if->sk_tick_ch, hz);
2676:
2677: splx(s);
2678: }
2679:
2680: void
2681: sk_stop(struct sk_if_softc *sc_if)
2682: {
2683: struct sk_softc *sc = sc_if->sk_softc;
2684: struct ifnet *ifp = &sc_if->arpcom.ac_if;
2685: struct sk_txmap_entry *dma;
2686: int i;
2687: u_int32_t val;
2688:
2689: DPRINTFN(2, ("sk_stop\n"));
2690:
2691: timeout_del(&sc_if->sk_tick_ch);
2692:
2693: ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
2694:
2695: /* stop Tx descriptor polling timer */
2696: SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP);
2697: /* stop transfer of Tx descriptors */
2698: CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_STOP);
2699: for (i = 0; i < SK_TIMEOUT; i++) {
2700: val = CSR_READ_4(sc, sc_if->sk_tx_bmu);
2701: if (!(val & SK_TXBMU_TX_STOP))
2702: break;
2703: DELAY(1);
2704: }
2705: if (i == SK_TIMEOUT)
2706: printf("%s: cannot stop transfer of Tx descriptors\n",
2707: sc_if->sk_dev.dv_xname);
2708: /* stop transfer of Rx descriptors */
2709: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_STOP);
2710: for (i = 0; i < SK_TIMEOUT; i++) {
2711: val = SK_IF_READ_4(sc_if, 0, SK_RXQ1_BMU_CSR);
2712: if (!(val & SK_RXBMU_RX_STOP))
2713: break;
2714: DELAY(1);
2715: }
2716: if (i == SK_TIMEOUT)
2717: printf("%s: cannot stop transfer of Rx descriptors\n",
2718: sc_if->sk_dev.dv_xname);
2719:
2720: if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
2721: u_int32_t val;
2722:
2723: /* Put PHY back into reset. */
2724: val = sk_win_read_4(sc, SK_GPIO);
2725: if (sc_if->sk_port == SK_PORT_A) {
2726: val |= SK_GPIO_DIR0;
2727: val &= ~SK_GPIO_DAT0;
2728: } else {
2729: val |= SK_GPIO_DIR2;
2730: val &= ~SK_GPIO_DAT2;
2731: }
2732: sk_win_write_4(sc, SK_GPIO, val);
2733: }
2734:
2735: /* Turn off various components of this interface. */
2736: SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
2737: switch (sc->sk_type) {
2738: case SK_GENESIS:
2739: SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL,
2740: SK_TXMACCTL_XMAC_RESET);
2741: SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET);
2742: break;
2743: case SK_YUKON:
2744: case SK_YUKON_LITE:
2745: case SK_YUKON_LP:
2746: SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
2747: SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
2748: break;
2749: }
2750: SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
2751: SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2752: SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE);
2753: SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2754: SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
2755: SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
2756: SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
2757: SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
2758: SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
2759:
2760: /* Disable interrupts */
2761: if (sc_if->sk_port == SK_PORT_A)
2762: sc->sk_intrmask &= ~SK_INTRS1;
2763: else
2764: sc->sk_intrmask &= ~SK_INTRS2;
2765: CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2766:
2767: SK_XM_READ_2(sc_if, XM_ISR);
2768: SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
2769:
2770: /* Free RX and TX mbufs still in the queues. */
2771: for (i = 0; i < SK_RX_RING_CNT; i++) {
2772: if (sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf != NULL) {
2773: m_freem(sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf);
2774: sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL;
2775: }
2776: }
2777:
2778: for (i = 0; i < SK_TX_RING_CNT; i++) {
2779: if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) {
2780: m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf);
2781: sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL;
2782: SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head,
2783: sc_if->sk_cdata.sk_tx_map[i], link);
2784: sc_if->sk_cdata.sk_tx_map[i] = 0;
2785: }
2786: }
2787:
2788: while ((dma = SIMPLEQ_FIRST(&sc_if->sk_txmap_head))) {
2789: SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
2790: bus_dmamap_destroy(sc->sc_dmatag, dma->dmamap);
2791: free(dma, M_DEVBUF);
2792: }
2793: }
2794:
2795: struct cfattach skc_ca = {
2796: sizeof(struct sk_softc), skc_probe, skc_attach,
2797: };
2798:
2799: struct cfdriver skc_cd = {
2800: 0, "skc", DV_DULL
2801: };
2802:
2803: struct cfattach sk_ca = {
2804: sizeof(struct sk_if_softc), sk_probe, sk_attach,
2805: };
2806:
2807: struct cfdriver sk_cd = {
2808: 0, "sk", DV_IFNET
2809: };
2810:
2811: #ifdef SK_DEBUG
2812: void
2813: sk_dump_txdesc(struct sk_tx_desc *desc, int idx)
2814: {
2815: #define DESC_PRINT(X) \
2816: if (X) \
2817: printf("txdesc[%d]." #X "=%#x\n", \
2818: idx, X);
2819:
2820: DESC_PRINT(letoh32(desc->sk_ctl));
2821: DESC_PRINT(letoh32(desc->sk_next));
2822: DESC_PRINT(letoh32(desc->sk_data_lo));
2823: DESC_PRINT(letoh32(desc->sk_data_hi));
2824: DESC_PRINT(letoh32(desc->sk_xmac_txstat));
2825: DESC_PRINT(letoh16(desc->sk_rsvd0));
2826: DESC_PRINT(letoh16(desc->sk_csum_startval));
2827: DESC_PRINT(letoh16(desc->sk_csum_startpos));
2828: DESC_PRINT(letoh16(desc->sk_csum_writepos));
2829: DESC_PRINT(letoh16(desc->sk_rsvd1));
2830: #undef PRINT
2831: }
2832:
2833: void
2834: sk_dump_bytes(const char *data, int len)
2835: {
2836: int c, i, j;
2837:
2838: for (i = 0; i < len; i += 16) {
2839: printf("%08x ", i);
2840: c = len - i;
2841: if (c > 16) c = 16;
2842:
2843: for (j = 0; j < c; j++) {
2844: printf("%02x ", data[i + j] & 0xff);
2845: if ((j & 0xf) == 7 && j > 0)
2846: printf(" ");
2847: }
2848:
2849: for (; j < 16; j++)
2850: printf(" ");
2851: printf(" ");
2852:
2853: for (j = 0; j < c; j++) {
2854: int ch = data[i + j] & 0xff;
2855: printf("%c", ' ' <= ch && ch <= '~' ? ch : ' ');
2856: }
2857:
2858: printf("\n");
2859:
2860: if (c < 16)
2861: break;
2862: }
2863: }
2864:
2865: void
2866: sk_dump_mbuf(struct mbuf *m)
2867: {
2868: int count = m->m_pkthdr.len;
2869:
2870: printf("m=%#lx, m->m_pkthdr.len=%#d\n", m, m->m_pkthdr.len);
2871:
2872: while (count > 0 && m) {
2873: printf("m=%#lx, m->m_data=%#lx, m->m_len=%d\n",
2874: m, m->m_data, m->m_len);
2875: sk_dump_bytes(mtod(m, char *), m->m_len);
2876:
2877: count -= m->m_len;
2878: m = m->m_next;
2879: }
2880: }
2881: #endif
CVSweb