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