Line data Source code
1 : /* $OpenBSD: if_msk.c,v 1.131 2018/01/06 03:11:04 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 :
116 : #include <dev/pci/pcireg.h>
117 : #include <dev/pci/pcivar.h>
118 : #include <dev/pci/pcidevs.h>
119 :
120 : #include <dev/pci/if_skreg.h>
121 : #include <dev/pci/if_mskvar.h>
122 :
123 : int mskc_probe(struct device *, void *, void *);
124 : void mskc_attach(struct device *, struct device *self, void *aux);
125 : int mskc_detach(struct device *, int);
126 : int mskc_activate(struct device *, int);
127 : void mskc_reset(struct sk_softc *);
128 : int msk_probe(struct device *, void *, void *);
129 : void msk_attach(struct device *, struct device *self, void *aux);
130 : int msk_detach(struct device *, int);
131 : int msk_activate(struct device *, int);
132 : void msk_reset(struct sk_if_softc *);
133 : int mskcprint(void *, const char *);
134 : int msk_intr(void *);
135 : void msk_intr_yukon(struct sk_if_softc *);
136 : static inline int msk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t);
137 : void msk_rxeof(struct sk_if_softc *, uint16_t, uint32_t);
138 : void msk_txeof(struct sk_if_softc *);
139 : static unsigned int msk_encap(struct sk_if_softc *, struct mbuf *, uint32_t);
140 : void msk_start(struct ifnet *);
141 : int msk_ioctl(struct ifnet *, u_long, caddr_t);
142 : void msk_init(void *);
143 : void msk_init_yukon(struct sk_if_softc *);
144 : void msk_stop(struct sk_if_softc *, int);
145 : void msk_watchdog(struct ifnet *);
146 : int msk_ifmedia_upd(struct ifnet *);
147 : void msk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
148 : static int msk_newbuf(struct sk_if_softc *);
149 : int msk_init_rx_ring(struct sk_if_softc *);
150 : int msk_init_tx_ring(struct sk_if_softc *);
151 : void msk_fill_rx_ring(struct sk_if_softc *);
152 :
153 : int msk_miibus_readreg(struct device *, int, int);
154 : void msk_miibus_writereg(struct device *, int, int, int);
155 : void msk_miibus_statchg(struct device *);
156 :
157 : void msk_iff(struct sk_if_softc *);
158 : void msk_tick(void *);
159 : void msk_fill_rx_tick(void *);
160 :
161 : #ifdef MSK_DEBUG
162 : #define DPRINTF(x) if (mskdebug) printf x
163 : #define DPRINTFN(n,x) if (mskdebug >= (n)) printf x
164 : int mskdebug = 0;
165 :
166 : void msk_dump_txdesc(struct msk_tx_desc *, int);
167 : void msk_dump_mbuf(struct mbuf *);
168 : void msk_dump_bytes(const char *, int);
169 : #else
170 : #define DPRINTF(x)
171 : #define DPRINTFN(n,x)
172 : #endif
173 :
174 : /* supported device vendors */
175 : const struct pci_matchid mskc_devices[] = {
176 : { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE550SX },
177 : { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE550T_B1 },
178 : { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE560SX },
179 : { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE560T },
180 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8021CU },
181 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8021X },
182 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8022CU },
183 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8022X },
184 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8035 },
185 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8036 },
186 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8038 },
187 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8039 },
188 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8040 },
189 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8040T },
190 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8042 },
191 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8048 },
192 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8050 },
193 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8052 },
194 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8053 },
195 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8055 },
196 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8055_2 },
197 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8056 },
198 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8057 },
199 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8058 },
200 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8059 },
201 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8061CU },
202 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8061X },
203 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8062CU },
204 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8062X },
205 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8070 },
206 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8071 },
207 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8072 },
208 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8075 },
209 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_8079 },
210 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C032 },
211 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C033 },
212 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C034 },
213 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C036 },
214 : { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_YUKON_C042 },
215 : { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK9Exx },
216 : { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK9Sxx }
217 : };
218 :
219 : static inline u_int32_t
220 0 : sk_win_read_4(struct sk_softc *sc, u_int32_t reg)
221 : {
222 0 : return CSR_READ_4(sc, reg);
223 : }
224 :
225 : static inline u_int16_t
226 0 : sk_win_read_2(struct sk_softc *sc, u_int32_t reg)
227 : {
228 0 : return CSR_READ_2(sc, reg);
229 : }
230 :
231 : static inline u_int8_t
232 0 : sk_win_read_1(struct sk_softc *sc, u_int32_t reg)
233 : {
234 0 : return CSR_READ_1(sc, reg);
235 : }
236 :
237 : static inline void
238 0 : sk_win_write_4(struct sk_softc *sc, u_int32_t reg, u_int32_t x)
239 : {
240 0 : CSR_WRITE_4(sc, reg, x);
241 0 : }
242 :
243 : static inline void
244 0 : sk_win_write_2(struct sk_softc *sc, u_int32_t reg, u_int16_t x)
245 : {
246 0 : CSR_WRITE_2(sc, reg, x);
247 0 : }
248 :
249 : static inline void
250 0 : sk_win_write_1(struct sk_softc *sc, u_int32_t reg, u_int8_t x)
251 : {
252 0 : CSR_WRITE_1(sc, reg, x);
253 0 : }
254 :
255 : int
256 0 : msk_miibus_readreg(struct device *dev, int phy, int reg)
257 : {
258 0 : struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
259 : u_int16_t val;
260 : int i;
261 :
262 0 : SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
263 : YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ);
264 :
265 0 : for (i = 0; i < SK_TIMEOUT; i++) {
266 0 : DELAY(1);
267 0 : val = SK_YU_READ_2(sc_if, YUKON_SMICR);
268 0 : if (val & YU_SMICR_READ_VALID)
269 : break;
270 : }
271 :
272 0 : if (i == SK_TIMEOUT) {
273 0 : printf("%s: phy failed to come ready\n",
274 0 : sc_if->sk_dev.dv_xname);
275 0 : return (0);
276 : }
277 :
278 : DPRINTFN(9, ("msk_miibus_readreg: i=%d, timeout=%d\n", i,
279 : SK_TIMEOUT));
280 :
281 0 : val = SK_YU_READ_2(sc_if, YUKON_SMIDR);
282 :
283 : DPRINTFN(9, ("msk_miibus_readreg phy=%d, reg=%#x, val=%#x\n",
284 : phy, reg, val));
285 :
286 0 : return (val);
287 0 : }
288 :
289 : void
290 0 : msk_miibus_writereg(struct device *dev, int phy, int reg, int val)
291 : {
292 0 : struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
293 : int i;
294 :
295 : DPRINTFN(9, ("msk_miibus_writereg phy=%d reg=%#x val=%#x\n",
296 : phy, reg, val));
297 :
298 0 : SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val);
299 0 : SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
300 : YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE);
301 :
302 0 : for (i = 0; i < SK_TIMEOUT; i++) {
303 0 : DELAY(1);
304 0 : if (!(SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY))
305 : break;
306 : }
307 :
308 0 : if (i == SK_TIMEOUT)
309 0 : printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname);
310 0 : }
311 :
312 : void
313 0 : msk_miibus_statchg(struct device *dev)
314 : {
315 0 : struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
316 0 : struct mii_data *mii = &sc_if->sk_mii;
317 0 : struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
318 : int gpcr;
319 :
320 0 : gpcr = SK_YU_READ_2(sc_if, YUKON_GPCR);
321 0 : gpcr &= (YU_GPCR_TXEN | YU_GPCR_RXEN);
322 :
323 0 : if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO ||
324 0 : sc_if->sk_softc->sk_type == SK_YUKON_FE_P) {
325 : /* Set speed. */
326 0 : gpcr |= YU_GPCR_SPEED_DIS;
327 0 : switch (IFM_SUBTYPE(mii->mii_media_active)) {
328 : case IFM_1000_SX:
329 : case IFM_1000_LX:
330 : case IFM_1000_CX:
331 : case IFM_1000_T:
332 0 : gpcr |= (YU_GPCR_GIG | YU_GPCR_SPEED);
333 0 : break;
334 : case IFM_100_TX:
335 0 : gpcr |= YU_GPCR_SPEED;
336 0 : break;
337 : }
338 :
339 : /* Set duplex. */
340 0 : gpcr |= YU_GPCR_DPLX_DIS;
341 0 : if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
342 0 : gpcr |= YU_GPCR_DUPLEX;
343 :
344 : /* Disable flow control. */
345 0 : gpcr |= YU_GPCR_FCTL_DIS;
346 0 : gpcr |= (YU_GPCR_FCTL_TX_DIS | YU_GPCR_FCTL_RX_DIS);
347 0 : }
348 :
349 0 : SK_YU_WRITE_2(sc_if, YUKON_GPCR, gpcr);
350 :
351 : DPRINTFN(9, ("msk_miibus_statchg: gpcr=%x\n",
352 : SK_YU_READ_2(((struct sk_if_softc *)dev), YUKON_GPCR)));
353 0 : }
354 :
355 : void
356 0 : msk_iff(struct sk_if_softc *sc_if)
357 : {
358 0 : struct ifnet *ifp = &sc_if->arpcom.ac_if;
359 : struct arpcom *ac = &sc_if->arpcom;
360 : struct ether_multi *enm;
361 : struct ether_multistep step;
362 : u_int32_t hashes[2];
363 : u_int16_t rcr;
364 : int h;
365 :
366 0 : rcr = SK_YU_READ_2(sc_if, YUKON_RCR);
367 0 : rcr &= ~(YU_RCR_MUFLEN | YU_RCR_UFLEN);
368 0 : ifp->if_flags &= ~IFF_ALLMULTI;
369 :
370 : /*
371 : * Always accept frames destined to our station address.
372 : */
373 0 : rcr |= YU_RCR_UFLEN;
374 :
375 0 : if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
376 0 : ifp->if_flags |= IFF_ALLMULTI;
377 0 : if (ifp->if_flags & IFF_PROMISC)
378 0 : rcr &= ~YU_RCR_UFLEN;
379 : else
380 0 : rcr |= YU_RCR_MUFLEN;
381 : hashes[0] = hashes[1] = 0xFFFFFFFF;
382 0 : } else {
383 0 : rcr |= YU_RCR_MUFLEN;
384 : /* Program new filter. */
385 : bzero(hashes, sizeof(hashes));
386 :
387 0 : ETHER_FIRST_MULTI(step, ac, enm);
388 0 : while (enm != NULL) {
389 0 : h = ether_crc32_be(enm->enm_addrlo,
390 0 : ETHER_ADDR_LEN) & ((1 << SK_HASH_BITS) - 1);
391 :
392 0 : if (h < 32)
393 0 : hashes[0] |= (1 << h);
394 : else
395 0 : hashes[1] |= (1 << (h - 32));
396 :
397 0 : ETHER_NEXT_MULTI(step, enm);
398 : }
399 : }
400 :
401 0 : SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
402 0 : SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
403 0 : SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
404 0 : SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff);
405 0 : SK_YU_WRITE_2(sc_if, YUKON_RCR, rcr);
406 0 : }
407 :
408 : int
409 0 : msk_init_rx_ring(struct sk_if_softc *sc_if)
410 : {
411 0 : struct msk_ring_data *rd = sc_if->sk_rdata;
412 : struct msk_rx_desc *r;
413 :
414 0 : memset(rd->sk_rx_ring, 0, sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT);
415 :
416 0 : r = &rd->sk_rx_ring[0];
417 0 : r->sk_addr = htole32(0);
418 0 : r->sk_opcode = SK_Y2_RXOPC_OWN | SK_Y2_RXOPC_ADDR64;
419 :
420 0 : sc_if->sk_cdata.sk_rx_prod = 1;
421 0 : sc_if->sk_cdata.sk_rx_cons = 0;
422 0 : sc_if->sk_cdata.sk_rx_hiaddr = 0;
423 :
424 : /*
425 : * up to two ring entries per packet, so the effective ring size is
426 : * halved
427 : */
428 0 : if_rxr_init(&sc_if->sk_cdata.sk_rx_ring, 2, (MSK_RX_RING_CNT/2) - 1);
429 :
430 0 : msk_fill_rx_ring(sc_if);
431 0 : return (0);
432 : }
433 :
434 : int
435 0 : msk_init_tx_ring(struct sk_if_softc *sc_if)
436 : {
437 0 : struct sk_softc *sc = sc_if->sk_softc;
438 0 : struct msk_ring_data *rd = sc_if->sk_rdata;
439 : struct msk_tx_desc *t;
440 : int i;
441 :
442 0 : memset(rd->sk_tx_ring, 0, sizeof(struct msk_tx_desc) * MSK_TX_RING_CNT);
443 :
444 0 : for (i = 0; i < MSK_TX_RING_CNT; i++) {
445 0 : if (bus_dmamap_create(sc->sc_dmatag, sc_if->sk_pktlen,
446 : SK_NTXSEG, sc_if->sk_pktlen, 0,
447 : BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
448 : &sc_if->sk_cdata.sk_tx_maps[i]))
449 0 : return (ENOBUFS);
450 : }
451 :
452 0 : t = &rd->sk_tx_ring[0];
453 0 : t->sk_addr = htole32(0);
454 0 : t->sk_opcode = SK_Y2_TXOPC_OWN | SK_Y2_TXOPC_ADDR64;
455 :
456 0 : sc_if->sk_cdata.sk_tx_prod = 1;
457 0 : sc_if->sk_cdata.sk_tx_cons = 0;
458 0 : sc_if->sk_cdata.sk_tx_hiaddr = 0;
459 :
460 0 : MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT, BUS_DMASYNC_PREWRITE);
461 :
462 0 : return (0);
463 0 : }
464 :
465 : static int
466 0 : msk_newbuf(struct sk_if_softc *sc_if)
467 : {
468 0 : struct msk_ring_data *rd = sc_if->sk_rdata;
469 : struct msk_rx_desc *r;
470 : struct mbuf *m;
471 : bus_dmamap_t map;
472 : uint64_t addr;
473 : uint32_t prod, head;
474 : uint32_t hiaddr;
475 0 : unsigned int pktlen = sc_if->sk_pktlen + ETHER_ALIGN;
476 :
477 0 : m = MCLGETI(NULL, M_DONTWAIT, NULL, pktlen);
478 0 : if (m == NULL)
479 0 : return (0);
480 0 : m->m_len = m->m_pkthdr.len = pktlen;
481 0 : m_adj(m, ETHER_ALIGN);
482 :
483 0 : prod = sc_if->sk_cdata.sk_rx_prod;
484 0 : map = sc_if->sk_cdata.sk_rx_maps[prod];
485 :
486 0 : if (bus_dmamap_load_mbuf(sc_if->sk_softc->sc_dmatag, map, m,
487 0 : BUS_DMA_READ|BUS_DMA_NOWAIT) != 0) {
488 0 : m_freem(m);
489 0 : return (0);
490 : }
491 :
492 0 : bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, map, 0,
493 : map->dm_mapsize, BUS_DMASYNC_PREREAD);
494 :
495 : head = prod;
496 :
497 : /* high 32 bits of address */
498 0 : addr = map->dm_segs[0].ds_addr;
499 0 : hiaddr = addr >> 32;
500 0 : if (sc_if->sk_cdata.sk_rx_hiaddr != hiaddr) {
501 0 : r = &rd->sk_rx_ring[prod];
502 0 : htolem32(&r->sk_addr, hiaddr);
503 0 : r->sk_len = htole16(0);
504 0 : r->sk_ctl = 0;
505 0 : r->sk_opcode = SK_Y2_RXOPC_OWN | SK_Y2_RXOPC_ADDR64;
506 :
507 0 : sc_if->sk_cdata.sk_rx_hiaddr = hiaddr;
508 :
509 : //printf("%s: addr64 @%u (%08x)\n", __func__, prod, hiaddr);
510 0 : SK_INC(prod, MSK_RX_RING_CNT);
511 0 : }
512 :
513 0 : r = &rd->sk_rx_ring[prod];
514 0 : htolem32(&r->sk_addr, addr);
515 0 : htolem16(&r->sk_len, map->dm_segs[0].ds_len);
516 0 : r->sk_ctl = 0;
517 0 : r->sk_opcode = SK_Y2_RXOPC_OWN | SK_Y2_RXOPC_PACKET;
518 : //printf("%s: packet @%u\n", __func__, prod);
519 :
520 0 : sc_if->sk_cdata.sk_rx_maps[head] = sc_if->sk_cdata.sk_rx_maps[prod];
521 0 : sc_if->sk_cdata.sk_rx_maps[prod] = map;
522 :
523 0 : sc_if->sk_cdata.sk_rx_mbuf[prod] = m;
524 :
525 0 : SK_INC(prod, MSK_RX_RING_CNT);
526 : //printf("%s: prod %u\n", __func__, prod);
527 0 : sc_if->sk_cdata.sk_rx_prod = prod;
528 :
529 0 : return (1);
530 0 : }
531 :
532 : /*
533 : * Set media options.
534 : */
535 : int
536 0 : msk_ifmedia_upd(struct ifnet *ifp)
537 : {
538 0 : struct sk_if_softc *sc_if = ifp->if_softc;
539 :
540 0 : mii_mediachg(&sc_if->sk_mii);
541 0 : return (0);
542 : }
543 :
544 : /*
545 : * Report current media status.
546 : */
547 : void
548 0 : msk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
549 : {
550 0 : struct sk_if_softc *sc_if = ifp->if_softc;
551 :
552 0 : mii_pollstat(&sc_if->sk_mii);
553 0 : ifmr->ifm_active = sc_if->sk_mii.mii_media_active;
554 0 : ifmr->ifm_status = sc_if->sk_mii.mii_media_status;
555 0 : }
556 :
557 : int
558 0 : msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
559 : {
560 0 : struct sk_if_softc *sc_if = ifp->if_softc;
561 0 : struct ifreq *ifr = (struct ifreq *) data;
562 : struct mii_data *mii;
563 : int s, error = 0;
564 :
565 0 : s = splnet();
566 :
567 0 : switch(command) {
568 : case SIOCSIFADDR:
569 0 : ifp->if_flags |= IFF_UP;
570 0 : if (!(ifp->if_flags & IFF_RUNNING))
571 0 : msk_init(sc_if);
572 : break;
573 :
574 : case SIOCSIFFLAGS:
575 0 : if (ifp->if_flags & IFF_UP) {
576 0 : if (ifp->if_flags & IFF_RUNNING)
577 0 : error = ENETRESET;
578 : else
579 0 : msk_init(sc_if);
580 : } else {
581 0 : if (ifp->if_flags & IFF_RUNNING)
582 0 : msk_stop(sc_if, 0);
583 : }
584 : break;
585 :
586 : case SIOCGIFMEDIA:
587 : case SIOCSIFMEDIA:
588 0 : mii = &sc_if->sk_mii;
589 0 : error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
590 0 : break;
591 :
592 : case SIOCGIFRXR:
593 0 : error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
594 0 : NULL, sc_if->sk_pktlen, &sc_if->sk_cdata.sk_rx_ring);
595 0 : break;
596 :
597 : default:
598 0 : error = ether_ioctl(ifp, &sc_if->arpcom, command, data);
599 0 : }
600 :
601 0 : if (error == ENETRESET) {
602 0 : if (ifp->if_flags & IFF_RUNNING)
603 0 : msk_iff(sc_if);
604 : error = 0;
605 0 : }
606 :
607 0 : splx(s);
608 0 : return (error);
609 : }
610 :
611 : /*
612 : * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device
613 : * IDs against our list and return a device name if we find a match.
614 : */
615 : int
616 0 : mskc_probe(struct device *parent, void *match, void *aux)
617 : {
618 0 : return (pci_matchbyid((struct pci_attach_args *)aux, mskc_devices,
619 : nitems(mskc_devices)));
620 : }
621 :
622 : /*
623 : * Force the GEnesis into reset, then bring it out of reset.
624 : */
625 : void
626 0 : mskc_reset(struct sk_softc *sc)
627 : {
628 : u_int32_t imtimer_ticks, reg1;
629 : int reg;
630 :
631 : DPRINTFN(2, ("mskc_reset\n"));
632 :
633 0 : CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_RESET);
634 0 : CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_RESET);
635 :
636 0 : DELAY(1000);
637 0 : CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_UNRESET);
638 0 : DELAY(2);
639 0 : CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
640 :
641 0 : sk_win_write_1(sc, SK_TESTCTL1, 2);
642 :
643 0 : if (sc->sk_type == SK_YUKON_EC_U || sc->sk_type == SK_YUKON_EX ||
644 0 : sc->sk_type >= SK_YUKON_FE_P) {
645 : /* enable all clocks. */
646 0 : sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG3), 0);
647 0 : reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG4));
648 0 : reg1 &= (SK_Y2_REG4_FORCE_ASPM_REQUEST|
649 : SK_Y2_REG4_ASPM_GPHY_LINK_DOWN|
650 : SK_Y2_REG4_ASPM_INT_FIFO_EMPTY|
651 : SK_Y2_REG4_ASPM_CLKRUN_REQUEST);
652 0 : sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG4), reg1);
653 :
654 0 : reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG5));
655 0 : reg1 &= SK_Y2_REG5_TIM_VMAIN_AV_MASK;
656 0 : sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG5), reg1);
657 0 : sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_CFGREG1), 0);
658 :
659 : /*
660 : * Disable status race, workaround for Yukon EC Ultra &
661 : * Yukon EX.
662 : */
663 0 : reg1 = sk_win_read_4(sc, SK_GPIO);
664 0 : reg1 |= SK_Y2_GPIO_STAT_RACE_DIS;
665 0 : sk_win_write_4(sc, SK_GPIO, reg1);
666 0 : sk_win_read_4(sc, SK_GPIO);
667 0 : }
668 :
669 0 : reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1));
670 0 : if (sc->sk_type == SK_YUKON_XL && sc->sk_rev > SK_YUKON_XL_REV_A1)
671 0 : reg1 |= (SK_Y2_REG1_PHY1_COMA | SK_Y2_REG1_PHY2_COMA);
672 : else
673 0 : reg1 &= ~(SK_Y2_REG1_PHY1_COMA | SK_Y2_REG1_PHY2_COMA);
674 0 : sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1), reg1);
675 :
676 0 : if (sc->sk_type == SK_YUKON_XL && sc->sk_rev > SK_YUKON_XL_REV_A1)
677 0 : sk_win_write_1(sc, SK_Y2_CLKGATE,
678 : SK_Y2_CLKGATE_LINK1_GATE_DIS |
679 : SK_Y2_CLKGATE_LINK2_GATE_DIS |
680 : SK_Y2_CLKGATE_LINK1_CORE_DIS |
681 : SK_Y2_CLKGATE_LINK2_CORE_DIS |
682 : SK_Y2_CLKGATE_LINK1_PCI_DIS | SK_Y2_CLKGATE_LINK2_PCI_DIS);
683 : else
684 0 : sk_win_write_1(sc, SK_Y2_CLKGATE, 0);
685 :
686 0 : CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
687 0 : CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_SET);
688 0 : DELAY(1000);
689 0 : CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
690 0 : CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_CLEAR);
691 :
692 0 : if (sc->sk_type == SK_YUKON_EX || sc->sk_type == SK_YUKON_SUPR) {
693 0 : CSR_WRITE_2(sc, SK_GMAC_CTRL, SK_GMAC_BYP_MACSECRX |
694 : SK_GMAC_BYP_MACSECTX | SK_GMAC_BYP_RETR_FIFO);
695 0 : }
696 :
697 0 : sk_win_write_1(sc, SK_TESTCTL1, 1);
698 :
699 : DPRINTFN(2, ("mskc_reset: sk_csr=%x\n", CSR_READ_1(sc, SK_CSR)));
700 : DPRINTFN(2, ("mskc_reset: sk_link_ctrl=%x\n",
701 : CSR_READ_2(sc, SK_LINK_CTRL)));
702 :
703 : /* Disable ASF */
704 0 : CSR_WRITE_1(sc, SK_Y2_ASF_CSR, SK_Y2_ASF_RESET);
705 0 : CSR_WRITE_2(sc, SK_CSR, SK_CSR_ASF_OFF);
706 :
707 : /* Clear I2C IRQ noise */
708 0 : CSR_WRITE_4(sc, SK_I2CHWIRQ, 1);
709 :
710 : /* Disable hardware timer */
711 0 : CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_STOP);
712 0 : CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_IRQ_CLEAR);
713 :
714 : /* Disable descriptor polling */
715 0 : CSR_WRITE_4(sc, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP);
716 :
717 : /* Disable time stamps */
718 0 : CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_STOP);
719 0 : CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_IRQ_CLEAR);
720 :
721 : /* Enable RAM interface */
722 0 : sk_win_write_1(sc, SK_RAMCTL, SK_RAMCTL_UNRESET);
723 0 : for (reg = SK_TO0;reg <= SK_TO11; reg++)
724 0 : sk_win_write_1(sc, reg, 36);
725 0 : sk_win_write_1(sc, SK_RAMCTL + (SK_WIN_LEN / 2), SK_RAMCTL_UNRESET);
726 0 : for (reg = SK_TO0;reg <= SK_TO11; reg++)
727 0 : sk_win_write_1(sc, reg + (SK_WIN_LEN / 2), 36);
728 :
729 : /*
730 : * Configure interrupt moderation. The moderation timer
731 : * defers interrupts specified in the interrupt moderation
732 : * timer mask based on the timeout specified in the interrupt
733 : * moderation timer init register. Each bit in the timer
734 : * register represents one tick, so to specify a timeout in
735 : * microseconds, we have to multiply by the correct number of
736 : * ticks-per-microsecond.
737 : */
738 0 : switch (sc->sk_type) {
739 : case SK_YUKON_EC:
740 : case SK_YUKON_EC_U:
741 : case SK_YUKON_EX:
742 : case SK_YUKON_SUPR:
743 : case SK_YUKON_ULTRA2:
744 : case SK_YUKON_OPTIMA:
745 : case SK_YUKON_PRM:
746 : case SK_YUKON_OPTIMA2:
747 : imtimer_ticks = SK_IMTIMER_TICKS_YUKON_EC;
748 0 : break;
749 : case SK_YUKON_FE:
750 : imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE;
751 0 : break;
752 : case SK_YUKON_FE_P:
753 : imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE_P;
754 0 : break;
755 : case SK_YUKON_XL:
756 : imtimer_ticks = SK_IMTIMER_TICKS_YUKON_XL;
757 0 : break;
758 : default:
759 : imtimer_ticks = SK_IMTIMER_TICKS_YUKON;
760 0 : break;
761 : }
762 :
763 : /* Reset status ring. */
764 0 : bzero(sc->sk_status_ring,
765 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
766 0 : sc->sk_status_idx = 0;
767 :
768 0 : sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_RESET);
769 0 : sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_UNRESET);
770 :
771 0 : sk_win_write_2(sc, SK_STAT_BMU_LIDX, MSK_STATUS_RING_CNT - 1);
772 0 : sk_win_write_4(sc, SK_STAT_BMU_ADDRLO,
773 0 : sc->sk_status_map->dm_segs[0].ds_addr);
774 0 : sk_win_write_4(sc, SK_STAT_BMU_ADDRHI,
775 0 : (u_int64_t)sc->sk_status_map->dm_segs[0].ds_addr >> 32);
776 0 : sk_win_write_2(sc, SK_STAT_BMU_TX_THRESH, 10);
777 0 : sk_win_write_1(sc, SK_STAT_BMU_FIFOWM, 16);
778 0 : sk_win_write_1(sc, SK_STAT_BMU_FIFOIWM, 16);
779 :
780 : #if 0
781 : sk_win_write_4(sc, SK_Y2_LEV_ITIMERINIT, SK_IM_USECS(100));
782 : sk_win_write_4(sc, SK_Y2_TX_ITIMERINIT, SK_IM_USECS(1000));
783 : sk_win_write_4(sc, SK_Y2_ISR_ITIMERINIT, SK_IM_USECS(20));
784 : #else
785 0 : sk_win_write_4(sc, SK_Y2_ISR_ITIMERINIT, SK_IM_USECS(4));
786 : #endif
787 :
788 0 : sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_ON);
789 :
790 0 : sk_win_write_1(sc, SK_Y2_LEV_ITIMERCTL, SK_IMCTL_START);
791 0 : sk_win_write_1(sc, SK_Y2_TX_ITIMERCTL, SK_IMCTL_START);
792 0 : sk_win_write_1(sc, SK_Y2_ISR_ITIMERCTL, SK_IMCTL_START);
793 0 : }
794 :
795 : int
796 0 : msk_probe(struct device *parent, void *match, void *aux)
797 : {
798 0 : struct skc_attach_args *sa = aux;
799 :
800 0 : if (sa->skc_port != SK_PORT_A && sa->skc_port != SK_PORT_B)
801 0 : return (0);
802 :
803 0 : switch (sa->skc_type) {
804 : case SK_YUKON_XL:
805 : case SK_YUKON_EC_U:
806 : case SK_YUKON_EX:
807 : case SK_YUKON_EC:
808 : case SK_YUKON_FE:
809 : case SK_YUKON_FE_P:
810 : case SK_YUKON_SUPR:
811 : case SK_YUKON_ULTRA2:
812 : case SK_YUKON_OPTIMA:
813 : case SK_YUKON_PRM:
814 : case SK_YUKON_OPTIMA2:
815 0 : return (1);
816 : }
817 :
818 0 : return (0);
819 0 : }
820 :
821 : void
822 0 : msk_reset(struct sk_if_softc *sc_if)
823 : {
824 : /* GMAC and GPHY Reset */
825 0 : SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
826 0 : SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
827 0 : DELAY(1000);
828 0 : SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_CLEAR);
829 0 : SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
830 : SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
831 0 : }
832 :
833 : /*
834 : * Each XMAC chip is attached as a separate logical IP interface.
835 : * Single port cards will have only one logical interface of course.
836 : */
837 : void
838 0 : msk_attach(struct device *parent, struct device *self, void *aux)
839 : {
840 0 : struct sk_if_softc *sc_if = (struct sk_if_softc *)self;
841 0 : struct sk_softc *sc = (struct sk_softc *)parent;
842 0 : struct skc_attach_args *sa = aux;
843 : struct ifnet *ifp;
844 0 : caddr_t kva;
845 : int i;
846 : u_int32_t chunk;
847 : int mii_flags;
848 : int error;
849 :
850 0 : sc_if->sk_port = sa->skc_port;
851 0 : sc_if->sk_softc = sc;
852 0 : sc->sk_if[sa->skc_port] = sc_if;
853 :
854 : DPRINTFN(2, ("begin msk_attach: port=%d\n", sc_if->sk_port));
855 :
856 : /*
857 : * Get station address for this interface. Note that
858 : * dual port cards actually come with three station
859 : * addresses: one for each port, plus an extra. The
860 : * extra one is used by the SysKonnect driver software
861 : * as a 'virtual' station address for when both ports
862 : * are operating in failover mode. Currently we don't
863 : * use this extra address.
864 : */
865 0 : for (i = 0; i < ETHER_ADDR_LEN; i++)
866 0 : sc_if->arpcom.ac_enaddr[i] =
867 0 : sk_win_read_1(sc, SK_MAC0_0 + (sa->skc_port * 8) + i);
868 :
869 0 : printf(": address %s\n",
870 0 : ether_sprintf(sc_if->arpcom.ac_enaddr));
871 :
872 : /*
873 : * Set up RAM buffer addresses. The Yukon2 has a small amount
874 : * of SRAM on it, somewhere between 4K and 48K. We need to
875 : * divide this up between the transmitter and receiver. We
876 : * give the receiver 2/3 of the memory (rounded down), and the
877 : * transmitter whatever remains.
878 : */
879 0 : chunk = (2 * (sc->sk_ramsize / sizeof(u_int64_t)) / 3) & ~0xff;
880 0 : sc_if->sk_rx_ramstart = 0;
881 0 : sc_if->sk_rx_ramend = sc_if->sk_rx_ramstart + chunk - 1;
882 0 : chunk = (sc->sk_ramsize / sizeof(u_int64_t)) - chunk;
883 0 : sc_if->sk_tx_ramstart = sc_if->sk_rx_ramend + 1;
884 0 : sc_if->sk_tx_ramend = sc_if->sk_tx_ramstart + chunk - 1;
885 :
886 : DPRINTFN(2, ("msk_attach: rx_ramstart=%#x rx_ramend=%#x\n"
887 : " tx_ramstart=%#x tx_ramend=%#x\n",
888 : sc_if->sk_rx_ramstart, sc_if->sk_rx_ramend,
889 : sc_if->sk_tx_ramstart, sc_if->sk_tx_ramend));
890 :
891 : /* Allocate the descriptor queues. */
892 0 : if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct msk_ring_data),
893 : PAGE_SIZE, 0, &sc_if->sk_ring_seg, 1, &sc_if->sk_ring_nseg,
894 : BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
895 0 : printf(": can't alloc rx buffers\n");
896 0 : goto fail;
897 : }
898 0 : if (bus_dmamem_map(sc->sc_dmatag, &sc_if->sk_ring_seg,
899 : sc_if->sk_ring_nseg,
900 : sizeof(struct msk_ring_data), &kva, BUS_DMA_NOWAIT)) {
901 0 : printf(": can't map dma buffers (%lu bytes)\n",
902 : (ulong)sizeof(struct msk_ring_data));
903 0 : goto fail_1;
904 : }
905 0 : if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct msk_ring_data), 1,
906 : sizeof(struct msk_ring_data), 0,
907 : BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
908 : &sc_if->sk_ring_map)) {
909 0 : printf(": can't create dma map\n");
910 0 : goto fail_2;
911 : }
912 0 : if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_ring_map, kva,
913 : sizeof(struct msk_ring_data), NULL, BUS_DMA_NOWAIT)) {
914 0 : printf(": can't load dma map\n");
915 0 : goto fail_3;
916 : }
917 0 : sc_if->sk_rdata = (struct msk_ring_data *)kva;
918 :
919 0 : if (sc->sk_type != SK_YUKON_FE &&
920 0 : sc->sk_type != SK_YUKON_FE_P)
921 0 : sc_if->sk_pktlen = SK_JLEN;
922 : else
923 0 : sc_if->sk_pktlen = MCLBYTES;
924 :
925 0 : for (i = 0; i < MSK_RX_RING_CNT; i++) {
926 0 : if ((error = bus_dmamap_create(sc->sc_dmatag,
927 : sc_if->sk_pktlen, 1, sc_if->sk_pktlen, 0,
928 : BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
929 0 : &sc_if->sk_cdata.sk_rx_maps[i])) != 0) {
930 0 : printf("\n%s: unable to create rx DMA map %d, "
931 0 : "error = %d\n", sc->sk_dev.dv_xname, i, error);
932 : goto fail_4;
933 : }
934 : }
935 :
936 0 : ifp = &sc_if->arpcom.ac_if;
937 0 : ifp->if_softc = sc_if;
938 0 : ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
939 0 : ifp->if_ioctl = msk_ioctl;
940 0 : ifp->if_start = msk_start;
941 0 : ifp->if_watchdog = msk_watchdog;
942 0 : if (sc->sk_type != SK_YUKON_FE &&
943 0 : sc->sk_type != SK_YUKON_FE_P)
944 0 : ifp->if_hardmtu = SK_JUMBO_MTU;
945 0 : IFQ_SET_MAXLEN(&ifp->if_snd, MSK_TX_RING_CNT - 1);
946 0 : bcopy(sc_if->sk_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
947 :
948 0 : ifp->if_capabilities = IFCAP_VLAN_MTU;
949 :
950 0 : msk_reset(sc_if);
951 :
952 : /*
953 : * Do miibus setup.
954 : */
955 0 : msk_init_yukon(sc_if);
956 :
957 : DPRINTFN(2, ("msk_attach: 1\n"));
958 :
959 0 : sc_if->sk_mii.mii_ifp = ifp;
960 0 : sc_if->sk_mii.mii_readreg = msk_miibus_readreg;
961 0 : sc_if->sk_mii.mii_writereg = msk_miibus_writereg;
962 0 : sc_if->sk_mii.mii_statchg = msk_miibus_statchg;
963 :
964 0 : ifmedia_init(&sc_if->sk_mii.mii_media, 0,
965 : msk_ifmedia_upd, msk_ifmedia_sts);
966 : mii_flags = MIIF_DOPAUSE;
967 0 : if (sc->sk_fibertype)
968 0 : mii_flags |= MIIF_HAVEFIBER;
969 0 : mii_attach(self, &sc_if->sk_mii, 0xffffffff, 0,
970 : MII_OFFSET_ANY, mii_flags);
971 0 : if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
972 0 : printf("%s: no PHY found!\n", sc_if->sk_dev.dv_xname);
973 0 : ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL,
974 : 0, NULL);
975 0 : ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL);
976 0 : } else
977 0 : ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_AUTO);
978 :
979 0 : timeout_set(&sc_if->sk_tick_ch, msk_tick, sc_if);
980 0 : timeout_set(&sc_if->sk_tick_rx, msk_fill_rx_tick, sc_if);
981 :
982 : /*
983 : * Call MI attach routines.
984 : */
985 0 : if_attach(ifp);
986 0 : ether_ifattach(ifp);
987 :
988 : DPRINTFN(2, ("msk_attach: end\n"));
989 0 : return;
990 :
991 : fail_4:
992 0 : for (i = 0; i < MSK_RX_RING_CNT; i++) {
993 0 : if (sc_if->sk_cdata.sk_rx_maps[i] != NULL)
994 0 : bus_dmamap_destroy(sc->sc_dmatag,
995 : sc_if->sk_cdata.sk_rx_maps[i]);
996 : }
997 :
998 : fail_3:
999 0 : bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
1000 : fail_2:
1001 0 : bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct msk_ring_data));
1002 : fail_1:
1003 0 : bus_dmamem_free(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
1004 : fail:
1005 0 : sc->sk_if[sa->skc_port] = NULL;
1006 0 : }
1007 :
1008 : int
1009 0 : msk_detach(struct device *self, int flags)
1010 : {
1011 0 : struct sk_if_softc *sc_if = (struct sk_if_softc *)self;
1012 0 : struct sk_softc *sc = sc_if->sk_softc;
1013 0 : struct ifnet *ifp= &sc_if->arpcom.ac_if;
1014 :
1015 0 : if (sc->sk_if[sc_if->sk_port] == NULL)
1016 0 : return (0);
1017 :
1018 0 : msk_stop(sc_if, 1);
1019 :
1020 : /* Detach any PHYs we might have. */
1021 0 : if (LIST_FIRST(&sc_if->sk_mii.mii_phys) != NULL)
1022 0 : mii_detach(&sc_if->sk_mii, MII_PHY_ANY, MII_OFFSET_ANY);
1023 :
1024 : /* Delete any remaining media. */
1025 0 : ifmedia_delete_instance(&sc_if->sk_mii.mii_media, IFM_INST_ANY);
1026 :
1027 0 : ether_ifdetach(ifp);
1028 0 : if_detach(ifp);
1029 :
1030 0 : bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc_if->sk_rdata,
1031 : sizeof(struct msk_ring_data));
1032 0 : bus_dmamem_free(sc->sc_dmatag,
1033 : &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
1034 0 : bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
1035 0 : sc->sk_if[sc_if->sk_port] = NULL;
1036 :
1037 0 : return (0);
1038 0 : }
1039 :
1040 : int
1041 0 : msk_activate(struct device *self, int act)
1042 : {
1043 0 : struct sk_if_softc *sc_if = (void *)self;
1044 0 : struct ifnet *ifp = &sc_if->arpcom.ac_if;
1045 : int rv = 0;
1046 :
1047 0 : switch (act) {
1048 : case DVACT_RESUME:
1049 0 : msk_reset(sc_if);
1050 0 : if (ifp->if_flags & IFF_RUNNING)
1051 0 : msk_init(sc_if);
1052 : break;
1053 : default:
1054 0 : rv = config_activate_children(self, act);
1055 0 : break;
1056 : }
1057 0 : return (rv);
1058 : }
1059 :
1060 : int
1061 0 : mskcprint(void *aux, const char *pnp)
1062 : {
1063 0 : struct skc_attach_args *sa = aux;
1064 :
1065 0 : if (pnp)
1066 0 : printf("msk port %c at %s",
1067 : (sa->skc_port == SK_PORT_A) ? 'A' : 'B', pnp);
1068 : else
1069 0 : printf(" port %c", (sa->skc_port == SK_PORT_A) ? 'A' : 'B');
1070 0 : return (UNCONF);
1071 : }
1072 :
1073 : /*
1074 : * Attach the interface. Allocate softc structures, do ifmedia
1075 : * setup and ethernet/BPF attach.
1076 : */
1077 : void
1078 0 : mskc_attach(struct device *parent, struct device *self, void *aux)
1079 : {
1080 0 : struct sk_softc *sc = (struct sk_softc *)self;
1081 0 : struct pci_attach_args *pa = aux;
1082 0 : struct skc_attach_args skca;
1083 0 : pci_chipset_tag_t pc = pa->pa_pc;
1084 : pcireg_t memtype;
1085 0 : pci_intr_handle_t ih;
1086 : const char *intrstr = NULL;
1087 : u_int8_t hw, pmd;
1088 : char *revstr = NULL;
1089 0 : caddr_t kva;
1090 :
1091 : DPRINTFN(2, ("begin mskc_attach\n"));
1092 :
1093 0 : pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
1094 :
1095 : /*
1096 : * Map control/status registers.
1097 : */
1098 0 : memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM);
1099 0 : if (pci_mapreg_map(pa, SK_PCI_LOMEM, memtype, 0, &sc->sk_btag,
1100 0 : &sc->sk_bhandle, NULL, &sc->sk_bsize, 0)) {
1101 0 : printf(": can't map mem space\n");
1102 0 : return;
1103 : }
1104 :
1105 0 : sc->sc_dmatag = pa->pa_dmat;
1106 :
1107 0 : sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
1108 0 : sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);
1109 :
1110 : /* bail out here if chip is not recognized */
1111 0 : if (!(SK_IS_YUKON2(sc))) {
1112 0 : printf(": unknown chip type: %d\n", sc->sk_type);
1113 0 : goto fail_1;
1114 : }
1115 : DPRINTFN(2, ("mskc_attach: allocate interrupt\n"));
1116 :
1117 0 : if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_MARVELL) {
1118 0 : switch (PCI_PRODUCT(pa->pa_id)) {
1119 : case PCI_PRODUCT_MARVELL_YUKON_8036:
1120 : case PCI_PRODUCT_MARVELL_YUKON_8053:
1121 0 : pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED;
1122 0 : }
1123 : }
1124 :
1125 : /* Allocate interrupt */
1126 0 : if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
1127 0 : printf(": couldn't map interrupt\n");
1128 0 : goto fail_1;
1129 : }
1130 :
1131 0 : intrstr = pci_intr_string(pc, ih);
1132 0 : sc->sk_intrhand = pci_intr_establish(pc, ih, IPL_NET, msk_intr, sc,
1133 0 : self->dv_xname);
1134 0 : if (sc->sk_intrhand == NULL) {
1135 0 : printf(": couldn't establish interrupt");
1136 0 : if (intrstr != NULL)
1137 0 : printf(" at %s", intrstr);
1138 0 : printf("\n");
1139 0 : goto fail_1;
1140 : }
1141 0 : sc->sk_pc = pc;
1142 :
1143 0 : if (bus_dmamem_alloc(sc->sc_dmatag,
1144 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
1145 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
1146 : 0, &sc->sk_status_seg, 1, &sc->sk_status_nseg,
1147 : BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
1148 0 : printf(": can't alloc status buffers\n");
1149 0 : goto fail_2;
1150 : }
1151 :
1152 0 : if (bus_dmamem_map(sc->sc_dmatag,
1153 : &sc->sk_status_seg, sc->sk_status_nseg,
1154 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
1155 : &kva, BUS_DMA_NOWAIT)) {
1156 0 : printf(": can't map dma buffers (%lu bytes)\n",
1157 : (ulong)(MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc)));
1158 0 : goto fail_3;
1159 : }
1160 0 : if (bus_dmamap_create(sc->sc_dmatag,
1161 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 1,
1162 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 0,
1163 : BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
1164 : &sc->sk_status_map)) {
1165 0 : printf(": can't create dma map\n");
1166 : goto fail_4;
1167 : }
1168 0 : if (bus_dmamap_load(sc->sc_dmatag, sc->sk_status_map, kva,
1169 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
1170 : NULL, BUS_DMA_NOWAIT)) {
1171 0 : printf(": can't load dma map\n");
1172 0 : goto fail_5;
1173 : }
1174 0 : sc->sk_status_ring = (struct msk_status_desc *)kva;
1175 :
1176 : /* Reset the adapter. */
1177 0 : mskc_reset(sc);
1178 :
1179 0 : sc->sk_ramsize = sk_win_read_1(sc, SK_EPROM0) * 4096;
1180 : DPRINTFN(2, ("mskc_attach: ramsize=%dK\n", sc->sk_ramsize / 1024));
1181 :
1182 0 : pmd = sk_win_read_1(sc, SK_PMDTYPE);
1183 0 : if (pmd == 'L' || pmd == 'S' || pmd == 'P')
1184 0 : sc->sk_fibertype = 1;
1185 :
1186 0 : switch (sc->sk_type) {
1187 : case SK_YUKON_XL:
1188 0 : sc->sk_name = "Yukon-2 XL";
1189 0 : break;
1190 : case SK_YUKON_EC_U:
1191 0 : sc->sk_name = "Yukon-2 EC Ultra";
1192 0 : break;
1193 : case SK_YUKON_EX:
1194 0 : sc->sk_name = "Yukon-2 Extreme";
1195 0 : break;
1196 : case SK_YUKON_EC:
1197 0 : sc->sk_name = "Yukon-2 EC";
1198 0 : break;
1199 : case SK_YUKON_FE:
1200 0 : sc->sk_name = "Yukon-2 FE";
1201 0 : break;
1202 : case SK_YUKON_FE_P:
1203 0 : sc->sk_name = "Yukon-2 FE+";
1204 0 : break;
1205 : case SK_YUKON_SUPR:
1206 0 : sc->sk_name = "Yukon-2 Supreme";
1207 0 : break;
1208 : case SK_YUKON_ULTRA2:
1209 0 : sc->sk_name = "Yukon-2 Ultra 2";
1210 0 : break;
1211 : case SK_YUKON_OPTIMA:
1212 0 : sc->sk_name = "Yukon-2 Optima";
1213 0 : break;
1214 : case SK_YUKON_PRM:
1215 0 : sc->sk_name = "Yukon-2 Optima Prime";
1216 0 : break;
1217 : case SK_YUKON_OPTIMA2:
1218 0 : sc->sk_name = "Yukon-2 Optima 2";
1219 0 : break;
1220 : default:
1221 0 : sc->sk_name = "Yukon (Unknown)";
1222 0 : }
1223 :
1224 0 : if (sc->sk_type == SK_YUKON_XL) {
1225 0 : switch (sc->sk_rev) {
1226 : case SK_YUKON_XL_REV_A0:
1227 : revstr = "A0";
1228 0 : break;
1229 : case SK_YUKON_XL_REV_A1:
1230 : revstr = "A1";
1231 0 : break;
1232 : case SK_YUKON_XL_REV_A2:
1233 : revstr = "A2";
1234 0 : break;
1235 : case SK_YUKON_XL_REV_A3:
1236 : revstr = "A3";
1237 0 : break;
1238 : default:
1239 : ;
1240 : }
1241 : }
1242 :
1243 0 : if (sc->sk_type == SK_YUKON_EC) {
1244 0 : switch (sc->sk_rev) {
1245 : case SK_YUKON_EC_REV_A1:
1246 : revstr = "A1";
1247 0 : break;
1248 : case SK_YUKON_EC_REV_A2:
1249 : revstr = "A2";
1250 0 : break;
1251 : case SK_YUKON_EC_REV_A3:
1252 : revstr = "A3";
1253 0 : break;
1254 : default:
1255 : ;
1256 : }
1257 : }
1258 :
1259 0 : if (sc->sk_type == SK_YUKON_EC_U) {
1260 0 : switch (sc->sk_rev) {
1261 : case SK_YUKON_EC_U_REV_A0:
1262 : revstr = "A0";
1263 0 : break;
1264 : case SK_YUKON_EC_U_REV_A1:
1265 : revstr = "A1";
1266 0 : break;
1267 : case SK_YUKON_EC_U_REV_B0:
1268 : revstr = "B0";
1269 0 : break;
1270 : case SK_YUKON_EC_U_REV_B1:
1271 : revstr = "B1";
1272 0 : break;
1273 : default:
1274 : ;
1275 : }
1276 : }
1277 :
1278 0 : if (sc->sk_type == SK_YUKON_FE) {
1279 0 : switch (sc->sk_rev) {
1280 : case SK_YUKON_FE_REV_A1:
1281 : revstr = "A1";
1282 0 : break;
1283 : case SK_YUKON_FE_REV_A2:
1284 : revstr = "A2";
1285 0 : break;
1286 : default:
1287 : ;
1288 : }
1289 : }
1290 :
1291 0 : if (sc->sk_type == SK_YUKON_FE_P && sc->sk_rev == SK_YUKON_FE_P_REV_A0)
1292 0 : revstr = "A0";
1293 :
1294 0 : if (sc->sk_type == SK_YUKON_EX) {
1295 0 : switch (sc->sk_rev) {
1296 : case SK_YUKON_EX_REV_A0:
1297 : revstr = "A0";
1298 0 : break;
1299 : case SK_YUKON_EX_REV_B0:
1300 : revstr = "B0";
1301 0 : break;
1302 : default:
1303 : ;
1304 : }
1305 : }
1306 :
1307 0 : if (sc->sk_type == SK_YUKON_SUPR) {
1308 0 : switch (sc->sk_rev) {
1309 : case SK_YUKON_SUPR_REV_A0:
1310 : revstr = "A0";
1311 0 : break;
1312 : case SK_YUKON_SUPR_REV_B0:
1313 : revstr = "B0";
1314 0 : break;
1315 : case SK_YUKON_SUPR_REV_B1:
1316 : revstr = "B1";
1317 0 : break;
1318 : default:
1319 : ;
1320 : }
1321 : }
1322 :
1323 0 : if (sc->sk_type == SK_YUKON_PRM) {
1324 0 : switch (sc->sk_rev) {
1325 : case SK_YUKON_PRM_REV_Z1:
1326 : revstr = "Z1";
1327 0 : break;
1328 : case SK_YUKON_PRM_REV_A0:
1329 : revstr = "A0";
1330 0 : break;
1331 : default:
1332 : ;
1333 : }
1334 : }
1335 :
1336 : /* Announce the product name. */
1337 0 : printf(", %s", sc->sk_name);
1338 0 : if (revstr != NULL)
1339 0 : printf(" rev. %s", revstr);
1340 0 : printf(" (0x%x): %s\n", sc->sk_rev, intrstr);
1341 :
1342 0 : sc->sk_macs = 1;
1343 :
1344 0 : hw = sk_win_read_1(sc, SK_Y2_HWRES);
1345 0 : if ((hw & SK_Y2_HWRES_LINK_MASK) == SK_Y2_HWRES_LINK_DUAL) {
1346 0 : if ((sk_win_read_1(sc, SK_Y2_CLKGATE) &
1347 0 : SK_Y2_CLKGATE_LINK2_INACTIVE) == 0)
1348 0 : sc->sk_macs++;
1349 : }
1350 :
1351 0 : skca.skc_port = SK_PORT_A;
1352 0 : skca.skc_type = sc->sk_type;
1353 0 : skca.skc_rev = sc->sk_rev;
1354 0 : (void)config_found(&sc->sk_dev, &skca, mskcprint);
1355 :
1356 0 : if (sc->sk_macs > 1) {
1357 0 : skca.skc_port = SK_PORT_B;
1358 0 : skca.skc_type = sc->sk_type;
1359 0 : skca.skc_rev = sc->sk_rev;
1360 0 : (void)config_found(&sc->sk_dev, &skca, mskcprint);
1361 0 : }
1362 :
1363 : /* Turn on the 'driver is loaded' LED. */
1364 0 : CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
1365 :
1366 0 : return;
1367 :
1368 : fail_4:
1369 0 : bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sk_status_ring,
1370 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
1371 : fail_3:
1372 0 : bus_dmamem_free(sc->sc_dmatag,
1373 : &sc->sk_status_seg, sc->sk_status_nseg);
1374 0 : sc->sk_status_nseg = 0;
1375 : fail_5:
1376 0 : bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
1377 : fail_2:
1378 0 : pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
1379 0 : sc->sk_intrhand = NULL;
1380 : fail_1:
1381 0 : bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
1382 0 : sc->sk_bsize = 0;
1383 0 : }
1384 :
1385 : int
1386 0 : mskc_detach(struct device *self, int flags)
1387 : {
1388 0 : struct sk_softc *sc = (struct sk_softc *)self;
1389 : int rv;
1390 :
1391 0 : if (sc->sk_intrhand)
1392 0 : pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
1393 :
1394 0 : rv = config_detach_children(self, flags);
1395 0 : if (rv != 0)
1396 0 : return (rv);
1397 :
1398 0 : if (sc->sk_status_nseg > 0) {
1399 0 : bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
1400 0 : bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sk_status_ring,
1401 : MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
1402 0 : bus_dmamem_free(sc->sc_dmatag,
1403 : &sc->sk_status_seg, sc->sk_status_nseg);
1404 0 : }
1405 :
1406 0 : if (sc->sk_bsize > 0)
1407 0 : bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
1408 :
1409 0 : return(0);
1410 0 : }
1411 :
1412 : int
1413 0 : mskc_activate(struct device *self, int act)
1414 : {
1415 0 : struct sk_softc *sc = (void *)self;
1416 : int rv = 0;
1417 :
1418 0 : switch (act) {
1419 : case DVACT_RESUME:
1420 0 : mskc_reset(sc);
1421 0 : rv = config_activate_children(self, act);
1422 0 : break;
1423 : default:
1424 0 : rv = config_activate_children(self, act);
1425 0 : break;
1426 : }
1427 0 : return (rv);
1428 : }
1429 :
1430 : static unsigned int
1431 0 : msk_encap(struct sk_if_softc *sc_if, struct mbuf *m, uint32_t prod)
1432 : {
1433 0 : struct sk_softc *sc = sc_if->sk_softc;
1434 0 : struct msk_ring_data *rd = sc_if->sk_rdata;
1435 : struct msk_tx_desc *t;
1436 : bus_dmamap_t map;
1437 : uint64_t addr;
1438 : uint32_t hiaddr;
1439 : uint32_t next, last;
1440 : uint8_t opcode;
1441 : unsigned int entries = 0;
1442 : int i;
1443 :
1444 0 : map = sc_if->sk_cdata.sk_tx_maps[prod];
1445 :
1446 0 : switch (bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,
1447 : BUS_DMA_STREAMING | BUS_DMA_NOWAIT)) {
1448 : case 0:
1449 : break;
1450 : case EFBIG: /* mbuf chain is too fragmented */
1451 0 : if (m_defrag(m, M_DONTWAIT) == 0 &&
1452 0 : bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,
1453 0 : BUS_DMA_STREAMING | BUS_DMA_NOWAIT) == 0)
1454 : break;
1455 : /* FALLTHROUGH */
1456 : default:
1457 0 : return (0);
1458 : }
1459 :
1460 0 : bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,
1461 : BUS_DMASYNC_PREWRITE);
1462 :
1463 : opcode = SK_Y2_TXOPC_OWN | SK_Y2_TXOPC_PACKET;
1464 : next = prod;
1465 0 : for (i = 0; i < map->dm_nsegs; i++) {
1466 : /* high 32 bits of address */
1467 0 : addr = map->dm_segs[i].ds_addr;
1468 0 : hiaddr = addr >> 32;
1469 0 : if (sc_if->sk_cdata.sk_tx_hiaddr != hiaddr) {
1470 0 : t = &rd->sk_tx_ring[next];
1471 0 : htolem32(&t->sk_addr, hiaddr);
1472 0 : t->sk_opcode = SK_Y2_TXOPC_OWN | SK_Y2_TXOPC_ADDR64;
1473 :
1474 0 : sc_if->sk_cdata.sk_tx_hiaddr = hiaddr;
1475 :
1476 0 : SK_INC(next, MSK_TX_RING_CNT);
1477 0 : entries++;
1478 0 : }
1479 :
1480 : /* low 32 bits of address + length */
1481 0 : t = &rd->sk_tx_ring[next];
1482 0 : htolem32(&t->sk_addr, addr);
1483 0 : htolem16(&t->sk_len, map->dm_segs[i].ds_len);
1484 0 : t->sk_ctl = 0;
1485 0 : t->sk_opcode = opcode;
1486 :
1487 : last = next;
1488 0 : SK_INC(next, MSK_TX_RING_CNT);
1489 0 : entries++;
1490 :
1491 : opcode = SK_Y2_TXOPC_OWN | SK_Y2_TXOPC_BUFFER;
1492 : }
1493 0 : t->sk_ctl = SK_Y2_TXCTL_LASTFRAG;
1494 :
1495 0 : sc_if->sk_cdata.sk_tx_maps[prod] = sc_if->sk_cdata.sk_tx_maps[last];
1496 0 : sc_if->sk_cdata.sk_tx_maps[last] = map;
1497 0 : sc_if->sk_cdata.sk_tx_mbuf[last] = m;
1498 :
1499 0 : return (entries);
1500 0 : }
1501 :
1502 : void
1503 0 : msk_start(struct ifnet *ifp)
1504 : {
1505 0 : struct sk_if_softc *sc_if = ifp->if_softc;
1506 : struct mbuf *m = NULL;
1507 : uint32_t prod, free, used;
1508 : int post = 0;
1509 :
1510 0 : prod = sc_if->sk_cdata.sk_tx_prod;
1511 0 : free = sc_if->sk_cdata.sk_tx_cons;
1512 0 : if (free <= prod)
1513 0 : free += MSK_TX_RING_CNT;
1514 0 : free -= prod;
1515 :
1516 0 : MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT, BUS_DMASYNC_POSTWRITE);
1517 :
1518 0 : for (;;) {
1519 0 : if (free <= SK_NTXSEG * 2) {
1520 0 : ifq_set_oactive(&ifp->if_snd);
1521 0 : break;
1522 : }
1523 :
1524 0 : m = ifq_dequeue(&ifp->if_snd);
1525 0 : if (m == NULL)
1526 : break;
1527 :
1528 0 : used = msk_encap(sc_if, m, prod);
1529 0 : if (used == 0) {
1530 0 : m_freem(m);
1531 0 : continue;
1532 : }
1533 :
1534 0 : free -= used;
1535 0 : prod += used;
1536 0 : prod &= MSK_TX_RING_CNT - 1;
1537 :
1538 : #if NBPFILTER > 0
1539 0 : if (ifp->if_bpf)
1540 0 : bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1541 : #endif
1542 : post = 1;
1543 : }
1544 :
1545 0 : MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT, BUS_DMASYNC_PREWRITE);
1546 :
1547 0 : if (post == 0)
1548 0 : return;
1549 :
1550 : /* Transmit */
1551 0 : sc_if->sk_cdata.sk_tx_prod = prod;
1552 0 : SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_PUTIDX, prod);
1553 :
1554 : /* Set a timeout in case the chip goes out to lunch. */
1555 0 : ifp->if_timer = MSK_TX_TIMEOUT;
1556 0 : }
1557 :
1558 : void
1559 0 : msk_watchdog(struct ifnet *ifp)
1560 : {
1561 0 : struct sk_if_softc *sc_if = ifp->if_softc;
1562 :
1563 : /*
1564 : * Reclaim first as there is a possibility of losing Tx completion
1565 : * interrupts.
1566 : */
1567 0 : msk_txeof(sc_if);
1568 0 : if (sc_if->sk_cdata.sk_tx_prod != sc_if->sk_cdata.sk_tx_cons) {
1569 0 : printf("%s: watchdog timeout\n", sc_if->sk_dev.dv_xname);
1570 :
1571 0 : ifp->if_oerrors++;
1572 :
1573 : /* XXX Resets both ports; we shouldn't do that. */
1574 0 : mskc_reset(sc_if->sk_softc);
1575 0 : msk_reset(sc_if);
1576 0 : msk_init(sc_if);
1577 0 : }
1578 0 : }
1579 :
1580 : static inline int
1581 0 : msk_rxvalid(struct sk_softc *sc, u_int32_t stat, u_int32_t len)
1582 : {
1583 0 : if ((stat & (YU_RXSTAT_CRCERR | YU_RXSTAT_LONGERR |
1584 : YU_RXSTAT_MIIERR | YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC |
1585 0 : YU_RXSTAT_JABBER)) != 0 ||
1586 0 : (stat & YU_RXSTAT_RXOK) != YU_RXSTAT_RXOK ||
1587 0 : YU_RXSTAT_BYTES(stat) != len)
1588 0 : return (0);
1589 :
1590 0 : return (1);
1591 0 : }
1592 :
1593 : void
1594 0 : msk_rxeof(struct sk_if_softc *sc_if, uint16_t len, uint32_t rxstat)
1595 : {
1596 0 : struct sk_softc *sc = sc_if->sk_softc;
1597 0 : struct ifnet *ifp = &sc_if->arpcom.ac_if;
1598 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
1599 : struct mbuf *m = NULL;
1600 : int prod, cons, tail;
1601 : bus_dmamap_t map;
1602 :
1603 0 : prod = sc_if->sk_cdata.sk_rx_prod;
1604 0 : cons = sc_if->sk_cdata.sk_rx_cons;
1605 :
1606 : //printf("%s: prod %u cons %u\n", __func__, prod, cons);
1607 :
1608 0 : while (cons != prod) {
1609 : tail = cons;
1610 0 : SK_INC(cons, MSK_RX_RING_CNT);
1611 :
1612 0 : m = sc_if->sk_cdata.sk_rx_mbuf[tail];
1613 0 : if (m != NULL) {
1614 : /* found it */
1615 : break;
1616 : }
1617 : }
1618 0 : sc_if->sk_cdata.sk_rx_cons = cons;
1619 :
1620 0 : if (m == NULL) {
1621 : /* maybe if ADDR64 is consumed? */
1622 0 : return;
1623 : }
1624 :
1625 0 : sc_if->sk_cdata.sk_rx_mbuf[tail] = NULL;
1626 :
1627 0 : map = sc_if->sk_cdata.sk_rx_maps[tail];
1628 0 : if_rxr_put(&sc_if->sk_cdata.sk_rx_ring, 1);
1629 :
1630 0 : bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, map, 0, map->dm_mapsize,
1631 : BUS_DMASYNC_POSTREAD);
1632 0 : bus_dmamap_unload(sc_if->sk_softc->sc_dmatag, map);
1633 :
1634 0 : if (len < SK_MIN_FRAMELEN || len > SK_JUMBO_FRAMELEN ||
1635 0 : msk_rxvalid(sc, rxstat, len) == 0) {
1636 0 : ifp->if_ierrors++;
1637 0 : m_freem(m);
1638 0 : return;
1639 : }
1640 :
1641 0 : m->m_pkthdr.len = m->m_len = len;
1642 :
1643 0 : ml_enqueue(&ml, m);
1644 0 : if_input(ifp, &ml);
1645 0 : }
1646 :
1647 : void
1648 0 : msk_txeof(struct sk_if_softc *sc_if)
1649 : {
1650 0 : struct ifnet *ifp = &sc_if->arpcom.ac_if;
1651 0 : struct sk_softc *sc = sc_if->sk_softc;
1652 : uint32_t prod, cons;
1653 : struct mbuf *m;
1654 : bus_dmamap_t map;
1655 : bus_size_t reg;
1656 :
1657 0 : if (sc_if->sk_port == SK_PORT_A)
1658 0 : reg = SK_STAT_BMU_TXA1_RIDX;
1659 : else
1660 : reg = SK_STAT_BMU_TXA2_RIDX;
1661 :
1662 : /*
1663 : * Go through our tx ring and free mbufs for those
1664 : * frames that have been sent.
1665 : */
1666 0 : cons = sc_if->sk_cdata.sk_tx_cons;
1667 0 : prod = sk_win_read_2(sc, reg);
1668 :
1669 0 : if (cons == prod)
1670 0 : return;
1671 :
1672 0 : while (cons != prod) {
1673 0 : m = sc_if->sk_cdata.sk_tx_mbuf[cons];
1674 0 : if (m != NULL) {
1675 0 : sc_if->sk_cdata.sk_tx_mbuf[cons] = NULL;
1676 :
1677 0 : map = sc_if->sk_cdata.sk_tx_maps[cons];
1678 0 : bus_dmamap_sync(sc->sc_dmatag, map, 0,
1679 : map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1680 0 : bus_dmamap_unload(sc->sc_dmatag, map);
1681 :
1682 0 : m_freem(m);
1683 0 : }
1684 :
1685 0 : SK_INC(cons, MSK_TX_RING_CNT);
1686 : }
1687 0 : if (cons == sc_if->sk_cdata.sk_tx_prod)
1688 0 : ifp->if_timer = 0;
1689 :
1690 0 : sc_if->sk_cdata.sk_tx_cons = cons;
1691 :
1692 0 : if (ifq_is_oactive(&ifp->if_snd))
1693 0 : ifq_restart(&ifp->if_snd);
1694 0 : }
1695 :
1696 : void
1697 0 : msk_fill_rx_ring(struct sk_if_softc *sc_if)
1698 : {
1699 : u_int slots, used;
1700 :
1701 0 : slots = if_rxr_get(&sc_if->sk_cdata.sk_rx_ring, MSK_RX_RING_CNT/2);
1702 :
1703 0 : MSK_CDRXSYNC(sc_if, 0, BUS_DMASYNC_POSTWRITE); /* XXX */
1704 0 : while (slots > 0) {
1705 0 : used = msk_newbuf(sc_if);
1706 0 : if (used == 0)
1707 : break;
1708 :
1709 0 : slots -= used;
1710 : }
1711 0 : MSK_CDRXSYNC(sc_if, 0, BUS_DMASYNC_PREWRITE); /* XXX */
1712 :
1713 0 : if_rxr_put(&sc_if->sk_cdata.sk_rx_ring, slots);
1714 0 : if (if_rxr_inuse(&sc_if->sk_cdata.sk_rx_ring) == 0)
1715 0 : timeout_add(&sc_if->sk_tick_rx, 1);
1716 0 : }
1717 :
1718 : void
1719 0 : msk_fill_rx_tick(void *xsc_if)
1720 : {
1721 0 : struct sk_if_softc *sc_if = xsc_if;
1722 : int s;
1723 :
1724 0 : s = splnet();
1725 0 : if (if_rxr_inuse(&sc_if->sk_cdata.sk_rx_ring) == 0) {
1726 0 : msk_fill_rx_ring(sc_if);
1727 0 : SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,
1728 : sc_if->sk_cdata.sk_rx_prod);
1729 0 : }
1730 0 : splx(s);
1731 0 : }
1732 :
1733 : void
1734 0 : msk_tick(void *xsc_if)
1735 : {
1736 0 : struct sk_if_softc *sc_if = xsc_if;
1737 0 : struct mii_data *mii = &sc_if->sk_mii;
1738 : int s;
1739 :
1740 0 : s = splnet();
1741 0 : mii_tick(mii);
1742 0 : splx(s);
1743 0 : timeout_add_sec(&sc_if->sk_tick_ch, 1);
1744 0 : }
1745 :
1746 : void
1747 0 : msk_intr_yukon(struct sk_if_softc *sc_if)
1748 : {
1749 : u_int8_t status;
1750 :
1751 0 : status = SK_IF_READ_1(sc_if, 0, SK_GMAC_ISR);
1752 : /* RX overrun */
1753 0 : if ((status & SK_GMAC_INT_RX_OVER) != 0) {
1754 0 : SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST,
1755 : SK_RFCTL_RX_FIFO_OVER);
1756 0 : }
1757 : /* TX underrun */
1758 0 : if ((status & SK_GMAC_INT_TX_UNDER) != 0) {
1759 0 : SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST,
1760 : SK_TFCTL_TX_FIFO_UNDER);
1761 0 : }
1762 :
1763 : DPRINTFN(2, ("msk_intr_yukon status=%#x\n", status));
1764 0 : }
1765 :
1766 : int
1767 0 : msk_intr(void *xsc)
1768 : {
1769 0 : struct sk_softc *sc = xsc;
1770 : struct sk_if_softc *sc_if;
1771 0 : struct sk_if_softc *sc_if0 = sc->sk_if[SK_PORT_A];
1772 0 : struct sk_if_softc *sc_if1 = sc->sk_if[SK_PORT_B];
1773 : struct ifnet *ifp0 = NULL, *ifp1 = NULL;
1774 0 : int claimed = 0, rx[2] = {0, 0};
1775 : u_int32_t status;
1776 : struct msk_status_desc *cur_st;
1777 :
1778 0 : status = CSR_READ_4(sc, SK_Y2_ISSR2);
1779 0 : if (status == 0xffffffff)
1780 0 : return (0);
1781 0 : if (status == 0) {
1782 0 : CSR_WRITE_4(sc, SK_Y2_ICR, 2);
1783 0 : return (0);
1784 : }
1785 :
1786 0 : status = CSR_READ_4(sc, SK_ISR);
1787 :
1788 0 : if (sc_if0 != NULL)
1789 0 : ifp0 = &sc_if0->arpcom.ac_if;
1790 0 : if (sc_if1 != NULL)
1791 0 : ifp1 = &sc_if1->arpcom.ac_if;
1792 :
1793 0 : if (sc_if0 && (status & SK_Y2_IMR_MAC1) &&
1794 0 : (ifp0->if_flags & IFF_RUNNING)) {
1795 0 : msk_intr_yukon(sc_if0);
1796 0 : }
1797 :
1798 0 : if (sc_if1 && (status & SK_Y2_IMR_MAC2) &&
1799 0 : (ifp1->if_flags & IFF_RUNNING)) {
1800 0 : msk_intr_yukon(sc_if1);
1801 0 : }
1802 :
1803 0 : MSK_CDSTSYNC(sc, sc->sk_status_idx,
1804 : BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1805 0 : cur_st = &sc->sk_status_ring[sc->sk_status_idx];
1806 :
1807 0 : while (cur_st->sk_opcode & SK_Y2_STOPC_OWN) {
1808 0 : cur_st->sk_opcode &= ~SK_Y2_STOPC_OWN;
1809 0 : switch (cur_st->sk_opcode) {
1810 : case SK_Y2_STOPC_RXSTAT:
1811 0 : sc_if = sc->sk_if[cur_st->sk_link & 0x01];
1812 0 : rx[cur_st->sk_link & 0x01] = 1;
1813 0 : msk_rxeof(sc_if, lemtoh16(&cur_st->sk_len),
1814 0 : lemtoh32(&cur_st->sk_status));
1815 0 : break;
1816 : case SK_Y2_STOPC_TXSTAT:
1817 0 : if (sc_if0)
1818 0 : msk_txeof(sc_if0);
1819 0 : if (sc_if1)
1820 0 : msk_txeof(sc_if1);
1821 : break;
1822 : default:
1823 0 : printf("opcode=0x%x\n", cur_st->sk_opcode);
1824 0 : break;
1825 : }
1826 0 : SK_INC(sc->sk_status_idx, MSK_STATUS_RING_CNT);
1827 :
1828 0 : MSK_CDSTSYNC(sc, sc->sk_status_idx,
1829 : BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1830 0 : cur_st = &sc->sk_status_ring[sc->sk_status_idx];
1831 : }
1832 :
1833 0 : if (status & SK_Y2_IMR_BMU) {
1834 0 : CSR_WRITE_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_IRQ_CLEAR);
1835 : claimed = 1;
1836 0 : }
1837 :
1838 0 : CSR_WRITE_4(sc, SK_Y2_ICR, 2);
1839 :
1840 0 : if (rx[0]) {
1841 0 : msk_fill_rx_ring(sc_if0);
1842 0 : SK_IF_WRITE_2(sc_if0, 0, SK_RXQ1_Y2_PREF_PUTIDX,
1843 : sc_if0->sk_cdata.sk_rx_prod);
1844 0 : }
1845 0 : if (rx[1]) {
1846 0 : msk_fill_rx_ring(sc_if1);
1847 0 : SK_IF_WRITE_2(sc_if1, 0, SK_RXQ1_Y2_PREF_PUTIDX,
1848 : sc_if1->sk_cdata.sk_rx_prod);
1849 0 : }
1850 :
1851 0 : return (claimed);
1852 0 : }
1853 :
1854 : void
1855 0 : msk_init_yukon(struct sk_if_softc *sc_if)
1856 : {
1857 : u_int32_t v;
1858 : u_int16_t reg;
1859 : struct sk_softc *sc;
1860 : int i;
1861 :
1862 0 : sc = sc_if->sk_softc;
1863 :
1864 : DPRINTFN(2, ("msk_init_yukon: start: sk_csr=%#x\n",
1865 : CSR_READ_4(sc_if->sk_softc, SK_CSR)));
1866 :
1867 : DPRINTFN(6, ("msk_init_yukon: 1\n"));
1868 :
1869 : DPRINTFN(3, ("msk_init_yukon: gmac_ctrl=%#x\n",
1870 : SK_IF_READ_4(sc_if, 0, SK_GMAC_CTRL)));
1871 :
1872 : DPRINTFN(6, ("msk_init_yukon: 3\n"));
1873 :
1874 : /* unused read of the interrupt source register */
1875 : DPRINTFN(6, ("msk_init_yukon: 4\n"));
1876 0 : SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR);
1877 :
1878 : DPRINTFN(6, ("msk_init_yukon: 4a\n"));
1879 0 : reg = SK_YU_READ_2(sc_if, YUKON_PAR);
1880 : DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg));
1881 :
1882 : /* MIB Counter Clear Mode set */
1883 0 : reg |= YU_PAR_MIB_CLR;
1884 : DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg));
1885 : DPRINTFN(6, ("msk_init_yukon: 4b\n"));
1886 0 : SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
1887 :
1888 : /* MIB Counter Clear Mode clear */
1889 : DPRINTFN(6, ("msk_init_yukon: 5\n"));
1890 0 : reg &= ~YU_PAR_MIB_CLR;
1891 0 : SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
1892 :
1893 : /* receive control reg */
1894 : DPRINTFN(6, ("msk_init_yukon: 7\n"));
1895 0 : SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
1896 :
1897 : /* transmit parameter register */
1898 : DPRINTFN(6, ("msk_init_yukon: 8\n"));
1899 0 : SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
1900 : YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) );
1901 :
1902 : /* serial mode register */
1903 : DPRINTFN(6, ("msk_init_yukon: 9\n"));
1904 : reg = YU_SMR_DATA_BLIND(0x1c) |
1905 : YU_SMR_MFL_VLAN |
1906 : YU_SMR_IPG_DATA(0x1e);
1907 :
1908 0 : if (sc->sk_type != SK_YUKON_FE &&
1909 0 : sc->sk_type != SK_YUKON_FE_P)
1910 0 : reg |= YU_SMR_MFL_JUMBO;
1911 :
1912 0 : SK_YU_WRITE_2(sc_if, YUKON_SMR, reg);
1913 :
1914 : DPRINTFN(6, ("msk_init_yukon: 10\n"));
1915 : /* Setup Yukon's address */
1916 0 : for (i = 0; i < 3; i++) {
1917 : /* Write Source Address 1 (unicast filter) */
1918 0 : SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4,
1919 : sc_if->arpcom.ac_enaddr[i * 2] |
1920 : sc_if->arpcom.ac_enaddr[i * 2 + 1] << 8);
1921 : }
1922 :
1923 0 : for (i = 0; i < 3; i++) {
1924 0 : reg = sk_win_read_2(sc_if->sk_softc,
1925 0 : SK_MAC1_0 + i * 2 + sc_if->sk_port * 8);
1926 0 : SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
1927 : }
1928 :
1929 : /* Program promiscuous mode and multicast filters */
1930 : DPRINTFN(6, ("msk_init_yukon: 11\n"));
1931 0 : msk_iff(sc_if);
1932 :
1933 : /* enable interrupt mask for counter overflows */
1934 : DPRINTFN(6, ("msk_init_yukon: 12\n"));
1935 0 : SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
1936 0 : SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0);
1937 0 : SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0);
1938 :
1939 : /* Configure RX MAC FIFO Flush Mask */
1940 : v = YU_RXSTAT_FOFL | YU_RXSTAT_CRCERR | YU_RXSTAT_MIIERR |
1941 : YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC | YU_RXSTAT_RUNT |
1942 : YU_RXSTAT_JABBER;
1943 0 : SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_MASK, v);
1944 :
1945 : /* Configure RX MAC FIFO */
1946 0 : SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR);
1947 0 : SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_OPERATION_ON |
1948 : SK_RFCTL_FIFO_FLUSH_ON);
1949 :
1950 : /* Increase flush threshould to 64 bytes */
1951 0 : SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_THRESHOLD,
1952 : SK_RFCTL_FIFO_THRESHOLD + 1);
1953 :
1954 : /* Configure TX MAC FIFO */
1955 0 : SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR);
1956 0 : SK_IF_WRITE_2(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON);
1957 :
1958 : #if 1
1959 0 : SK_YU_WRITE_2(sc_if, YUKON_GPCR, YU_GPCR_TXEN | YU_GPCR_RXEN);
1960 : #endif
1961 : DPRINTFN(6, ("msk_init_yukon: end\n"));
1962 0 : }
1963 :
1964 : /*
1965 : * Note that to properly initialize any part of the GEnesis chip,
1966 : * you first have to take it out of reset mode.
1967 : */
1968 : void
1969 0 : msk_init(void *xsc_if)
1970 : {
1971 0 : struct sk_if_softc *sc_if = xsc_if;
1972 0 : struct sk_softc *sc = sc_if->sk_softc;
1973 0 : struct ifnet *ifp = &sc_if->arpcom.ac_if;
1974 0 : struct mii_data *mii = &sc_if->sk_mii;
1975 : int s;
1976 :
1977 : DPRINTFN(2, ("msk_init\n"));
1978 :
1979 0 : s = splnet();
1980 :
1981 : /* Cancel pending I/O and free all RX/TX buffers. */
1982 0 : msk_stop(sc_if, 0);
1983 :
1984 : /* Configure I2C registers */
1985 :
1986 : /* Configure XMAC(s) */
1987 0 : msk_init_yukon(sc_if);
1988 0 : mii_mediachg(mii);
1989 :
1990 : /* Configure transmit arbiter(s) */
1991 0 : SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_ON);
1992 : #if 0
1993 : SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON);
1994 : #endif
1995 :
1996 : /* Configure RAMbuffers */
1997 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET);
1998 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart);
1999 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart);
2000 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart);
2001 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend);
2002 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON);
2003 :
2004 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_UNRESET);
2005 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_STORENFWD_ON);
2006 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_START, sc_if->sk_tx_ramstart);
2007 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_WR_PTR, sc_if->sk_tx_ramstart);
2008 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_RD_PTR, sc_if->sk_tx_ramstart);
2009 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_END, sc_if->sk_tx_ramend);
2010 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_ON);
2011 :
2012 : /* Configure BMUs */
2013 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000016);
2014 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000d28);
2015 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000080);
2016 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_WATERMARK, 0x00000600);
2017 :
2018 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000016);
2019 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000d28);
2020 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000080);
2021 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_WATERMARK, 0x00000600);
2022 :
2023 : /* Make sure the sync transmit queue is disabled. */
2024 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET);
2025 :
2026 : /* Init descriptors */
2027 0 : if (msk_init_rx_ring(sc_if) == ENOBUFS) {
2028 0 : printf("%s: initialization failed: no "
2029 0 : "memory for rx buffers\n", sc_if->sk_dev.dv_xname);
2030 0 : msk_stop(sc_if, 0);
2031 0 : splx(s);
2032 0 : return;
2033 : }
2034 :
2035 0 : if (msk_init_tx_ring(sc_if) == ENOBUFS) {
2036 0 : printf("%s: initialization failed: no "
2037 0 : "memory for tx buffers\n", sc_if->sk_dev.dv_xname);
2038 0 : msk_stop(sc_if, 0);
2039 0 : splx(s);
2040 0 : return;
2041 : }
2042 :
2043 : /* Initialize prefetch engine. */
2044 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
2045 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000002);
2046 0 : SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_LIDX, MSK_RX_RING_CNT - 1);
2047 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRLO,
2048 : MSK_RX_RING_ADDR(sc_if, 0));
2049 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRHI,
2050 : (u_int64_t)MSK_RX_RING_ADDR(sc_if, 0) >> 32);
2051 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000008);
2052 0 : SK_IF_READ_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR);
2053 :
2054 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
2055 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000002);
2056 0 : SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_LIDX, MSK_TX_RING_CNT - 1);
2057 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRLO,
2058 : MSK_TX_RING_ADDR(sc_if, 0));
2059 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRHI,
2060 : (u_int64_t)MSK_TX_RING_ADDR(sc_if, 0) >> 32);
2061 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000008);
2062 0 : SK_IF_READ_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR);
2063 :
2064 0 : SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,
2065 : sc_if->sk_cdata.sk_rx_prod);
2066 0 : SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_PUTIDX,
2067 : sc_if->sk_cdata.sk_tx_prod);
2068 :
2069 : /* Configure interrupt handling */
2070 0 : if (sc_if->sk_port == SK_PORT_A)
2071 0 : sc->sk_intrmask |= SK_Y2_INTRS1;
2072 : else
2073 0 : sc->sk_intrmask |= SK_Y2_INTRS2;
2074 0 : sc->sk_intrmask |= SK_Y2_IMR_BMU;
2075 0 : CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2076 :
2077 0 : ifp->if_flags |= IFF_RUNNING;
2078 0 : ifq_clr_oactive(&ifp->if_snd);
2079 :
2080 0 : timeout_add_sec(&sc_if->sk_tick_ch, 1);
2081 :
2082 0 : splx(s);
2083 0 : }
2084 :
2085 : void
2086 0 : msk_stop(struct sk_if_softc *sc_if, int softonly)
2087 : {
2088 0 : struct sk_softc *sc = sc_if->sk_softc;
2089 0 : struct ifnet *ifp = &sc_if->arpcom.ac_if;
2090 : struct mbuf *m;
2091 : bus_dmamap_t map;
2092 : int i;
2093 :
2094 : DPRINTFN(2, ("msk_stop\n"));
2095 :
2096 0 : timeout_del(&sc_if->sk_tick_ch);
2097 0 : timeout_del(&sc_if->sk_tick_rx);
2098 :
2099 0 : ifp->if_flags &= ~IFF_RUNNING;
2100 0 : ifq_clr_oactive(&ifp->if_snd);
2101 :
2102 : /* Stop transfer of Tx descriptors */
2103 :
2104 : /* Stop transfer of Rx descriptors */
2105 :
2106 0 : if (!softonly) {
2107 : /* Turn off various components of this interface. */
2108 0 : SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
2109 0 : SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
2110 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
2111 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2112 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE);
2113 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2114 0 : SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
2115 0 : SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
2116 0 : SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP);
2117 0 : SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
2118 0 : SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
2119 :
2120 0 : SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
2121 0 : SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
2122 :
2123 : /* Disable interrupts */
2124 0 : if (sc_if->sk_port == SK_PORT_A)
2125 0 : sc->sk_intrmask &= ~SK_Y2_INTRS1;
2126 : else
2127 0 : sc->sk_intrmask &= ~SK_Y2_INTRS2;
2128 0 : CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2129 0 : }
2130 :
2131 : /* Free RX and TX mbufs still in the queues. */
2132 0 : for (i = 0; i < MSK_RX_RING_CNT; i++) {
2133 0 : m = sc_if->sk_cdata.sk_rx_mbuf[i];
2134 0 : if (m == NULL)
2135 : continue;
2136 :
2137 0 : map = sc_if->sk_cdata.sk_rx_maps[i];
2138 0 : bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,
2139 : BUS_DMASYNC_POSTREAD);
2140 0 : bus_dmamap_unload(sc->sc_dmatag, map);
2141 :
2142 0 : m_freem(m);
2143 :
2144 0 : sc_if->sk_cdata.sk_rx_mbuf[i] = NULL;
2145 0 : }
2146 :
2147 0 : sc_if->sk_cdata.sk_rx_prod = 0;
2148 0 : sc_if->sk_cdata.sk_rx_cons = 0;
2149 :
2150 0 : for (i = 0; i < MSK_TX_RING_CNT; i++) {
2151 0 : m = sc_if->sk_cdata.sk_tx_mbuf[i];
2152 0 : if (m == NULL)
2153 : continue;
2154 :
2155 0 : map = sc_if->sk_cdata.sk_tx_maps[i];
2156 0 : bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,
2157 : BUS_DMASYNC_POSTREAD);
2158 0 : bus_dmamap_unload(sc->sc_dmatag, map);
2159 :
2160 0 : m_freem(m);
2161 :
2162 0 : sc_if->sk_cdata.sk_tx_mbuf[i] = NULL;
2163 0 : }
2164 0 : }
2165 :
2166 : struct cfattach mskc_ca = {
2167 : sizeof(struct sk_softc), mskc_probe, mskc_attach, mskc_detach,
2168 : mskc_activate
2169 : };
2170 :
2171 : struct cfdriver mskc_cd = {
2172 : NULL, "mskc", DV_DULL
2173 : };
2174 :
2175 : struct cfattach msk_ca = {
2176 : sizeof(struct sk_if_softc), msk_probe, msk_attach, msk_detach,
2177 : msk_activate
2178 : };
2179 :
2180 : struct cfdriver msk_cd = {
2181 : NULL, "msk", DV_IFNET
2182 : };
2183 :
2184 : #ifdef MSK_DEBUG
2185 : void
2186 : msk_dump_txdesc(struct msk_tx_desc *le, int idx)
2187 : {
2188 : #define DESC_PRINT(X) \
2189 : if (X) \
2190 : printf("txdesc[%d]." #X "=%#x\n", \
2191 : idx, X);
2192 :
2193 : DESC_PRINT(letoh32(le->sk_addr));
2194 : DESC_PRINT(letoh16(le->sk_len));
2195 : DESC_PRINT(le->sk_ctl);
2196 : DESC_PRINT(le->sk_opcode);
2197 : #undef DESC_PRINT
2198 : }
2199 :
2200 : void
2201 : msk_dump_bytes(const char *data, int len)
2202 : {
2203 : int c, i, j;
2204 :
2205 : for (i = 0; i < len; i += 16) {
2206 : printf("%08x ", i);
2207 : c = len - i;
2208 : if (c > 16) c = 16;
2209 :
2210 : for (j = 0; j < c; j++) {
2211 : printf("%02x ", data[i + j] & 0xff);
2212 : if ((j & 0xf) == 7 && j > 0)
2213 : printf(" ");
2214 : }
2215 :
2216 : for (; j < 16; j++)
2217 : printf(" ");
2218 : printf(" ");
2219 :
2220 : for (j = 0; j < c; j++) {
2221 : int ch = data[i + j] & 0xff;
2222 : printf("%c", ' ' <= ch && ch <= '~' ? ch : ' ');
2223 : }
2224 :
2225 : printf("\n");
2226 :
2227 : if (c < 16)
2228 : break;
2229 : }
2230 : }
2231 :
2232 : void
2233 : msk_dump_mbuf(struct mbuf *m)
2234 : {
2235 : int count = m->m_pkthdr.len;
2236 :
2237 : printf("m=%#lx, m->m_pkthdr.len=%#d\n", m, m->m_pkthdr.len);
2238 :
2239 : while (count > 0 && m) {
2240 : printf("m=%#lx, m->m_data=%#lx, m->m_len=%d\n",
2241 : m, m->m_data, m->m_len);
2242 : msk_dump_bytes(mtod(m, char *), m->m_len);
2243 :
2244 : count -= m->m_len;
2245 : m = m->m_next;
2246 : }
2247 : }
2248 : #endif
|