if_sk.c revision 148654
1116742Ssam/*	$OpenBSD: if_sk.c,v 2.33 2003/08/12 05:23:06 nate Exp $	*/
2116904Ssam
3139530Ssam/*-
4116742Ssam * Copyright (c) 1997, 1998, 1999, 2000
5116742Ssam *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
6116742Ssam *
7116742Ssam * Redistribution and use in source and binary forms, with or without
8116742Ssam * modification, are permitted provided that the following conditions
9116742Ssam * are met:
10116742Ssam * 1. Redistributions of source code must retain the above copyright
11116742Ssam *    notice, this list of conditions and the following disclaimer.
12116742Ssam * 2. Redistributions in binary form must reproduce the above copyright
13116742Ssam *    notice, this list of conditions and the following disclaimer in the
14116904Ssam *    documentation and/or other materials provided with the distribution.
15116904Ssam * 3. All advertising materials mentioning features or use of this software
16116742Ssam *    must display the following acknowledgement:
17116904Ssam *	This product includes software developed by Bill Paul.
18116904Ssam * 4. Neither the name of the author nor the names of any co-contributors
19116904Ssam *    may be used to endorse or promote products derived from this software
20116742Ssam *    without specific prior written permission.
21116904Ssam *
22116904Ssam * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23116904Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24116904Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25116904Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26116904Ssam * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27116904Ssam * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28116904Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29116904Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30116904Ssam * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31116904Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32116742Ssam * THE POSSIBILITY OF SUCH DAMAGE.
33116742Ssam */
34116742Ssam/*-
35116742Ssam * Copyright (c) 2003 Nathan L. Binkert <binkertn@umich.edu>
36116742Ssam *
37116742Ssam * Permission to use, copy, modify, and distribute this software for any
38116742Ssam * purpose with or without fee is hereby granted, provided that the above
39116742Ssam * copyright notice and this permission notice appear in all copies.
40138568Ssam *
41138568Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
42116742Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
43138568Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
44138568Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
45138568Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
46138568Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
47138568Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
48138568Ssam */
49138568Ssam
50138568Ssam#include <sys/cdefs.h>
51138568Ssam__FBSDID("$FreeBSD: head/sys/dev/sk/if_sk.c 148654 2005-08-03 00:18:35Z rwatson $");
52138568Ssam
53138568Ssam/*
54138568Ssam * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports
55116742Ssam * the SK-984x series adapters, both single port and dual port.
56116742Ssam * References:
57121180Ssam * 	The XaQti XMAC II datasheet,
58116742Ssam *  http://www.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf
59116742Ssam *	The SysKonnect GEnesis manual, http://www.syskonnect.com
60116742Ssam *
61138568Ssam * Note: XaQti has been aquired by Vitesse, and Vitesse does not have the
62138568Ssam * XMAC II datasheet online. I have put my copy at people.freebsd.org as a
63116742Ssam * convenience to others until Vitesse corrects this problem:
64138568Ssam *
65140754Ssam * http://people.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf
66116742Ssam *
67153349Ssam * Written by Bill Paul <wpaul@ee.columbia.edu>
68155688Ssam * Department of Electrical Engineering
69153349Ssam * Columbia University, New York City
70138568Ssam */
71138568Ssam/*
72116742Ssam * The SysKonnect gigabit ethernet adapters consist of two main
73148290Ssam * components: the SysKonnect GEnesis controller chip and the XaQti Corp.
74153346Ssam * XMAC II gigabit ethernet MAC. The XMAC provides all of the MAC
75148290Ssam * components and a PHY while the GEnesis controller provides a PCI
76148291Ssam * interface with DMA support. Each card may have between 512K and
77148291Ssam * 2MB of SRAM on board depending on the configuration.
78148291Ssam *
79167242Ssam * The SysKonnect GEnesis controller can have either one or two XMAC
80167242Ssam * chips connected to it, allowing single or dual port NIC configurations.
81167242Ssam * SysKonnect has the distinction of being the only vendor on the market
82140754Ssam * with a dual port gigabit ethernet NIC. The GEnesis provides dual FIFOs,
83138568Ssam * dual DMA queues, packet/MAC/transmit arbiters and direct access to the
84138568Ssam * XMAC registers. This driver takes advantage of these features to allow
85116742Ssam * both XMACs to operate as independent interfaces.
86138568Ssam */
87138568Ssam
88138568Ssam#include <sys/param.h>
89138568Ssam#include <sys/systm.h>
90138568Ssam#include <sys/sockio.h>
91138568Ssam#include <sys/mbuf.h>
92138568Ssam#include <sys/malloc.h>
93138568Ssam#include <sys/kernel.h>
94127648Ssam#include <sys/module.h>
95138568Ssam#include <sys/socket.h>
96116742Ssam#include <sys/queue.h>
97119150Ssam#include <sys/sysctl.h>
98119150Ssam
99116742Ssam#include <net/if.h>
100116742Ssam#include <net/if_arp.h>
101117811Ssam#include <net/ethernet.h>
102117811Ssam#include <net/if_dl.h>
103148307Ssam#include <net/if_media.h>
104138568Ssam#include <net/if_types.h>
105148304Ssam
106160690Ssam#include <net/bpf.h>
107160690Ssam
108160690Ssam#include <vm/vm.h>              /* for vtophys */
109116742Ssam#include <vm/pmap.h>            /* for vtophys */
110116742Ssam#include <machine/bus.h>
111116742Ssam#include <machine/resource.h>
112138568Ssam#include <sys/bus.h>
113138568Ssam#include <sys/rman.h>
114138568Ssam
115138568Ssam#include <dev/mii/mii.h>
116116742Ssam#include <dev/mii/miivar.h>
117116742Ssam#include <dev/mii/brgphyreg.h>
118148288Ssam
119116742Ssam#include <dev/pci/pcireg.h>
120116742Ssam#include <dev/pci/pcivar.h>
121116742Ssam
122116742Ssam#if 0
123116742Ssam#define SK_USEIOSPACE
124116742Ssam#endif
125127648Ssam
126138568Ssam#include <pci/if_skreg.h>
127140753Ssam#include <pci/xmaciireg.h>
128138568Ssam#include <pci/yukonreg.h>
129138568Ssam
130138568SsamMODULE_DEPEND(sk, pci, 1, 1, 1);
131138568SsamMODULE_DEPEND(sk, ether, 1, 1, 1);
132138568SsamMODULE_DEPEND(sk, miibus, 1, 1, 1);
133138568Ssam
134138568Ssam/* "controller miibus0" required.  See GENERIC if you get errors here. */
135147152Ssam#include "miibus_if.h"
136147152Ssam
137116742Ssam#ifndef lint
138116742Ssamstatic const char rcsid[] =
139116742Ssam  "$FreeBSD: head/sys/dev/sk/if_sk.c 148654 2005-08-03 00:18:35Z rwatson $";
140116742Ssam#endif
141148936Ssam
142116742Ssamstatic struct sk_type sk_devs[] = {
143153346Ssam	{
144116742Ssam		VENDORID_SK,
145116742Ssam		DEVICEID_SK_V1,
146154734Ssam		"SysKonnect Gigabit Ethernet (V1.0)"
147153349Ssam	},
148153349Ssam	{
149154736Ssam		VENDORID_SK,
150154736Ssam		DEVICEID_SK_V2,
151154736Ssam		"SysKonnect Gigabit Ethernet (V2.0)"
152138568Ssam	},
153138568Ssam	{
154138568Ssam		VENDORID_MARVELL,
155138568Ssam		DEVICEID_SK_V2,
156116742Ssam		"Marvell Gigabit Ethernet"
157148843Ssam	},
158116742Ssam	{
159116742Ssam		VENDORID_MARVELL,
160116742Ssam		DEVICEID_BELKIN_5005,
161116742Ssam		"Belkin F5D5005 Gigabit Ethernet"
162138568Ssam	},
163138568Ssam	{
164138568Ssam		VENDORID_3COM,
165116742Ssam		DEVICEID_3COM_3C940,
166116742Ssam		"3Com 3C940 Gigabit Ethernet"
167116742Ssam	},
168116742Ssam	{
169116742Ssam		VENDORID_LINKSYS,
170116742Ssam		DEVICEID_LINKSYS_EG1032,
171138568Ssam		"Linksys EG1032 Gigabit Ethernet"
172138568Ssam	},
173138568Ssam	{
174138568Ssam		VENDORID_DLINK,
175138568Ssam		DEVICEID_DLINK_DGE530T,
176138568Ssam		"D-Link DGE-530T Gigabit Ethernet"
177138568Ssam	},
178138568Ssam	{ 0, 0, NULL }
179138568Ssam};
180138568Ssam
181138568Ssamstatic int skc_probe(device_t);
182138568Ssamstatic int skc_attach(device_t);
183138568Ssamstatic int skc_detach(device_t);
184138568Ssamstatic void skc_shutdown(device_t);
185138568Ssamstatic int sk_detach(device_t);
186138568Ssamstatic int sk_probe(device_t);
187138568Ssamstatic int sk_attach(device_t);
188138568Ssamstatic void sk_tick(void *);
189138568Ssamstatic void sk_intr(void *);
190138568Ssamstatic void sk_intr_xmac(struct sk_if_softc *);
191138568Ssamstatic void sk_intr_bcom(struct sk_if_softc *);
192138568Ssamstatic void sk_intr_yukon(struct sk_if_softc *);
193138568Ssamstatic void sk_rxeof(struct sk_if_softc *);
194138568Ssamstatic void sk_txeof(struct sk_if_softc *);
195138568Ssamstatic int sk_encap(struct sk_if_softc *, struct mbuf *,
196138568Ssam					u_int32_t *);
197138568Ssamstatic void sk_start(struct ifnet *);
198138568Ssamstatic int sk_ioctl(struct ifnet *, u_long, caddr_t);
199138568Ssamstatic void sk_init(void *);
200138568Ssamstatic void sk_init_xmac(struct sk_if_softc *);
201138568Ssamstatic void sk_init_yukon(struct sk_if_softc *);
202138568Ssamstatic void sk_stop(struct sk_if_softc *);
203138568Ssamstatic void sk_watchdog(struct ifnet *);
204138568Ssamstatic int sk_ifmedia_upd(struct ifnet *);
205138568Ssamstatic void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
206138568Ssamstatic void sk_reset(struct sk_softc *);
207138568Ssamstatic int sk_newbuf(struct sk_if_softc *,
208116742Ssam					struct sk_chain *, struct mbuf *);
209116742Ssamstatic int sk_alloc_jumbo_mem(struct sk_if_softc *);
210116742Ssamstatic void sk_free_jumbo_mem(struct sk_if_softc *);
211116742Ssamstatic void *sk_jalloc(struct sk_if_softc *);
212116742Ssamstatic void sk_jfree(void *, void *);
213116742Ssamstatic int sk_init_rx_ring(struct sk_if_softc *);
214148288Ssamstatic void sk_init_tx_ring(struct sk_if_softc *);
215148289Ssamstatic u_int32_t sk_win_read_4(struct sk_softc *, int);
216148289Ssamstatic u_int16_t sk_win_read_2(struct sk_softc *, int);
217153421Ssamstatic u_int8_t sk_win_read_1(struct sk_softc *, int);
218138568Ssamstatic void sk_win_write_4(struct sk_softc *, int, u_int32_t);
219138568Ssamstatic void sk_win_write_2(struct sk_softc *, int, u_int32_t);
220147794Ssamstatic void sk_win_write_1(struct sk_softc *, int, u_int32_t);
221138568Ssamstatic u_int8_t sk_vpd_readbyte(struct sk_softc *, int);
222138568Ssamstatic void sk_vpd_read_res(struct sk_softc *, struct vpd_res *, int);
223138568Ssamstatic void sk_vpd_read(struct sk_softc *);
224138568Ssam
225138568Ssamstatic int sk_miibus_readreg(device_t, int, int);
226138568Ssamstatic int sk_miibus_writereg(device_t, int, int, int);
227138568Ssamstatic void sk_miibus_statchg(device_t);
228138568Ssam
229148288Ssamstatic int sk_xmac_miibus_readreg(struct sk_if_softc *, int, int);
230138568Ssamstatic int sk_xmac_miibus_writereg(struct sk_if_softc *, int, int,
231138568Ssam						int);
232138568Ssamstatic void sk_xmac_miibus_statchg(struct sk_if_softc *);
233138568Ssam
234138568Ssamstatic int sk_marv_miibus_readreg(struct sk_if_softc *, int, int);
235127648Ssamstatic int sk_marv_miibus_writereg(struct sk_if_softc *, int, int,
236127648Ssam						int);
237138568Ssamstatic void sk_marv_miibus_statchg(struct sk_if_softc *);
238138568Ssam
239138568Ssamstatic uint32_t sk_xmchash(const uint8_t *);
240138568Ssamstatic uint32_t sk_gmchash(const uint8_t *);
241138568Ssamstatic void sk_setfilt(struct sk_if_softc *, caddr_t, int);
242138568Ssamstatic void sk_setmulti(struct sk_if_softc *);
243138568Ssamstatic void sk_setpromisc(struct sk_if_softc *);
244138568Ssam
245138568Ssamstatic int sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high);
246116742Ssamstatic int sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS);
247148288Ssam
248148288Ssam#ifdef SK_USEIOSPACE
249148288Ssam#define SK_RES		SYS_RES_IOPORT
250148288Ssam#define SK_RID		SK_PCI_LOIO
251153973Ssam#else
252154736Ssam#define SK_RES		SYS_RES_MEMORY
253156358Ssam#define SK_RID		SK_PCI_LOMEM
254148288Ssam#endif
255121176Ssam
256116742Ssam/*
257138568Ssam * Note that we have newbus methods for both the GEnesis controller
258138568Ssam * itself and the XMAC(s). The XMACs are children of the GEnesis, and
259138568Ssam * the miibus code is a child of the XMACs. We need to do it this way
260138568Ssam * so that the miibus drivers can access the PHY registers on the
261148288Ssam * right PHY. It's not quite what I had in mind, but it's the only
262148288Ssam * design that achieves the desired effect.
263138568Ssam */
264138568Ssamstatic device_method_t skc_methods[] = {
265138568Ssam	/* Device interface */
266138568Ssam	DEVMETHOD(device_probe,		skc_probe),
267138568Ssam	DEVMETHOD(device_attach,	skc_attach),
268138568Ssam	DEVMETHOD(device_detach,	skc_detach),
269138568Ssam	DEVMETHOD(device_shutdown,	skc_shutdown),
270138568Ssam
271138568Ssam	/* bus interface */
272138568Ssam	DEVMETHOD(bus_print_child,	bus_generic_print_child),
273138568Ssam	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
274138568Ssam
275138568Ssam	{ 0, 0 }
276138568Ssam};
277138568Ssam
278148288Ssamstatic driver_t skc_driver = {
279148288Ssam	"skc",
280148288Ssam	skc_methods,
281148288Ssam	sizeof(struct sk_softc)
282138568Ssam};
283116742Ssam
284138568Ssamstatic devclass_t skc_devclass;
285116742Ssam
286138568Ssamstatic device_method_t sk_methods[] = {
287138568Ssam	/* Device interface */
288165569Ssam	DEVMETHOD(device_probe,		sk_probe),
289165569Ssam	DEVMETHOD(device_attach,	sk_attach),
290138568Ssam	DEVMETHOD(device_detach,	sk_detach),
291138568Ssam	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
292138568Ssam
293138568Ssam	/* bus interface */
294116742Ssam	DEVMETHOD(bus_print_child,	bus_generic_print_child),
295116742Ssam	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
296138568Ssam
297138568Ssam	/* MII interface */
298138568Ssam	DEVMETHOD(miibus_readreg,	sk_miibus_readreg),
299138568Ssam	DEVMETHOD(miibus_writereg,	sk_miibus_writereg),
300116742Ssam	DEVMETHOD(miibus_statchg,	sk_miibus_statchg),
301116742Ssam
302116742Ssam	{ 0, 0 }
303152450Ssam};
304165822Skmacy
305116742Ssamstatic driver_t sk_driver = {
306116742Ssam	"sk",
307116742Ssam	sk_methods,
308165569Ssam	sizeof(struct sk_if_softc)
309116742Ssam};
310138568Ssam
311138568Ssamstatic devclass_t sk_devclass;
312138568Ssam
313138568SsamDRIVER_MODULE(sk, pci, skc_driver, skc_devclass, 0, 0);
314138568SsamDRIVER_MODULE(sk, skc, sk_driver, sk_devclass, 0, 0);
315138568SsamDRIVER_MODULE(miibus, sk, miibus_driver, miibus_devclass, 0, 0);
316138568Ssam
317138568Ssam#define SK_SETBIT(sc, reg, x)		\
318138568Ssam	CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | x)
319138568Ssam
320138568Ssam#define SK_CLRBIT(sc, reg, x)		\
321138568Ssam	CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~x)
322138568Ssam
323138568Ssam#define SK_WIN_SETBIT_4(sc, reg, x)	\
324139509Ssam	sk_win_write_4(sc, reg, sk_win_read_4(sc, reg) | x)
325139509Ssam
326139509Ssam#define SK_WIN_CLRBIT_4(sc, reg, x)	\
327139509Ssam	sk_win_write_4(sc, reg, sk_win_read_4(sc, reg) & ~x)
328139509Ssam
329139509Ssam#define SK_WIN_SETBIT_2(sc, reg, x)	\
330139509Ssam	sk_win_write_2(sc, reg, sk_win_read_2(sc, reg) | x)
331139509Ssam
332139509Ssam#define SK_WIN_CLRBIT_2(sc, reg, x)	\
333139509Ssam	sk_win_write_2(sc, reg, sk_win_read_2(sc, reg) & ~x)
334139509Ssam
335139509Ssamstatic u_int32_t
336139509Ssamsk_win_read_4(sc, reg)
337139509Ssam	struct sk_softc		*sc;
338139509Ssam	int			reg;
339139509Ssam{
340139509Ssam#ifdef SK_USEIOSPACE
341139509Ssam	CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg));
342139509Ssam	return(CSR_READ_4(sc, SK_WIN_BASE + SK_REG(reg)));
343139509Ssam#else
344139509Ssam	return(CSR_READ_4(sc, reg));
345139509Ssam#endif
346139509Ssam}
347139509Ssam
348139509Ssamstatic u_int16_t
349139509Ssamsk_win_read_2(sc, reg)
350139509Ssam	struct sk_softc		*sc;
351139509Ssam	int			reg;
352139509Ssam{
353139509Ssam#ifdef SK_USEIOSPACE
354138568Ssam	CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg));
355138568Ssam	return(CSR_READ_2(sc, SK_WIN_BASE + SK_REG(reg)));
356138568Ssam#else
357138568Ssam	return(CSR_READ_2(sc, reg));
358138568Ssam#endif
359138568Ssam}
360138568Ssam
361138568Ssamstatic u_int8_t
362138568Ssamsk_win_read_1(sc, reg)
363138568Ssam	struct sk_softc		*sc;
364138568Ssam	int			reg;
365138568Ssam{
366138568Ssam#ifdef SK_USEIOSPACE
367138568Ssam	CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg));
368138568Ssam	return(CSR_READ_1(sc, SK_WIN_BASE + SK_REG(reg)));
369138568Ssam#else
370138568Ssam	return(CSR_READ_1(sc, reg));
371138568Ssam#endif
372138568Ssam}
373138568Ssam
374138568Ssamstatic void
375148288Ssamsk_win_write_4(sc, reg, val)
376148288Ssam	struct sk_softc		*sc;
377148288Ssam	int			reg;
378148288Ssam	u_int32_t		val;
379164634Ssam{
380138568Ssam#ifdef SK_USEIOSPACE
381138568Ssam	CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg));
382138568Ssam	CSR_WRITE_4(sc, SK_WIN_BASE + SK_REG(reg), val);
383116742Ssam#else
384148288Ssam	CSR_WRITE_4(sc, reg, val);
385148288Ssam#endif
386148288Ssam	return;
387148288Ssam}
388138568Ssam
389148288Ssamstatic void
390148288Ssamsk_win_write_2(sc, reg, val)
391148288Ssam	struct sk_softc		*sc;
392148288Ssam	int			reg;
393148288Ssam	u_int32_t		val;
394148288Ssam{
395148288Ssam#ifdef SK_USEIOSPACE
396148288Ssam	CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg));
397148288Ssam	CSR_WRITE_2(sc, SK_WIN_BASE + SK_REG(reg), val);
398148288Ssam#else
399148288Ssam	CSR_WRITE_2(sc, reg, val);
400148288Ssam#endif
401148288Ssam	return;
402148288Ssam}
403148288Ssam
404148288Ssamstatic void
405148288Ssamsk_win_write_1(sc, reg, val)
406138568Ssam	struct sk_softc		*sc;
407138568Ssam	int			reg;
408138568Ssam	u_int32_t		val;
409138568Ssam{
410138568Ssam#ifdef SK_USEIOSPACE
411138568Ssam	CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg));
412138568Ssam	CSR_WRITE_1(sc, SK_WIN_BASE + SK_REG(reg), val);
413138568Ssam#else
414138568Ssam	CSR_WRITE_1(sc, reg, val);
415138568Ssam#endif
416138568Ssam	return;
417138568Ssam}
418138568Ssam
419138568Ssam/*
420148288Ssam * The VPD EEPROM contains Vital Product Data, as suggested in
421148288Ssam * the PCI 2.1 specification. The VPD data is separared into areas
422116742Ssam * denoted by resource IDs. The SysKonnect VPD contains an ID string
423138568Ssam * resource (the name of the adapter), a read-only area resource
424148288Ssam * containing various key/data fields and a read/write area which
425148288Ssam * can be used to store asset management information or log messages.
426148288Ssam * We read the ID string and read-only into buffers attached to
427148288Ssam * the controller softc structure for later use. At the moment,
428116742Ssam * we only use the ID string during skc_attach().
429116742Ssam */
430116742Ssamstatic u_int8_t
431sk_vpd_readbyte(sc, addr)
432	struct sk_softc		*sc;
433	int			addr;
434{
435	int			i;
436
437	sk_win_write_2(sc, SK_PCI_REG(SK_PCI_VPD_ADDR), addr);
438	for (i = 0; i < SK_TIMEOUT; i++) {
439		DELAY(1);
440		if (sk_win_read_2(sc,
441		    SK_PCI_REG(SK_PCI_VPD_ADDR)) & SK_VPD_FLAG)
442			break;
443	}
444
445	if (i == SK_TIMEOUT)
446		return(0);
447
448	return(sk_win_read_1(sc, SK_PCI_REG(SK_PCI_VPD_DATA)));
449}
450
451static void
452sk_vpd_read_res(sc, res, addr)
453	struct sk_softc		*sc;
454	struct vpd_res		*res;
455	int			addr;
456{
457	int			i;
458	u_int8_t		*ptr;
459
460	ptr = (u_int8_t *)res;
461	for (i = 0; i < sizeof(struct vpd_res); i++)
462		ptr[i] = sk_vpd_readbyte(sc, i + addr);
463
464	return;
465}
466
467static void
468sk_vpd_read(sc)
469	struct sk_softc		*sc;
470{
471	int			pos = 0, i;
472	struct vpd_res		res;
473
474	if (sc->sk_vpd_prodname != NULL)
475		free(sc->sk_vpd_prodname, M_DEVBUF);
476	if (sc->sk_vpd_readonly != NULL)
477		free(sc->sk_vpd_readonly, M_DEVBUF);
478	sc->sk_vpd_prodname = NULL;
479	sc->sk_vpd_readonly = NULL;
480	sc->sk_vpd_readonly_len = 0;
481
482	sk_vpd_read_res(sc, &res, pos);
483
484	/*
485	 * Bail out quietly if the eeprom appears to be missing or empty.
486	 */
487	if (res.vr_id == 0xff && res.vr_len == 0xff && res.vr_pad == 0xff)
488		return;
489
490	if (res.vr_id != VPD_RES_ID) {
491		printf("skc%d: bad VPD resource id: expected %x got %x\n",
492		    sc->sk_unit, VPD_RES_ID, res.vr_id);
493		return;
494	}
495
496	pos += sizeof(res);
497	sc->sk_vpd_prodname = malloc(res.vr_len + 1, M_DEVBUF, M_NOWAIT);
498	if (sc->sk_vpd_prodname != NULL) {
499		for (i = 0; i < res.vr_len; i++)
500			sc->sk_vpd_prodname[i] = sk_vpd_readbyte(sc, i + pos);
501		sc->sk_vpd_prodname[i] = '\0';
502	}
503	pos += res.vr_len;
504
505	sk_vpd_read_res(sc, &res, pos);
506
507	if (res.vr_id != VPD_RES_READ) {
508		printf("skc%d: bad VPD resource id: expected %x got %x\n",
509		    sc->sk_unit, VPD_RES_READ, res.vr_id);
510		return;
511	}
512
513	pos += sizeof(res);
514	sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
515	for (i = 0; i < res.vr_len; i++)
516		sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos);
517	sc->sk_vpd_readonly_len = res.vr_len;
518
519	return;
520}
521
522static int
523sk_miibus_readreg(dev, phy, reg)
524	device_t		dev;
525	int			phy, reg;
526{
527	struct sk_if_softc	*sc_if;
528
529	sc_if = device_get_softc(dev);
530
531	switch(sc_if->sk_softc->sk_type) {
532	case SK_GENESIS:
533		return(sk_xmac_miibus_readreg(sc_if, phy, reg));
534	case SK_YUKON:
535	case SK_YUKON_LITE:
536	case SK_YUKON_LP:
537		return(sk_marv_miibus_readreg(sc_if, phy, reg));
538	}
539
540	return(0);
541}
542
543static int
544sk_miibus_writereg(dev, phy, reg, val)
545	device_t		dev;
546	int			phy, reg, val;
547{
548	struct sk_if_softc	*sc_if;
549
550	sc_if = device_get_softc(dev);
551
552	switch(sc_if->sk_softc->sk_type) {
553	case SK_GENESIS:
554		return(sk_xmac_miibus_writereg(sc_if, phy, reg, val));
555	case SK_YUKON:
556	case SK_YUKON_LITE:
557	case SK_YUKON_LP:
558		return(sk_marv_miibus_writereg(sc_if, phy, reg, val));
559	}
560
561	return(0);
562}
563
564static void
565sk_miibus_statchg(dev)
566	device_t		dev;
567{
568	struct sk_if_softc	*sc_if;
569
570	sc_if = device_get_softc(dev);
571
572	switch(sc_if->sk_softc->sk_type) {
573	case SK_GENESIS:
574		sk_xmac_miibus_statchg(sc_if);
575		break;
576	case SK_YUKON:
577	case SK_YUKON_LITE:
578	case SK_YUKON_LP:
579		sk_marv_miibus_statchg(sc_if);
580		break;
581	}
582
583	return;
584}
585
586static int
587sk_xmac_miibus_readreg(sc_if, phy, reg)
588	struct sk_if_softc	*sc_if;
589	int			phy, reg;
590{
591	int			i;
592
593	if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0)
594		return(0);
595
596	SK_IF_LOCK(sc_if);
597	SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
598	SK_XM_READ_2(sc_if, XM_PHY_DATA);
599	if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) {
600		for (i = 0; i < SK_TIMEOUT; i++) {
601			DELAY(1);
602			if (SK_XM_READ_2(sc_if, XM_MMUCMD) &
603			    XM_MMUCMD_PHYDATARDY)
604				break;
605		}
606
607		if (i == SK_TIMEOUT) {
608			printf("sk%d: phy failed to come ready\n",
609			    sc_if->sk_unit);
610			SK_IF_UNLOCK(sc_if);
611			return(0);
612		}
613	}
614	DELAY(1);
615	i = SK_XM_READ_2(sc_if, XM_PHY_DATA);
616	SK_IF_UNLOCK(sc_if);
617	return(i);
618}
619
620static int
621sk_xmac_miibus_writereg(sc_if, phy, reg, val)
622	struct sk_if_softc	*sc_if;
623	int			phy, reg, val;
624{
625	int			i;
626
627	SK_IF_LOCK(sc_if);
628	SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
629	for (i = 0; i < SK_TIMEOUT; i++) {
630		if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY))
631			break;
632	}
633
634	if (i == SK_TIMEOUT) {
635		printf("sk%d: phy failed to come ready\n", sc_if->sk_unit);
636		SK_IF_UNLOCK(sc_if);
637		return(ETIMEDOUT);
638	}
639
640	SK_XM_WRITE_2(sc_if, XM_PHY_DATA, val);
641	for (i = 0; i < SK_TIMEOUT; i++) {
642		DELAY(1);
643		if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY))
644			break;
645	}
646	SK_IF_UNLOCK(sc_if);
647	if (i == SK_TIMEOUT)
648		printf("sk%d: phy write timed out\n", sc_if->sk_unit);
649
650	return(0);
651}
652
653static void
654sk_xmac_miibus_statchg(sc_if)
655	struct sk_if_softc	*sc_if;
656{
657	struct mii_data		*mii;
658
659	mii = device_get_softc(sc_if->sk_miibus);
660
661	SK_IF_LOCK(sc_if);
662	/*
663	 * If this is a GMII PHY, manually set the XMAC's
664	 * duplex mode accordingly.
665	 */
666	if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) {
667		if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
668			SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX);
669		} else {
670			SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX);
671		}
672	}
673	SK_IF_UNLOCK(sc_if);
674
675	return;
676}
677
678static int
679sk_marv_miibus_readreg(sc_if, phy, reg)
680	struct sk_if_softc	*sc_if;
681	int			phy, reg;
682{
683	u_int16_t		val;
684	int			i;
685
686	if (phy != 0 ||
687	    (sc_if->sk_phytype != SK_PHYTYPE_MARV_COPPER &&
688	     sc_if->sk_phytype != SK_PHYTYPE_MARV_FIBER)) {
689		return(0);
690	}
691
692	SK_IF_LOCK(sc_if);
693        SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
694		      YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ);
695
696	for (i = 0; i < SK_TIMEOUT; i++) {
697		DELAY(1);
698		val = SK_YU_READ_2(sc_if, YUKON_SMICR);
699		if (val & YU_SMICR_READ_VALID)
700			break;
701	}
702
703	if (i == SK_TIMEOUT) {
704		printf("sk%d: phy failed to come ready\n",
705		    sc_if->sk_unit);
706		SK_IF_UNLOCK(sc_if);
707		return(0);
708	}
709
710	val = SK_YU_READ_2(sc_if, YUKON_SMIDR);
711	SK_IF_UNLOCK(sc_if);
712
713	return(val);
714}
715
716static int
717sk_marv_miibus_writereg(sc_if, phy, reg, val)
718	struct sk_if_softc	*sc_if;
719	int			phy, reg, val;
720{
721	int			i;
722
723	SK_IF_LOCK(sc_if);
724	SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val);
725	SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
726		      YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE);
727
728	for (i = 0; i < SK_TIMEOUT; i++) {
729		DELAY(1);
730		if (SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY)
731			break;
732	}
733	SK_IF_UNLOCK(sc_if);
734
735	return(0);
736}
737
738static void
739sk_marv_miibus_statchg(sc_if)
740	struct sk_if_softc	*sc_if;
741{
742	return;
743}
744
745#define HASH_BITS		6
746
747static u_int32_t
748sk_xmchash(addr)
749	const uint8_t *addr;
750{
751	uint32_t crc;
752
753	/* Compute CRC for the address value. */
754	crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
755
756	return (~crc & ((1 << HASH_BITS) - 1));
757}
758
759/* gmchash is just a big endian crc */
760static u_int32_t
761sk_gmchash(addr)
762	const uint8_t *addr;
763{
764	uint32_t crc;
765
766	/* Compute CRC for the address value. */
767	crc = ether_crc32_be(addr, ETHER_ADDR_LEN);
768
769	return (crc & ((1 << HASH_BITS) - 1));
770}
771
772static void
773sk_setfilt(sc_if, addr, slot)
774	struct sk_if_softc	*sc_if;
775	caddr_t			addr;
776	int			slot;
777{
778	int			base;
779
780	base = XM_RXFILT_ENTRY(slot);
781
782	SK_XM_WRITE_2(sc_if, base, *(u_int16_t *)(&addr[0]));
783	SK_XM_WRITE_2(sc_if, base + 2, *(u_int16_t *)(&addr[2]));
784	SK_XM_WRITE_2(sc_if, base + 4, *(u_int16_t *)(&addr[4]));
785
786	return;
787}
788
789static void
790sk_setmulti(sc_if)
791	struct sk_if_softc	*sc_if;
792{
793	struct sk_softc		*sc = sc_if->sk_softc;
794	struct ifnet		*ifp = sc_if->sk_ifp;
795	u_int32_t		hashes[2] = { 0, 0 };
796	int			h = 0, i;
797	struct ifmultiaddr	*ifma;
798	u_int8_t		dummy[] = { 0, 0, 0, 0, 0 ,0 };
799
800
801	/* First, zot all the existing filters. */
802	switch(sc->sk_type) {
803	case SK_GENESIS:
804		for (i = 1; i < XM_RXFILT_MAX; i++)
805			sk_setfilt(sc_if, (caddr_t)&dummy, i);
806
807		SK_XM_WRITE_4(sc_if, XM_MAR0, 0);
808		SK_XM_WRITE_4(sc_if, XM_MAR2, 0);
809		break;
810	case SK_YUKON:
811	case SK_YUKON_LITE:
812	case SK_YUKON_LP:
813		SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
814		SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
815		SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
816		SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0);
817		break;
818	}
819
820	/* Now program new ones. */
821	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
822		hashes[0] = 0xFFFFFFFF;
823		hashes[1] = 0xFFFFFFFF;
824	} else {
825		i = 1;
826		IF_ADDR_LOCK(ifp);
827		TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) {
828			if (ifma->ifma_addr->sa_family != AF_LINK)
829				continue;
830			/*
831			 * Program the first XM_RXFILT_MAX multicast groups
832			 * into the perfect filter. For all others,
833			 * use the hash table.
834			 */
835			if (sc->sk_type == SK_GENESIS && i < XM_RXFILT_MAX) {
836				sk_setfilt(sc_if,
837			LLADDR((struct sockaddr_dl *)ifma->ifma_addr), i);
838				i++;
839				continue;
840			}
841
842			switch(sc->sk_type) {
843			case SK_GENESIS:
844				h = sk_xmchash(
845					LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
846				break;
847			case SK_YUKON:
848			case SK_YUKON_LITE:
849			case SK_YUKON_LP:
850				h = sk_gmchash(
851					LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
852				break;
853			}
854			if (h < 32)
855				hashes[0] |= (1 << h);
856			else
857				hashes[1] |= (1 << (h - 32));
858		}
859		IF_ADDR_UNLOCK(ifp);
860	}
861
862	switch(sc->sk_type) {
863	case SK_GENESIS:
864		SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_HASH|
865			       XM_MODE_RX_USE_PERFECT);
866		SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]);
867		SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]);
868		break;
869	case SK_YUKON:
870	case SK_YUKON_LITE:
871	case SK_YUKON_LP:
872		SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
873		SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
874		SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
875		SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff);
876		break;
877	}
878
879	return;
880}
881
882static void
883sk_setpromisc(sc_if)
884	struct sk_if_softc	*sc_if;
885{
886	struct sk_softc		*sc = sc_if->sk_softc;
887	struct ifnet		*ifp = sc_if->sk_ifp;
888
889	switch(sc->sk_type) {
890	case SK_GENESIS:
891		if (ifp->if_flags & IFF_PROMISC) {
892			SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
893		} else {
894			SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
895		}
896		break;
897	case SK_YUKON:
898	case SK_YUKON_LITE:
899	case SK_YUKON_LP:
900		if (ifp->if_flags & IFF_PROMISC) {
901			SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
902			    YU_RCR_UFLEN | YU_RCR_MUFLEN);
903		} else {
904			SK_YU_SETBIT_2(sc_if, YUKON_RCR,
905			    YU_RCR_UFLEN | YU_RCR_MUFLEN);
906		}
907		break;
908	}
909
910	return;
911}
912
913static int
914sk_init_rx_ring(sc_if)
915	struct sk_if_softc	*sc_if;
916{
917	struct sk_chain_data	*cd = &sc_if->sk_cdata;
918	struct sk_ring_data	*rd = sc_if->sk_rdata;
919	int			i;
920
921	bzero((char *)rd->sk_rx_ring,
922	    sizeof(struct sk_rx_desc) * SK_RX_RING_CNT);
923
924	for (i = 0; i < SK_RX_RING_CNT; i++) {
925		cd->sk_rx_chain[i].sk_desc = &rd->sk_rx_ring[i];
926		if (sk_newbuf(sc_if, &cd->sk_rx_chain[i], NULL) == ENOBUFS)
927			return(ENOBUFS);
928		if (i == (SK_RX_RING_CNT - 1)) {
929			cd->sk_rx_chain[i].sk_next =
930			    &cd->sk_rx_chain[0];
931			rd->sk_rx_ring[i].sk_next =
932			    vtophys(&rd->sk_rx_ring[0]);
933		} else {
934			cd->sk_rx_chain[i].sk_next =
935			    &cd->sk_rx_chain[i + 1];
936			rd->sk_rx_ring[i].sk_next =
937			    vtophys(&rd->sk_rx_ring[i + 1]);
938		}
939	}
940
941	sc_if->sk_cdata.sk_rx_prod = 0;
942	sc_if->sk_cdata.sk_rx_cons = 0;
943
944	return(0);
945}
946
947static void
948sk_init_tx_ring(sc_if)
949	struct sk_if_softc	*sc_if;
950{
951	struct sk_chain_data	*cd = &sc_if->sk_cdata;
952	struct sk_ring_data	*rd = sc_if->sk_rdata;
953	int			i;
954
955	bzero((char *)sc_if->sk_rdata->sk_tx_ring,
956	    sizeof(struct sk_tx_desc) * SK_TX_RING_CNT);
957
958	for (i = 0; i < SK_TX_RING_CNT; i++) {
959		cd->sk_tx_chain[i].sk_desc = &rd->sk_tx_ring[i];
960		if (i == (SK_TX_RING_CNT - 1)) {
961			cd->sk_tx_chain[i].sk_next =
962			    &cd->sk_tx_chain[0];
963			rd->sk_tx_ring[i].sk_next =
964			    vtophys(&rd->sk_tx_ring[0]);
965		} else {
966			cd->sk_tx_chain[i].sk_next =
967			    &cd->sk_tx_chain[i + 1];
968			rd->sk_tx_ring[i].sk_next =
969			    vtophys(&rd->sk_tx_ring[i + 1]);
970		}
971	}
972
973	sc_if->sk_cdata.sk_tx_prod = 0;
974	sc_if->sk_cdata.sk_tx_cons = 0;
975	sc_if->sk_cdata.sk_tx_cnt = 0;
976
977	return;
978}
979
980static int
981sk_newbuf(sc_if, c, m)
982	struct sk_if_softc	*sc_if;
983	struct sk_chain		*c;
984	struct mbuf		*m;
985{
986	struct mbuf		*m_new = NULL;
987	struct sk_rx_desc	*r;
988
989	if (m == NULL) {
990		caddr_t			*buf = NULL;
991
992		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
993		if (m_new == NULL)
994			return(ENOBUFS);
995
996		/* Allocate the jumbo buffer */
997		buf = sk_jalloc(sc_if);
998		if (buf == NULL) {
999			m_freem(m_new);
1000#ifdef SK_VERBOSE
1001			printf("sk%d: jumbo allocation failed "
1002			    "-- packet dropped!\n", sc_if->sk_unit);
1003#endif
1004			return(ENOBUFS);
1005		}
1006
1007		/* Attach the buffer to the mbuf */
1008		MEXTADD(m_new, buf, SK_JLEN, sk_jfree,
1009		    (struct sk_if_softc *)sc_if, 0, EXT_NET_DRV);
1010		m_new->m_data = (void *)buf;
1011		m_new->m_pkthdr.len = m_new->m_len = SK_JLEN;
1012	} else {
1013		/*
1014	 	 * We're re-using a previously allocated mbuf;
1015		 * be sure to re-init pointers and lengths to
1016		 * default values.
1017		 */
1018		m_new = m;
1019		m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
1020		m_new->m_data = m_new->m_ext.ext_buf;
1021	}
1022
1023	/*
1024	 * Adjust alignment so packet payload begins on a
1025	 * longword boundary. Mandatory for Alpha, useful on
1026	 * x86 too.
1027	 */
1028	m_adj(m_new, ETHER_ALIGN);
1029
1030	r = c->sk_desc;
1031	c->sk_mbuf = m_new;
1032	r->sk_data_lo = vtophys(mtod(m_new, caddr_t));
1033	r->sk_ctl = m_new->m_len | SK_RXSTAT;
1034
1035	return(0);
1036}
1037
1038/*
1039 * Allocate jumbo buffer storage. The SysKonnect adapters support
1040 * "jumbograms" (9K frames), although SysKonnect doesn't currently
1041 * use them in their drivers. In order for us to use them, we need
1042 * large 9K receive buffers, however standard mbuf clusters are only
1043 * 2048 bytes in size. Consequently, we need to allocate and manage
1044 * our own jumbo buffer pool. Fortunately, this does not require an
1045 * excessive amount of additional code.
1046 */
1047static int
1048sk_alloc_jumbo_mem(sc_if)
1049	struct sk_if_softc	*sc_if;
1050{
1051	caddr_t			ptr;
1052	register int		i;
1053	struct sk_jpool_entry   *entry;
1054
1055	/* Grab a big chunk o' storage. */
1056	sc_if->sk_cdata.sk_jumbo_buf = contigmalloc(SK_JMEM, M_DEVBUF,
1057	    M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
1058
1059	if (sc_if->sk_cdata.sk_jumbo_buf == NULL) {
1060		printf("sk%d: no memory for jumbo buffers!\n", sc_if->sk_unit);
1061		return(ENOBUFS);
1062	}
1063
1064	mtx_init(&sc_if->sk_jlist_mtx, "sk_jlist_mtx", NULL, MTX_DEF);
1065
1066	SLIST_INIT(&sc_if->sk_jfree_listhead);
1067	SLIST_INIT(&sc_if->sk_jinuse_listhead);
1068
1069	/*
1070	 * Now divide it up into 9K pieces and save the addresses
1071	 * in an array.
1072	 */
1073	ptr = sc_if->sk_cdata.sk_jumbo_buf;
1074	for (i = 0; i < SK_JSLOTS; i++) {
1075		sc_if->sk_cdata.sk_jslots[i] = ptr;
1076		ptr += SK_JLEN;
1077		entry = malloc(sizeof(struct sk_jpool_entry),
1078		    M_DEVBUF, M_NOWAIT);
1079		if (entry == NULL) {
1080			sk_free_jumbo_mem(sc_if);
1081			sc_if->sk_cdata.sk_jumbo_buf = NULL;
1082			printf("sk%d: no memory for jumbo "
1083			    "buffer queue!\n", sc_if->sk_unit);
1084			return(ENOBUFS);
1085		}
1086		entry->slot = i;
1087		SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead,
1088		    entry, jpool_entries);
1089	}
1090
1091	return(0);
1092}
1093
1094static void
1095sk_free_jumbo_mem(sc_if)
1096	struct sk_if_softc	*sc_if;
1097{
1098	struct sk_jpool_entry	*entry;
1099
1100	SK_JLIST_LOCK(sc_if);
1101
1102	/* We cannot release external mbuf storage while in use. */
1103	if (!SLIST_EMPTY(&sc_if->sk_jinuse_listhead)) {
1104		printf("sk%d: will leak jumbo buffer memory!\n", sc_if->sk_unit);
1105		SK_JLIST_UNLOCK(sc_if);
1106		return;
1107	}
1108
1109	while (!SLIST_EMPTY(&sc_if->sk_jfree_listhead)) {
1110		entry = SLIST_FIRST(&sc_if->sk_jfree_listhead);
1111		SLIST_REMOVE_HEAD(&sc_if->sk_jfree_listhead, jpool_entries);
1112		free(entry, M_DEVBUF);
1113	}
1114
1115	SK_JLIST_UNLOCK(sc_if);
1116
1117	mtx_destroy(&sc_if->sk_jlist_mtx);
1118
1119	contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
1120
1121	return;
1122}
1123
1124/*
1125 * Allocate a jumbo buffer.
1126 */
1127static void *
1128sk_jalloc(sc_if)
1129	struct sk_if_softc	*sc_if;
1130{
1131	struct sk_jpool_entry   *entry;
1132
1133	SK_JLIST_LOCK(sc_if);
1134
1135	entry = SLIST_FIRST(&sc_if->sk_jfree_listhead);
1136
1137	if (entry == NULL) {
1138#ifdef SK_VERBOSE
1139		printf("sk%d: no free jumbo buffers\n", sc_if->sk_unit);
1140#endif
1141		SK_JLIST_UNLOCK(sc_if);
1142		return(NULL);
1143	}
1144
1145	SLIST_REMOVE_HEAD(&sc_if->sk_jfree_listhead, jpool_entries);
1146	SLIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead, entry, jpool_entries);
1147
1148	SK_JLIST_UNLOCK(sc_if);
1149
1150	return(sc_if->sk_cdata.sk_jslots[entry->slot]);
1151}
1152
1153/*
1154 * Release a jumbo buffer.
1155 */
1156static void
1157sk_jfree(buf, args)
1158	void			*buf;
1159	void			*args;
1160{
1161	struct sk_if_softc	*sc_if;
1162	int		        i;
1163	struct sk_jpool_entry   *entry;
1164
1165	/* Extract the softc struct pointer. */
1166	sc_if = (struct sk_if_softc *)args;
1167	if (sc_if == NULL)
1168		panic("sk_jfree: didn't get softc pointer!");
1169
1170	SK_JLIST_LOCK(sc_if);
1171
1172	/* calculate the slot this buffer belongs to */
1173	i = ((vm_offset_t)buf
1174	     - (vm_offset_t)sc_if->sk_cdata.sk_jumbo_buf) / SK_JLEN;
1175
1176	if ((i < 0) || (i >= SK_JSLOTS))
1177		panic("sk_jfree: asked to free buffer that we don't manage!");
1178
1179	entry = SLIST_FIRST(&sc_if->sk_jinuse_listhead);
1180	if (entry == NULL)
1181		panic("sk_jfree: buffer not in use!");
1182	entry->slot = i;
1183	SLIST_REMOVE_HEAD(&sc_if->sk_jinuse_listhead, jpool_entries);
1184	SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, jpool_entries);
1185	if (SLIST_EMPTY(&sc_if->sk_jinuse_listhead))
1186		wakeup(sc_if);
1187
1188	SK_JLIST_UNLOCK(sc_if);
1189	return;
1190}
1191
1192/*
1193 * Set media options.
1194 */
1195static int
1196sk_ifmedia_upd(ifp)
1197	struct ifnet		*ifp;
1198{
1199	struct sk_if_softc	*sc_if = ifp->if_softc;
1200	struct mii_data		*mii;
1201
1202	mii = device_get_softc(sc_if->sk_miibus);
1203	sk_init(sc_if);
1204	mii_mediachg(mii);
1205
1206	return(0);
1207}
1208
1209/*
1210 * Report current media status.
1211 */
1212static void
1213sk_ifmedia_sts(ifp, ifmr)
1214	struct ifnet		*ifp;
1215	struct ifmediareq	*ifmr;
1216{
1217	struct sk_if_softc	*sc_if;
1218	struct mii_data		*mii;
1219
1220	sc_if = ifp->if_softc;
1221	mii = device_get_softc(sc_if->sk_miibus);
1222
1223	mii_pollstat(mii);
1224	ifmr->ifm_active = mii->mii_media_active;
1225	ifmr->ifm_status = mii->mii_media_status;
1226
1227	return;
1228}
1229
1230static int
1231sk_ioctl(ifp, command, data)
1232	struct ifnet		*ifp;
1233	u_long			command;
1234	caddr_t			data;
1235{
1236	struct sk_if_softc	*sc_if = ifp->if_softc;
1237	struct ifreq		*ifr = (struct ifreq *) data;
1238	int			error = 0;
1239	struct mii_data		*mii;
1240
1241	switch(command) {
1242	case SIOCSIFMTU:
1243		if (ifr->ifr_mtu > SK_JUMBO_MTU)
1244			error = EINVAL;
1245		else {
1246			ifp->if_mtu = ifr->ifr_mtu;
1247			ifp->if_flags &= ~IFF_RUNNING;
1248			sk_init(sc_if);
1249		}
1250		break;
1251	case SIOCSIFFLAGS:
1252		SK_IF_LOCK(sc_if);
1253		if (ifp->if_flags & IFF_UP) {
1254			if (ifp->if_flags & IFF_RUNNING) {
1255				if ((ifp->if_flags ^ sc_if->sk_if_flags)
1256				    & IFF_PROMISC) {
1257					sk_setpromisc(sc_if);
1258					sk_setmulti(sc_if);
1259				}
1260			} else
1261				sk_init(sc_if);
1262		} else {
1263			if (ifp->if_flags & IFF_RUNNING)
1264				sk_stop(sc_if);
1265		}
1266		sc_if->sk_if_flags = ifp->if_flags;
1267		SK_IF_UNLOCK(sc_if);
1268		error = 0;
1269		break;
1270	case SIOCADDMULTI:
1271	case SIOCDELMULTI:
1272		if (ifp->if_flags & IFF_RUNNING) {
1273			SK_IF_LOCK(sc_if);
1274			sk_setmulti(sc_if);
1275			SK_IF_UNLOCK(sc_if);
1276			error = 0;
1277		}
1278		break;
1279	case SIOCGIFMEDIA:
1280	case SIOCSIFMEDIA:
1281		mii = device_get_softc(sc_if->sk_miibus);
1282		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
1283		break;
1284	default:
1285		error = ether_ioctl(ifp, command, data);
1286		break;
1287	}
1288
1289	return(error);
1290}
1291
1292/*
1293 * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device
1294 * IDs against our list and return a device name if we find a match.
1295 */
1296static int
1297skc_probe(dev)
1298	device_t		dev;
1299{
1300	struct sk_softc		*sc;
1301	struct sk_type		*t = sk_devs;
1302
1303	sc = device_get_softc(dev);
1304
1305	while(t->sk_name != NULL) {
1306		if ((pci_get_vendor(dev) == t->sk_vid) &&
1307		    (pci_get_device(dev) == t->sk_did)) {
1308			device_set_desc(dev, t->sk_name);
1309			return (BUS_PROBE_DEFAULT);
1310		}
1311		t++;
1312	}
1313
1314	return(ENXIO);
1315}
1316
1317/*
1318 * Force the GEnesis into reset, then bring it out of reset.
1319 */
1320static void
1321sk_reset(sc)
1322	struct sk_softc		*sc;
1323{
1324	CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET);
1325	CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET);
1326	if (SK_YUKON_FAMILY(sc->sk_type))
1327		CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
1328
1329	DELAY(1000);
1330	CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET);
1331	DELAY(2);
1332	CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
1333	if (SK_YUKON_FAMILY(sc->sk_type))
1334		CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
1335
1336	if (sc->sk_type == SK_GENESIS) {
1337		/* Configure packet arbiter */
1338		sk_win_write_2(sc, SK_PKTARB_CTL, SK_PKTARBCTL_UNRESET);
1339		sk_win_write_2(sc, SK_RXPA1_TINIT, SK_PKTARB_TIMEOUT);
1340		sk_win_write_2(sc, SK_TXPA1_TINIT, SK_PKTARB_TIMEOUT);
1341		sk_win_write_2(sc, SK_RXPA2_TINIT, SK_PKTARB_TIMEOUT);
1342		sk_win_write_2(sc, SK_TXPA2_TINIT, SK_PKTARB_TIMEOUT);
1343	}
1344
1345	/* Enable RAM interface */
1346	sk_win_write_4(sc, SK_RAMCTL, SK_RAMCTL_UNRESET);
1347
1348	/*
1349         * Configure interrupt moderation. The moderation timer
1350	 * defers interrupts specified in the interrupt moderation
1351	 * timer mask based on the timeout specified in the interrupt
1352	 * moderation timer init register. Each bit in the timer
1353	 * register represents 18.825ns, so to specify a timeout in
1354	 * microseconds, we have to multiply by 54.
1355	 */
1356	printf("skc%d: interrupt moderation is %d us\n",
1357	    sc->sk_unit, sc->sk_int_mod);
1358	sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod));
1359	sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF|
1360	    SK_ISR_RX1_EOF|SK_ISR_RX2_EOF);
1361	sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START);
1362
1363	return;
1364}
1365
1366static int
1367sk_probe(dev)
1368	device_t		dev;
1369{
1370	struct sk_softc		*sc;
1371
1372	sc = device_get_softc(device_get_parent(dev));
1373
1374	/*
1375	 * Not much to do here. We always know there will be
1376	 * at least one XMAC present, and if there are two,
1377	 * skc_attach() will create a second device instance
1378	 * for us.
1379	 */
1380	switch (sc->sk_type) {
1381	case SK_GENESIS:
1382		device_set_desc(dev, "XaQti Corp. XMAC II");
1383		break;
1384	case SK_YUKON:
1385	case SK_YUKON_LITE:
1386	case SK_YUKON_LP:
1387		device_set_desc(dev, "Marvell Semiconductor, Inc. Yukon");
1388		break;
1389	}
1390
1391	return (BUS_PROBE_DEFAULT);
1392}
1393
1394/*
1395 * Each XMAC chip is attached as a separate logical IP interface.
1396 * Single port cards will have only one logical interface of course.
1397 */
1398static int
1399sk_attach(dev)
1400	device_t		dev;
1401{
1402	struct sk_softc		*sc;
1403	struct sk_if_softc	*sc_if;
1404	struct ifnet		*ifp;
1405	int			i, port, error;
1406	u_char			eaddr[6];
1407
1408	if (dev == NULL)
1409		return(EINVAL);
1410
1411	error = 0;
1412	sc_if = device_get_softc(dev);
1413	sc = device_get_softc(device_get_parent(dev));
1414	port = *(int *)device_get_ivars(dev);
1415
1416	sc_if->sk_dev = dev;
1417	sc_if->sk_unit = device_get_unit(dev);
1418	sc_if->sk_port = port;
1419	sc_if->sk_softc = sc;
1420	sc->sk_if[port] = sc_if;
1421	if (port == SK_PORT_A)
1422		sc_if->sk_tx_bmu = SK_BMU_TXS_CSR0;
1423	if (port == SK_PORT_B)
1424		sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1;
1425
1426	/* Allocate the descriptor queues. */
1427	sc_if->sk_rdata = contigmalloc(sizeof(struct sk_ring_data), M_DEVBUF,
1428	    M_NOWAIT, M_ZERO, 0xffffffff, PAGE_SIZE, 0);
1429
1430	if (sc_if->sk_rdata == NULL) {
1431		printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
1432		error = ENOMEM;
1433		goto fail;
1434	}
1435
1436	/* Try to allocate memory for jumbo buffers. */
1437	if (sk_alloc_jumbo_mem(sc_if)) {
1438		printf("sk%d: jumbo buffer allocation failed\n",
1439		    sc_if->sk_unit);
1440		error = ENOMEM;
1441		goto fail;
1442	}
1443
1444	ifp = sc_if->sk_ifp = if_alloc(IFT_ETHER);
1445	if (ifp == NULL) {
1446		printf("sk%d: can not if_alloc()\n", sc_if->sk_unit);
1447		error = ENOSPC;
1448		goto fail;
1449	}
1450	ifp->if_softc = sc_if;
1451	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1452	ifp->if_mtu = ETHERMTU;
1453	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1454	ifp->if_ioctl = sk_ioctl;
1455	ifp->if_start = sk_start;
1456	ifp->if_watchdog = sk_watchdog;
1457	ifp->if_init = sk_init;
1458	ifp->if_baudrate = 1000000000;
1459	IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1);
1460	ifp->if_snd.ifq_drv_maxlen = SK_TX_RING_CNT - 1;
1461	IFQ_SET_READY(&ifp->if_snd);
1462
1463	callout_handle_init(&sc_if->sk_tick_ch);
1464
1465	/*
1466	 * Get station address for this interface. Note that
1467	 * dual port cards actually come with three station
1468	 * addresses: one for each port, plus an extra. The
1469	 * extra one is used by the SysKonnect driver software
1470	 * as a 'virtual' station address for when both ports
1471	 * are operating in failover mode. Currently we don't
1472	 * use this extra address.
1473	 */
1474	SK_LOCK(sc);
1475	for (i = 0; i < ETHER_ADDR_LEN; i++)
1476		eaddr[i] =
1477		    sk_win_read_1(sc, SK_MAC0_0 + (port * 8) + i);
1478
1479	/*
1480	 * Set up RAM buffer addresses. The NIC will have a certain
1481	 * amount of SRAM on it, somewhere between 512K and 2MB. We
1482	 * need to divide this up a) between the transmitter and
1483 	 * receiver and b) between the two XMACs, if this is a
1484	 * dual port NIC. Our algotithm is to divide up the memory
1485	 * evenly so that everyone gets a fair share.
1486	 */
1487	if (sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC) {
1488		u_int32_t		chunk, val;
1489
1490		chunk = sc->sk_ramsize / 2;
1491		val = sc->sk_rboff / sizeof(u_int64_t);
1492		sc_if->sk_rx_ramstart = val;
1493		val += (chunk / sizeof(u_int64_t));
1494		sc_if->sk_rx_ramend = val - 1;
1495		sc_if->sk_tx_ramstart = val;
1496		val += (chunk / sizeof(u_int64_t));
1497		sc_if->sk_tx_ramend = val - 1;
1498	} else {
1499		u_int32_t		chunk, val;
1500
1501		chunk = sc->sk_ramsize / 4;
1502		val = (sc->sk_rboff + (chunk * 2 * sc_if->sk_port)) /
1503		    sizeof(u_int64_t);
1504		sc_if->sk_rx_ramstart = val;
1505		val += (chunk / sizeof(u_int64_t));
1506		sc_if->sk_rx_ramend = val - 1;
1507		sc_if->sk_tx_ramstart = val;
1508		val += (chunk / sizeof(u_int64_t));
1509		sc_if->sk_tx_ramend = val - 1;
1510	}
1511
1512	/* Read and save PHY type and set PHY address */
1513	sc_if->sk_phytype = sk_win_read_1(sc, SK_EPROM1) & 0xF;
1514	switch(sc_if->sk_phytype) {
1515	case SK_PHYTYPE_XMAC:
1516		sc_if->sk_phyaddr = SK_PHYADDR_XMAC;
1517		break;
1518	case SK_PHYTYPE_BCOM:
1519		sc_if->sk_phyaddr = SK_PHYADDR_BCOM;
1520		break;
1521	case SK_PHYTYPE_MARV_COPPER:
1522		sc_if->sk_phyaddr = SK_PHYADDR_MARV;
1523		break;
1524	default:
1525		printf("skc%d: unsupported PHY type: %d\n",
1526		    sc->sk_unit, sc_if->sk_phytype);
1527		error = ENODEV;
1528		SK_UNLOCK(sc);
1529		if_free(ifp);
1530		goto fail;
1531	}
1532
1533
1534	/*
1535	 * Call MI attach routine.  Can't hold locks when calling into ether_*.
1536	 */
1537	SK_UNLOCK(sc);
1538	ether_ifattach(ifp, eaddr);
1539	SK_LOCK(sc);
1540
1541	/*
1542	 * Do miibus setup.
1543	 */
1544	switch (sc->sk_type) {
1545	case SK_GENESIS:
1546		sk_init_xmac(sc_if);
1547		break;
1548	case SK_YUKON:
1549	case SK_YUKON_LITE:
1550	case SK_YUKON_LP:
1551		sk_init_yukon(sc_if);
1552		break;
1553	}
1554
1555	SK_UNLOCK(sc);
1556	if (mii_phy_probe(dev, &sc_if->sk_miibus,
1557	    sk_ifmedia_upd, sk_ifmedia_sts)) {
1558		printf("skc%d: no PHY found!\n", sc_if->sk_unit);
1559		ether_ifdetach(ifp);
1560		if_free(ifp);
1561		error = ENXIO;
1562		goto fail;
1563	}
1564
1565fail:
1566	if (error) {
1567		/* Access should be ok even though lock has been dropped */
1568		sc->sk_if[port] = NULL;
1569		sk_detach(dev);
1570	}
1571
1572	return(error);
1573}
1574
1575/*
1576 * Attach the interface. Allocate softc structures, do ifmedia
1577 * setup and ethernet/BPF attach.
1578 */
1579static int
1580skc_attach(dev)
1581	device_t		dev;
1582{
1583	struct sk_softc		*sc;
1584	int			unit, error = 0, rid, *port;
1585	uint8_t			skrs;
1586	char			*pname, *revstr;
1587
1588	sc = device_get_softc(dev);
1589	unit = device_get_unit(dev);
1590
1591	mtx_init(&sc->sk_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
1592	    MTX_DEF | MTX_RECURSE);
1593	/*
1594	 * Map control/status registers.
1595	 */
1596	pci_enable_busmaster(dev);
1597
1598	rid = SK_RID;
1599	sc->sk_res = bus_alloc_resource_any(dev, SK_RES, &rid, RF_ACTIVE);
1600
1601	if (sc->sk_res == NULL) {
1602		printf("sk%d: couldn't map ports/memory\n", unit);
1603		error = ENXIO;
1604		goto fail;
1605	}
1606
1607	sc->sk_btag = rman_get_bustag(sc->sk_res);
1608	sc->sk_bhandle = rman_get_bushandle(sc->sk_res);
1609
1610	sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
1611	sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4) & 0xf;
1612
1613	/* Bail out if chip is not recognized. */
1614	if (sc->sk_type != SK_GENESIS && !SK_YUKON_FAMILY(sc->sk_type)) {
1615		printf("skc%d: unknown device: chipver=%02x, rev=%x\n",
1616			unit, sc->sk_type, sc->sk_rev);
1617		error = ENXIO;
1618		goto fail;
1619	}
1620
1621	/* Allocate interrupt */
1622	rid = 0;
1623	sc->sk_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
1624	    RF_SHAREABLE | RF_ACTIVE);
1625
1626	if (sc->sk_irq == NULL) {
1627		printf("skc%d: couldn't map interrupt\n", unit);
1628		error = ENXIO;
1629		goto fail;
1630	}
1631
1632	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1633		SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
1634		OID_AUTO, "int_mod", CTLTYPE_INT|CTLFLAG_RW,
1635		&sc->sk_int_mod, 0, sysctl_hw_sk_int_mod, "I",
1636		"SK interrupt moderation");
1637
1638	/* Pull in device tunables. */
1639	sc->sk_int_mod = SK_IM_DEFAULT;
1640	error = resource_int_value(device_get_name(dev), unit,
1641		"int_mod", &sc->sk_int_mod);
1642	if (error == 0) {
1643		if (sc->sk_int_mod < SK_IM_MIN ||
1644		    sc->sk_int_mod > SK_IM_MAX) {
1645			printf("skc%d: int_mod value out of range; "
1646			    "using default: %d\n", unit, SK_IM_DEFAULT);
1647			sc->sk_int_mod = SK_IM_DEFAULT;
1648		}
1649	}
1650
1651	/* Reset the adapter. */
1652	sk_reset(sc);
1653
1654	sc->sk_unit = unit;
1655
1656	/* Read and save vital product data from EEPROM. */
1657	sk_vpd_read(sc);
1658
1659	skrs = sk_win_read_1(sc, SK_EPROM0);
1660	if (sc->sk_type == SK_GENESIS) {
1661		/* Read and save RAM size and RAMbuffer offset */
1662		switch(skrs) {
1663		case SK_RAMSIZE_512K_64:
1664			sc->sk_ramsize = 0x80000;
1665			sc->sk_rboff = SK_RBOFF_0;
1666			break;
1667		case SK_RAMSIZE_1024K_64:
1668			sc->sk_ramsize = 0x100000;
1669			sc->sk_rboff = SK_RBOFF_80000;
1670			break;
1671		case SK_RAMSIZE_1024K_128:
1672			sc->sk_ramsize = 0x100000;
1673			sc->sk_rboff = SK_RBOFF_0;
1674			break;
1675		case SK_RAMSIZE_2048K_128:
1676			sc->sk_ramsize = 0x200000;
1677			sc->sk_rboff = SK_RBOFF_0;
1678			break;
1679		default:
1680			printf("skc%d: unknown ram size: %d\n",
1681			    sc->sk_unit, sk_win_read_1(sc, SK_EPROM0));
1682			error = ENXIO;
1683			goto fail;
1684		}
1685	} else { /* SK_YUKON_FAMILY */
1686		if (skrs == 0x00)
1687			sc->sk_ramsize = 0x20000;
1688		else
1689			sc->sk_ramsize = skrs * (1<<12);
1690		sc->sk_rboff = SK_RBOFF_0;
1691	}
1692
1693	/* Read and save physical media type */
1694	switch(sk_win_read_1(sc, SK_PMDTYPE)) {
1695	case SK_PMD_1000BASESX:
1696		sc->sk_pmd = IFM_1000_SX;
1697		break;
1698	case SK_PMD_1000BASELX:
1699		sc->sk_pmd = IFM_1000_LX;
1700		break;
1701	case SK_PMD_1000BASECX:
1702		sc->sk_pmd = IFM_1000_CX;
1703		break;
1704	case SK_PMD_1000BASETX:
1705		sc->sk_pmd = IFM_1000_T;
1706		break;
1707	default:
1708		printf("skc%d: unknown media type: 0x%x\n",
1709		    sc->sk_unit, sk_win_read_1(sc, SK_PMDTYPE));
1710		error = ENXIO;
1711		goto fail;
1712	}
1713
1714	/* Determine whether to name it with VPD PN or just make it up.
1715	 * Marvell Yukon VPD PN seems to freqently be bogus. */
1716	switch (pci_get_device(dev)) {
1717	case DEVICEID_SK_V1:
1718	case DEVICEID_BELKIN_5005:
1719	case DEVICEID_3COM_3C940:
1720	case DEVICEID_LINKSYS_EG1032:
1721	case DEVICEID_DLINK_DGE530T:
1722		/* Stay with VPD PN. */
1723		pname = sc->sk_vpd_prodname;
1724		break;
1725	case DEVICEID_SK_V2:
1726		/* YUKON VPD PN might bear no resemblance to reality. */
1727		switch (sc->sk_type) {
1728		case SK_GENESIS:
1729			/* Stay with VPD PN. */
1730			pname = sc->sk_vpd_prodname;
1731			break;
1732		case SK_YUKON:
1733			pname = "Marvell Yukon Gigabit Ethernet";
1734			break;
1735		case SK_YUKON_LITE:
1736			pname = "Marvell Yukon Lite Gigabit Ethernet";
1737			break;
1738		case SK_YUKON_LP:
1739			pname = "Marvell Yukon LP Gigabit Ethernet";
1740			break;
1741		default:
1742			pname = "Marvell Yukon (Unknown) Gigabit Ethernet";
1743			break;
1744		}
1745
1746		/* Yukon Lite Rev. A0 needs special test. */
1747		if (sc->sk_type == SK_YUKON || sc->sk_type == SK_YUKON_LP) {
1748			u_int32_t far;
1749			u_int8_t testbyte;
1750
1751			/* Save flash address register before testing. */
1752			far = sk_win_read_4(sc, SK_EP_ADDR);
1753
1754			sk_win_write_1(sc, SK_EP_ADDR+0x03, 0xff);
1755			testbyte = sk_win_read_1(sc, SK_EP_ADDR+0x03);
1756
1757			if (testbyte != 0x00) {
1758				/* Yukon Lite Rev. A0 detected. */
1759				sc->sk_type = SK_YUKON_LITE;
1760				sc->sk_rev = SK_YUKON_LITE_REV_A0;
1761				/* Restore flash address register. */
1762				sk_win_write_4(sc, SK_EP_ADDR, far);
1763			}
1764		}
1765		break;
1766	default:
1767		device_printf(dev, "unknown device: vendor=%04x, device=%04x, "
1768			"chipver=%02x, rev=%x\n",
1769			pci_get_vendor(dev), pci_get_device(dev),
1770			sc->sk_type, sc->sk_rev);
1771		error = ENXIO;
1772		goto fail;
1773	}
1774
1775	if (sc->sk_type == SK_YUKON_LITE) {
1776		switch (sc->sk_rev) {
1777		case SK_YUKON_LITE_REV_A0:
1778			revstr = "A0";
1779			break;
1780		case SK_YUKON_LITE_REV_A1:
1781			revstr = "A1";
1782			break;
1783		case SK_YUKON_LITE_REV_A3:
1784			revstr = "A3";
1785			break;
1786		default:
1787			revstr = "";
1788			break;
1789		}
1790	} else {
1791		revstr = "";
1792	}
1793
1794	/* Announce the product name and more VPD data if there. */
1795	device_printf(dev, "%s rev. %s(0x%x)\n",
1796		pname != NULL ? pname : "<unknown>", revstr, sc->sk_rev);
1797
1798	if (bootverbose) {
1799		if (sc->sk_vpd_readonly != NULL &&
1800		    sc->sk_vpd_readonly_len != 0) {
1801			char buf[256];
1802			char *dp = sc->sk_vpd_readonly;
1803			uint16_t l, len = sc->sk_vpd_readonly_len;
1804
1805			while (len >= 3) {
1806				if ((*dp == 'P' && *(dp+1) == 'N') ||
1807				    (*dp == 'E' && *(dp+1) == 'C') ||
1808				    (*dp == 'M' && *(dp+1) == 'N') ||
1809				    (*dp == 'S' && *(dp+1) == 'N')) {
1810					l = 0;
1811					while (l < *(dp+2)) {
1812						buf[l] = *(dp+3+l);
1813						++l;
1814					}
1815					buf[l] = '\0';
1816					device_printf(dev, "%c%c: %s\n",
1817					    *dp, *(dp+1), buf);
1818					len -= (3 + l);
1819					dp += (3 + l);
1820				} else {
1821					len -= (3 + *(dp+2));
1822					dp += (3 + *(dp+2));
1823				}
1824			}
1825		}
1826		device_printf(dev, "chip ver  = 0x%02x\n", sc->sk_type);
1827		device_printf(dev, "chip rev  = 0x%02x\n", sc->sk_rev);
1828		device_printf(dev, "SK_EPROM0 = 0x%02x\n", skrs);
1829		device_printf(dev, "SRAM size = 0x%06x\n", sc->sk_ramsize);
1830	}
1831
1832	sc->sk_devs[SK_PORT_A] = device_add_child(dev, "sk", -1);
1833	if (sc->sk_devs[SK_PORT_A] == NULL) {
1834		device_printf(dev, "failed to add child for PORT_A\n");
1835		error = ENXIO;
1836		goto fail;
1837	}
1838	port = malloc(sizeof(int), M_DEVBUF, M_NOWAIT);
1839	if (port == NULL) {
1840		device_printf(dev, "failed to allocate memory for "
1841		    "ivars of PORT_A\n");
1842		error = ENXIO;
1843		goto fail;
1844	}
1845	*port = SK_PORT_A;
1846	device_set_ivars(sc->sk_devs[SK_PORT_A], port);
1847
1848	if (!(sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC)) {
1849		sc->sk_devs[SK_PORT_B] = device_add_child(dev, "sk", -1);
1850		if (sc->sk_devs[SK_PORT_B] == NULL) {
1851			device_printf(dev, "failed to add child for PORT_B\n");
1852			error = ENXIO;
1853			goto fail;
1854		}
1855		port = malloc(sizeof(int), M_DEVBUF, M_NOWAIT);
1856		if (port == NULL) {
1857			device_printf(dev, "failed to allocate memory for "
1858			    "ivars of PORT_B\n");
1859			error = ENXIO;
1860			goto fail;
1861		}
1862		*port = SK_PORT_B;
1863		device_set_ivars(sc->sk_devs[SK_PORT_B], port);
1864	}
1865
1866	/* Turn on the 'driver is loaded' LED. */
1867	CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
1868
1869	bus_generic_attach(dev);
1870
1871	/* Hook interrupt last to avoid having to lock softc */
1872	error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET|INTR_MPSAFE,
1873	    sk_intr, sc, &sc->sk_intrhand);
1874
1875	if (error) {
1876		printf("skc%d: couldn't set up irq\n", unit);
1877		goto fail;
1878	}
1879
1880fail:
1881	if (error)
1882		skc_detach(dev);
1883
1884	return(error);
1885}
1886
1887/*
1888 * Shutdown hardware and free up resources. This can be called any
1889 * time after the mutex has been initialized. It is called in both
1890 * the error case in attach and the normal detach case so it needs
1891 * to be careful about only freeing resources that have actually been
1892 * allocated.
1893 */
1894static int
1895sk_detach(dev)
1896	device_t		dev;
1897{
1898	struct sk_if_softc	*sc_if;
1899	struct ifnet		*ifp;
1900
1901	sc_if = device_get_softc(dev);
1902	KASSERT(mtx_initialized(&sc_if->sk_softc->sk_mtx),
1903	    ("sk mutex not initialized in sk_detach"));
1904	SK_IF_LOCK(sc_if);
1905
1906	ifp = sc_if->sk_ifp;
1907	/* These should only be active if attach_xmac succeeded */
1908	if (device_is_attached(dev)) {
1909		sk_stop(sc_if);
1910		/* Can't hold locks while calling detach */
1911		SK_IF_UNLOCK(sc_if);
1912		ether_ifdetach(ifp);
1913		if_free(ifp);
1914		SK_IF_LOCK(sc_if);
1915	}
1916	/*
1917	 * We're generally called from skc_detach() which is using
1918	 * device_delete_child() to get to here. It's already trashed
1919	 * miibus for us, so don't do it here or we'll panic.
1920	 */
1921	/*
1922	if (sc_if->sk_miibus != NULL)
1923		device_delete_child(dev, sc_if->sk_miibus);
1924	*/
1925	bus_generic_detach(dev);
1926	if (sc_if->sk_cdata.sk_jumbo_buf != NULL)
1927		sk_free_jumbo_mem(sc_if);
1928	if (sc_if->sk_rdata != NULL) {
1929		contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data),
1930		    M_DEVBUF);
1931	}
1932	SK_IF_UNLOCK(sc_if);
1933
1934	return(0);
1935}
1936
1937static int
1938skc_detach(dev)
1939	device_t		dev;
1940{
1941	struct sk_softc		*sc;
1942
1943	sc = device_get_softc(dev);
1944	KASSERT(mtx_initialized(&sc->sk_mtx), ("sk mutex not initialized"));
1945
1946	if (device_is_alive(dev)) {
1947		if (sc->sk_devs[SK_PORT_A] != NULL) {
1948			free(device_get_ivars(sc->sk_devs[SK_PORT_A]), M_DEVBUF);
1949			device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
1950		}
1951		if (sc->sk_devs[SK_PORT_B] != NULL) {
1952			free(device_get_ivars(sc->sk_devs[SK_PORT_B]), M_DEVBUF);
1953			device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
1954		}
1955		bus_generic_detach(dev);
1956	}
1957
1958	if (sc->sk_vpd_prodname != NULL)
1959		free(sc->sk_vpd_prodname, M_DEVBUF);
1960	if (sc->sk_vpd_readonly != NULL)
1961		free(sc->sk_vpd_readonly, M_DEVBUF);
1962
1963	if (sc->sk_intrhand)
1964		bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
1965	if (sc->sk_irq)
1966		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
1967	if (sc->sk_res)
1968		bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
1969
1970	mtx_destroy(&sc->sk_mtx);
1971
1972	return(0);
1973}
1974
1975static int
1976sk_encap(sc_if, m_head, txidx)
1977        struct sk_if_softc	*sc_if;
1978        struct mbuf		*m_head;
1979        u_int32_t		*txidx;
1980{
1981	struct sk_tx_desc	*f = NULL;
1982	struct mbuf		*m;
1983	u_int32_t		frag, cur, cnt = 0;
1984
1985	SK_IF_LOCK_ASSERT(sc_if);
1986
1987	m = m_head;
1988	cur = frag = *txidx;
1989
1990	/*
1991	 * Start packing the mbufs in this chain into
1992	 * the fragment pointers. Stop when we run out
1993	 * of fragments or hit the end of the mbuf chain.
1994	 */
1995	for (m = m_head; m != NULL; m = m->m_next) {
1996		if (m->m_len != 0) {
1997			if ((SK_TX_RING_CNT -
1998			    (sc_if->sk_cdata.sk_tx_cnt + cnt)) < 2)
1999				return(ENOBUFS);
2000			f = &sc_if->sk_rdata->sk_tx_ring[frag];
2001			f->sk_data_lo = vtophys(mtod(m, vm_offset_t));
2002			f->sk_ctl = m->m_len | SK_OPCODE_DEFAULT;
2003			if (cnt == 0)
2004				f->sk_ctl |= SK_TXCTL_FIRSTFRAG;
2005			else
2006				f->sk_ctl |= SK_TXCTL_OWN;
2007			cur = frag;
2008			SK_INC(frag, SK_TX_RING_CNT);
2009			cnt++;
2010		}
2011	}
2012
2013	if (m != NULL)
2014		return(ENOBUFS);
2015
2016	sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |=
2017		SK_TXCTL_LASTFRAG|SK_TXCTL_EOF_INTR;
2018	sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head;
2019	sc_if->sk_rdata->sk_tx_ring[*txidx].sk_ctl |= SK_TXCTL_OWN;
2020	sc_if->sk_cdata.sk_tx_cnt += cnt;
2021
2022	*txidx = frag;
2023
2024	return(0);
2025}
2026
2027static void
2028sk_start(ifp)
2029	struct ifnet		*ifp;
2030{
2031        struct sk_softc		*sc;
2032        struct sk_if_softc	*sc_if;
2033        struct mbuf		*m_head = NULL;
2034        u_int32_t		idx;
2035
2036	sc_if = ifp->if_softc;
2037	sc = sc_if->sk_softc;
2038
2039	SK_IF_LOCK(sc_if);
2040
2041	idx = sc_if->sk_cdata.sk_tx_prod;
2042
2043	while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
2044		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
2045		if (m_head == NULL)
2046			break;
2047
2048		/*
2049		 * Pack the data into the transmit ring. If we
2050		 * don't have room, set the OACTIVE flag and wait
2051		 * for the NIC to drain the ring.
2052		 */
2053		if (sk_encap(sc_if, m_head, &idx)) {
2054			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
2055			ifp->if_flags |= IFF_OACTIVE;
2056			break;
2057		}
2058
2059		/*
2060		 * If there's a BPF listener, bounce a copy of this frame
2061		 * to him.
2062		 */
2063		BPF_MTAP(ifp, m_head);
2064	}
2065
2066	/* Transmit */
2067	if (idx != sc_if->sk_cdata.sk_tx_prod) {
2068		sc_if->sk_cdata.sk_tx_prod = idx;
2069		CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
2070
2071		/* Set a timeout in case the chip goes out to lunch. */
2072		ifp->if_timer = 5;
2073	}
2074	SK_IF_UNLOCK(sc_if);
2075
2076	return;
2077}
2078
2079
2080static void
2081sk_watchdog(ifp)
2082	struct ifnet		*ifp;
2083{
2084	struct sk_if_softc	*sc_if;
2085
2086	sc_if = ifp->if_softc;
2087
2088	printf("sk%d: watchdog timeout\n", sc_if->sk_unit);
2089	ifp->if_flags &= ~IFF_RUNNING;
2090	sk_init(sc_if);
2091
2092	return;
2093}
2094
2095static void
2096skc_shutdown(dev)
2097	device_t		dev;
2098{
2099	struct sk_softc		*sc;
2100
2101	sc = device_get_softc(dev);
2102	SK_LOCK(sc);
2103
2104	/* Turn off the 'driver is loaded' LED. */
2105	CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF);
2106
2107	/*
2108	 * Reset the GEnesis controller. Doing this should also
2109	 * assert the resets on the attached XMAC(s).
2110	 */
2111	sk_reset(sc);
2112	SK_UNLOCK(sc);
2113
2114	return;
2115}
2116
2117static void
2118sk_rxeof(sc_if)
2119	struct sk_if_softc	*sc_if;
2120{
2121	struct sk_softc		*sc;
2122	struct mbuf		*m;
2123	struct ifnet		*ifp;
2124	struct sk_chain		*cur_rx;
2125	int			total_len = 0;
2126	int			i;
2127	u_int32_t		rxstat;
2128
2129	sc = sc_if->sk_softc;
2130	ifp = sc_if->sk_ifp;
2131	i = sc_if->sk_cdata.sk_rx_prod;
2132	cur_rx = &sc_if->sk_cdata.sk_rx_chain[i];
2133
2134	SK_LOCK_ASSERT(sc);
2135
2136	while(!(sc_if->sk_rdata->sk_rx_ring[i].sk_ctl & SK_RXCTL_OWN)) {
2137
2138		cur_rx = &sc_if->sk_cdata.sk_rx_chain[i];
2139		rxstat = sc_if->sk_rdata->sk_rx_ring[i].sk_xmac_rxstat;
2140		m = cur_rx->sk_mbuf;
2141		cur_rx->sk_mbuf = NULL;
2142		total_len = SK_RXBYTES(sc_if->sk_rdata->sk_rx_ring[i].sk_ctl);
2143		SK_INC(i, SK_RX_RING_CNT);
2144
2145		if (rxstat & XM_RXSTAT_ERRFRAME) {
2146			ifp->if_ierrors++;
2147			sk_newbuf(sc_if, cur_rx, m);
2148			continue;
2149		}
2150
2151		/*
2152		 * Try to allocate a new jumbo buffer. If that
2153		 * fails, copy the packet to mbufs and put the
2154		 * jumbo buffer back in the ring so it can be
2155		 * re-used. If allocating mbufs fails, then we
2156		 * have to drop the packet.
2157		 */
2158		if (sk_newbuf(sc_if, cur_rx, NULL) == ENOBUFS) {
2159			struct mbuf		*m0;
2160			m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN,
2161			    ifp, NULL);
2162			sk_newbuf(sc_if, cur_rx, m);
2163			if (m0 == NULL) {
2164				printf("sk%d: no receive buffers "
2165				    "available -- packet dropped!\n",
2166				    sc_if->sk_unit);
2167				ifp->if_ierrors++;
2168				continue;
2169			}
2170			m = m0;
2171		} else {
2172			m->m_pkthdr.rcvif = ifp;
2173			m->m_pkthdr.len = m->m_len = total_len;
2174		}
2175
2176		ifp->if_ipackets++;
2177		SK_UNLOCK(sc);
2178		(*ifp->if_input)(ifp, m);
2179		SK_LOCK(sc);
2180	}
2181
2182	sc_if->sk_cdata.sk_rx_prod = i;
2183
2184	return;
2185}
2186
2187static void
2188sk_txeof(sc_if)
2189	struct sk_if_softc	*sc_if;
2190{
2191	struct sk_softc		*sc;
2192	struct sk_tx_desc	*cur_tx;
2193	struct ifnet		*ifp;
2194	u_int32_t		idx;
2195
2196	sc = sc_if->sk_softc;
2197	ifp = sc_if->sk_ifp;
2198
2199	/*
2200	 * Go through our tx ring and free mbufs for those
2201	 * frames that have been sent.
2202	 */
2203	idx = sc_if->sk_cdata.sk_tx_cons;
2204	while(idx != sc_if->sk_cdata.sk_tx_prod) {
2205		cur_tx = &sc_if->sk_rdata->sk_tx_ring[idx];
2206		if (cur_tx->sk_ctl & SK_TXCTL_OWN)
2207			break;
2208		if (cur_tx->sk_ctl & SK_TXCTL_LASTFRAG)
2209			ifp->if_opackets++;
2210		if (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf != NULL) {
2211			m_freem(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf);
2212			sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf = NULL;
2213		}
2214		sc_if->sk_cdata.sk_tx_cnt--;
2215		SK_INC(idx, SK_TX_RING_CNT);
2216	}
2217
2218	if (sc_if->sk_cdata.sk_tx_cnt == 0) {
2219		ifp->if_timer = 0;
2220	} else /* nudge chip to keep tx ring moving */
2221		CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
2222
2223	if (sc_if->sk_cdata.sk_tx_cnt < SK_TX_RING_CNT - 2)
2224		ifp->if_flags &= ~IFF_OACTIVE;
2225
2226	sc_if->sk_cdata.sk_tx_cons = idx;
2227}
2228
2229static void
2230sk_tick(xsc_if)
2231	void			*xsc_if;
2232{
2233	struct sk_if_softc	*sc_if;
2234	struct mii_data		*mii;
2235	struct ifnet		*ifp;
2236	int			i;
2237
2238	sc_if = xsc_if;
2239	SK_IF_LOCK(sc_if);
2240	ifp = sc_if->sk_ifp;
2241	mii = device_get_softc(sc_if->sk_miibus);
2242
2243	if (!(ifp->if_flags & IFF_UP)) {
2244		SK_IF_UNLOCK(sc_if);
2245		return;
2246	}
2247
2248	if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
2249		sk_intr_bcom(sc_if);
2250		SK_IF_UNLOCK(sc_if);
2251		return;
2252	}
2253
2254	/*
2255	 * According to SysKonnect, the correct way to verify that
2256	 * the link has come back up is to poll bit 0 of the GPIO
2257	 * register three times. This pin has the signal from the
2258	 * link_sync pin connected to it; if we read the same link
2259	 * state 3 times in a row, we know the link is up.
2260	 */
2261	for (i = 0; i < 3; i++) {
2262		if (SK_XM_READ_2(sc_if, XM_GPIO) & XM_GPIO_GP0_SET)
2263			break;
2264	}
2265
2266	if (i != 3) {
2267		sc_if->sk_tick_ch = timeout(sk_tick, sc_if, hz);
2268		SK_IF_UNLOCK(sc_if);
2269		return;
2270	}
2271
2272	/* Turn the GP0 interrupt back on. */
2273	SK_XM_CLRBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET);
2274	SK_XM_READ_2(sc_if, XM_ISR);
2275	mii_tick(mii);
2276	untimeout(sk_tick, sc_if, sc_if->sk_tick_ch);
2277
2278	SK_IF_UNLOCK(sc_if);
2279	return;
2280}
2281
2282static void
2283sk_intr_bcom(sc_if)
2284	struct sk_if_softc	*sc_if;
2285{
2286	struct mii_data		*mii;
2287	struct ifnet		*ifp;
2288	int			status;
2289	mii = device_get_softc(sc_if->sk_miibus);
2290	ifp = sc_if->sk_ifp;
2291
2292	SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
2293
2294	/*
2295	 * Read the PHY interrupt register to make sure
2296	 * we clear any pending interrupts.
2297	 */
2298	status = sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, BRGPHY_MII_ISR);
2299
2300	if (!(ifp->if_flags & IFF_RUNNING)) {
2301		sk_init_xmac(sc_if);
2302		return;
2303	}
2304
2305	if (status & (BRGPHY_ISR_LNK_CHG|BRGPHY_ISR_AN_PR)) {
2306		int			lstat;
2307		lstat = sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM,
2308		    BRGPHY_MII_AUXSTS);
2309
2310		if (!(lstat & BRGPHY_AUXSTS_LINK) && sc_if->sk_link) {
2311			mii_mediachg(mii);
2312			/* Turn off the link LED. */
2313			SK_IF_WRITE_1(sc_if, 0,
2314			    SK_LINKLED1_CTL, SK_LINKLED_OFF);
2315			sc_if->sk_link = 0;
2316		} else if (status & BRGPHY_ISR_LNK_CHG) {
2317			sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM,
2318	    		    BRGPHY_MII_IMR, 0xFF00);
2319			mii_tick(mii);
2320			sc_if->sk_link = 1;
2321			/* Turn on the link LED. */
2322			SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL,
2323			    SK_LINKLED_ON|SK_LINKLED_LINKSYNC_OFF|
2324			    SK_LINKLED_BLINK_OFF);
2325		} else {
2326			mii_tick(mii);
2327			sc_if->sk_tick_ch = timeout(sk_tick, sc_if, hz);
2328		}
2329	}
2330
2331	SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
2332
2333	return;
2334}
2335
2336static void
2337sk_intr_xmac(sc_if)
2338	struct sk_if_softc	*sc_if;
2339{
2340	struct sk_softc		*sc;
2341	u_int16_t		status;
2342
2343	sc = sc_if->sk_softc;
2344	status = SK_XM_READ_2(sc_if, XM_ISR);
2345
2346	/*
2347	 * Link has gone down. Start MII tick timeout to
2348	 * watch for link resync.
2349	 */
2350	if (sc_if->sk_phytype == SK_PHYTYPE_XMAC) {
2351		if (status & XM_ISR_GP0_SET) {
2352			SK_XM_SETBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET);
2353			sc_if->sk_tick_ch = timeout(sk_tick, sc_if, hz);
2354		}
2355
2356		if (status & XM_ISR_AUTONEG_DONE) {
2357			sc_if->sk_tick_ch = timeout(sk_tick, sc_if, hz);
2358		}
2359	}
2360
2361	if (status & XM_IMR_TX_UNDERRUN)
2362		SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_TXFIFO);
2363
2364	if (status & XM_IMR_RX_OVERRUN)
2365		SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_RXFIFO);
2366
2367	status = SK_XM_READ_2(sc_if, XM_ISR);
2368
2369	return;
2370}
2371
2372static void
2373sk_intr_yukon(sc_if)
2374	struct sk_if_softc	*sc_if;
2375{
2376	int status;
2377
2378	status = SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR);
2379
2380	return;
2381}
2382
2383static void
2384sk_intr(xsc)
2385	void			*xsc;
2386{
2387	struct sk_softc		*sc = xsc;
2388	struct sk_if_softc	*sc_if0 = NULL, *sc_if1 = NULL;
2389	struct ifnet		*ifp0 = NULL, *ifp1 = NULL;
2390	u_int32_t		status;
2391
2392	SK_LOCK(sc);
2393
2394	sc_if0 = sc->sk_if[SK_PORT_A];
2395	sc_if1 = sc->sk_if[SK_PORT_B];
2396
2397	if (sc_if0 != NULL)
2398		ifp0 = sc_if0->sk_ifp;
2399	if (sc_if1 != NULL)
2400		ifp1 = sc_if1->sk_ifp;
2401
2402	for (;;) {
2403		status = CSR_READ_4(sc, SK_ISSR);
2404		if (!(status & sc->sk_intrmask))
2405			break;
2406
2407		/* Handle receive interrupts first. */
2408		if (status & SK_ISR_RX1_EOF) {
2409			sk_rxeof(sc_if0);
2410			CSR_WRITE_4(sc, SK_BMU_RX_CSR0,
2411			    SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START);
2412		}
2413		if (status & SK_ISR_RX2_EOF) {
2414			sk_rxeof(sc_if1);
2415			CSR_WRITE_4(sc, SK_BMU_RX_CSR1,
2416			    SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START);
2417		}
2418
2419		/* Then transmit interrupts. */
2420		if (status & SK_ISR_TX1_S_EOF) {
2421			sk_txeof(sc_if0);
2422			CSR_WRITE_4(sc, SK_BMU_TXS_CSR0,
2423			    SK_TXBMU_CLR_IRQ_EOF);
2424		}
2425		if (status & SK_ISR_TX2_S_EOF) {
2426			sk_txeof(sc_if1);
2427			CSR_WRITE_4(sc, SK_BMU_TXS_CSR1,
2428			    SK_TXBMU_CLR_IRQ_EOF);
2429		}
2430
2431		/* Then MAC interrupts. */
2432		if (status & SK_ISR_MAC1 && ifp0->if_flags & IFF_RUNNING) {
2433			if (sc->sk_type == SK_GENESIS)
2434				sk_intr_xmac(sc_if0);
2435			else
2436				sk_intr_yukon(sc_if0);
2437		}
2438
2439		if (status & SK_ISR_MAC2 && ifp1->if_flags & IFF_RUNNING) {
2440			if (sc->sk_type == SK_GENESIS)
2441				sk_intr_xmac(sc_if1);
2442			else
2443				sk_intr_yukon(sc_if1);
2444		}
2445
2446		if (status & SK_ISR_EXTERNAL_REG) {
2447			if (ifp0 != NULL &&
2448			    sc_if0->sk_phytype == SK_PHYTYPE_BCOM)
2449				sk_intr_bcom(sc_if0);
2450			if (ifp1 != NULL &&
2451			    sc_if1->sk_phytype == SK_PHYTYPE_BCOM)
2452				sk_intr_bcom(sc_if1);
2453		}
2454	}
2455
2456	CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2457
2458	if (ifp0 != NULL && !IFQ_DRV_IS_EMPTY(&ifp0->if_snd))
2459		sk_start(ifp0);
2460	if (ifp1 != NULL && !IFQ_DRV_IS_EMPTY(&ifp1->if_snd))
2461		sk_start(ifp1);
2462
2463	SK_UNLOCK(sc);
2464
2465	return;
2466}
2467
2468static void
2469sk_init_xmac(sc_if)
2470	struct sk_if_softc	*sc_if;
2471{
2472	struct sk_softc		*sc;
2473	struct ifnet		*ifp;
2474	struct sk_bcom_hack	bhack[] = {
2475	{ 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
2476	{ 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
2477	{ 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
2478	{ 0, 0 } };
2479
2480	sc = sc_if->sk_softc;
2481	ifp = sc_if->sk_ifp;
2482
2483	/* Unreset the XMAC. */
2484	SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_UNRESET);
2485	DELAY(1000);
2486
2487	/* Reset the XMAC's internal state. */
2488	SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
2489
2490	/* Save the XMAC II revision */
2491	sc_if->sk_xmac_rev = XM_XMAC_REV(SK_XM_READ_4(sc_if, XM_DEVID));
2492
2493	/*
2494	 * Perform additional initialization for external PHYs,
2495	 * namely for the 1000baseTX cards that use the XMAC's
2496	 * GMII mode.
2497	 */
2498	if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
2499		int			i = 0;
2500		u_int32_t		val;
2501
2502		/* Take PHY out of reset. */
2503		val = sk_win_read_4(sc, SK_GPIO);
2504		if (sc_if->sk_port == SK_PORT_A)
2505			val |= SK_GPIO_DIR0|SK_GPIO_DAT0;
2506		else
2507			val |= SK_GPIO_DIR2|SK_GPIO_DAT2;
2508		sk_win_write_4(sc, SK_GPIO, val);
2509
2510		/* Enable GMII mode on the XMAC. */
2511		SK_XM_SETBIT_2(sc_if, XM_HWCFG, XM_HWCFG_GMIIMODE);
2512
2513		sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM,
2514		    BRGPHY_MII_BMCR, BRGPHY_BMCR_RESET);
2515		DELAY(10000);
2516		sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM,
2517		    BRGPHY_MII_IMR, 0xFFF0);
2518
2519		/*
2520		 * Early versions of the BCM5400 apparently have
2521		 * a bug that requires them to have their reserved
2522		 * registers initialized to some magic values. I don't
2523		 * know what the numbers do, I'm just the messenger.
2524		 */
2525		if (sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, 0x03)
2526		    == 0x6041) {
2527			while(bhack[i].reg) {
2528				sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM,
2529				    bhack[i].reg, bhack[i].val);
2530				i++;
2531			}
2532		}
2533	}
2534
2535	/* Set station address */
2536	SK_XM_WRITE_2(sc_if, XM_PAR0,
2537	    *(u_int16_t *)(&IFP2ENADDR(sc_if->sk_ifp)[0]));
2538	SK_XM_WRITE_2(sc_if, XM_PAR1,
2539	    *(u_int16_t *)(&IFP2ENADDR(sc_if->sk_ifp)[2]));
2540	SK_XM_WRITE_2(sc_if, XM_PAR2,
2541	    *(u_int16_t *)(&IFP2ENADDR(sc_if->sk_ifp)[4]));
2542	SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_STATION);
2543
2544	if (ifp->if_flags & IFF_BROADCAST) {
2545		SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD);
2546	} else {
2547		SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD);
2548	}
2549
2550	/* We don't need the FCS appended to the packet. */
2551	SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_STRIPFCS);
2552
2553	/* We want short frames padded to 60 bytes. */
2554	SK_XM_SETBIT_2(sc_if, XM_TXCMD, XM_TXCMD_AUTOPAD);
2555
2556	/*
2557	 * Enable the reception of all error frames. This is is
2558	 * a necessary evil due to the design of the XMAC. The
2559	 * XMAC's receive FIFO is only 8K in size, however jumbo
2560	 * frames can be up to 9000 bytes in length. When bad
2561	 * frame filtering is enabled, the XMAC's RX FIFO operates
2562	 * in 'store and forward' mode. For this to work, the
2563	 * entire frame has to fit into the FIFO, but that means
2564	 * that jumbo frames larger than 8192 bytes will be
2565	 * truncated. Disabling all bad frame filtering causes
2566	 * the RX FIFO to operate in streaming mode, in which
2567	 * case the XMAC will start transfering frames out of the
2568	 * RX FIFO as soon as the FIFO threshold is reached.
2569	 */
2570	SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_BADFRAMES|
2571	    XM_MODE_RX_GIANTS|XM_MODE_RX_RUNTS|XM_MODE_RX_CRCERRS|
2572	    XM_MODE_RX_INRANGELEN);
2573
2574	if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN))
2575		SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK);
2576	else
2577		SK_XM_CLRBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK);
2578
2579	/*
2580	 * Bump up the transmit threshold. This helps hold off transmit
2581	 * underruns when we're blasting traffic from both ports at once.
2582	 */
2583	SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH);
2584
2585	/* Set promiscuous mode */
2586	sk_setpromisc(sc_if);
2587
2588	/* Set multicast filter */
2589	sk_setmulti(sc_if);
2590
2591	/* Clear and enable interrupts */
2592	SK_XM_READ_2(sc_if, XM_ISR);
2593	if (sc_if->sk_phytype == SK_PHYTYPE_XMAC)
2594		SK_XM_WRITE_2(sc_if, XM_IMR, XM_INTRS);
2595	else
2596		SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
2597
2598	/* Configure MAC arbiter */
2599	switch(sc_if->sk_xmac_rev) {
2600	case XM_XMAC_REV_B2:
2601		sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_B2);
2602		sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_B2);
2603		sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_B2);
2604		sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_B2);
2605		sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_B2);
2606		sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_B2);
2607		sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_B2);
2608		sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_B2);
2609		sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2);
2610		break;
2611	case XM_XMAC_REV_C1:
2612		sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_C1);
2613		sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_C1);
2614		sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_C1);
2615		sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_C1);
2616		sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_C1);
2617		sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_C1);
2618		sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_C1);
2619		sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_C1);
2620		sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2);
2621		break;
2622	default:
2623		break;
2624	}
2625	sk_win_write_2(sc, SK_MACARB_CTL,
2626	    SK_MACARBCTL_UNRESET|SK_MACARBCTL_FASTOE_OFF);
2627
2628	sc_if->sk_link = 1;
2629
2630	return;
2631}
2632
2633static void
2634sk_init_yukon(sc_if)
2635	struct sk_if_softc	*sc_if;
2636{
2637	u_int32_t		phy;
2638	u_int16_t		reg;
2639	struct sk_softc		*sc;
2640	struct ifnet		*ifp;
2641	int			i;
2642
2643	sc = sc_if->sk_softc;
2644	ifp = sc_if->sk_ifp;
2645
2646	if (sc->sk_type == SK_YUKON_LITE &&
2647	    sc->sk_rev == SK_YUKON_LITE_REV_A3) {
2648		/* Take PHY out of reset. */
2649		sk_win_write_4(sc, SK_GPIO,
2650			(sk_win_read_4(sc, SK_GPIO) | SK_GPIO_DIR9) & ~SK_GPIO_DAT9);
2651	}
2652
2653	/* GMAC and GPHY Reset */
2654	SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
2655	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
2656	DELAY(1000);
2657	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_CLEAR);
2658	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
2659	DELAY(1000);
2660
2661	phy = SK_GPHY_INT_POL_HI | SK_GPHY_DIS_FC | SK_GPHY_DIS_SLEEP |
2662		SK_GPHY_ENA_XC | SK_GPHY_ANEG_ALL | SK_GPHY_ENA_PAUSE;
2663
2664	switch(sc_if->sk_softc->sk_pmd) {
2665	case IFM_1000_SX:
2666	case IFM_1000_LX:
2667		phy |= SK_GPHY_FIBER;
2668		break;
2669
2670	case IFM_1000_CX:
2671	case IFM_1000_T:
2672		phy |= SK_GPHY_COPPER;
2673		break;
2674	}
2675
2676	SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_SET);
2677	DELAY(1000);
2678	SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_CLEAR);
2679	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
2680		      SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
2681
2682	/* unused read of the interrupt source register */
2683	SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR);
2684
2685	reg = SK_YU_READ_2(sc_if, YUKON_PAR);
2686
2687	/* MIB Counter Clear Mode set */
2688	reg |= YU_PAR_MIB_CLR;
2689	SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
2690
2691	/* MIB Counter Clear Mode clear */
2692	reg &= ~YU_PAR_MIB_CLR;
2693	SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
2694
2695	/* receive control reg */
2696	SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
2697
2698	/* transmit parameter register */
2699	SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
2700		      YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) );
2701
2702	/* serial mode register */
2703	reg = YU_SMR_DATA_BLIND(0x1c) | YU_SMR_MFL_VLAN | YU_SMR_IPG_DATA(0x1e);
2704	if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN))
2705		reg |= YU_SMR_MFL_JUMBO;
2706	SK_YU_WRITE_2(sc_if, YUKON_SMR, reg);
2707
2708	/* Setup Yukon's address */
2709	for (i = 0; i < 3; i++) {
2710		/* Write Source Address 1 (unicast filter) */
2711		SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4,
2712			      IFP2ENADDR(sc_if->sk_ifp)[i * 2] |
2713			      IFP2ENADDR(sc_if->sk_ifp)[i * 2 + 1] << 8);
2714	}
2715
2716	for (i = 0; i < 3; i++) {
2717		reg = sk_win_read_2(sc_if->sk_softc,
2718				    SK_MAC1_0 + i * 2 + sc_if->sk_port * 8);
2719		SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
2720	}
2721
2722	/* Set promiscuous mode */
2723	sk_setpromisc(sc_if);
2724
2725	/* Set multicast filter */
2726	sk_setmulti(sc_if);
2727
2728	/* enable interrupt mask for counter overflows */
2729	SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
2730	SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0);
2731	SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0);
2732
2733	/* Configure RX MAC FIFO */
2734	SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR);
2735	SK_IF_WRITE_4(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_OPERATION_ON);
2736
2737	/* Configure TX MAC FIFO */
2738	SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR);
2739	SK_IF_WRITE_4(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON);
2740}
2741
2742/*
2743 * Note that to properly initialize any part of the GEnesis chip,
2744 * you first have to take it out of reset mode.
2745 */
2746static void
2747sk_init(xsc)
2748	void			*xsc;
2749{
2750	struct sk_if_softc	*sc_if = xsc;
2751	struct sk_softc		*sc;
2752	struct ifnet		*ifp;
2753	struct mii_data		*mii;
2754	u_int16_t		reg;
2755	u_int32_t		imr;
2756
2757	SK_IF_LOCK(sc_if);
2758
2759	ifp = sc_if->sk_ifp;
2760	sc = sc_if->sk_softc;
2761	mii = device_get_softc(sc_if->sk_miibus);
2762
2763	if (ifp->if_flags & IFF_RUNNING) {
2764		SK_IF_UNLOCK(sc_if);
2765		return;
2766	}
2767
2768	/* Cancel pending I/O and free all RX/TX buffers. */
2769	sk_stop(sc_if);
2770
2771	if (sc->sk_type == SK_GENESIS) {
2772		/* Configure LINK_SYNC LED */
2773		SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_ON);
2774		SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL,
2775			SK_LINKLED_LINKSYNC_ON);
2776
2777		/* Configure RX LED */
2778		SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL,
2779			SK_RXLEDCTL_COUNTER_START);
2780
2781		/* Configure TX LED */
2782		SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL,
2783			SK_TXLEDCTL_COUNTER_START);
2784	}
2785
2786	/* Configure I2C registers */
2787
2788	/* Configure XMAC(s) */
2789	switch (sc->sk_type) {
2790	case SK_GENESIS:
2791		sk_init_xmac(sc_if);
2792		break;
2793	case SK_YUKON:
2794	case SK_YUKON_LITE:
2795	case SK_YUKON_LP:
2796		sk_init_yukon(sc_if);
2797		break;
2798	}
2799	mii_mediachg(mii);
2800
2801	if (sc->sk_type == SK_GENESIS) {
2802		/* Configure MAC FIFOs */
2803		SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET);
2804		SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END);
2805		SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON);
2806
2807		SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET);
2808		SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END);
2809		SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON);
2810	}
2811
2812	/* Configure transmit arbiter(s) */
2813	SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL,
2814	    SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON);
2815
2816	/* Configure RAMbuffers */
2817	SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET);
2818	SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart);
2819	SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart);
2820	SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart);
2821	SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend);
2822	SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON);
2823
2824	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_UNRESET);
2825	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_STORENFWD_ON);
2826	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_START, sc_if->sk_tx_ramstart);
2827	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_WR_PTR, sc_if->sk_tx_ramstart);
2828	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_RD_PTR, sc_if->sk_tx_ramstart);
2829	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_END, sc_if->sk_tx_ramend);
2830	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_ON);
2831
2832	/* Configure BMUs */
2833	SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_ONLINE);
2834	SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_LO,
2835	    vtophys(&sc_if->sk_rdata->sk_rx_ring[0]));
2836	SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_HI, 0);
2837
2838	SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_ONLINE);
2839	SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_LO,
2840	    vtophys(&sc_if->sk_rdata->sk_tx_ring[0]));
2841	SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_HI, 0);
2842
2843	/* Init descriptors */
2844	if (sk_init_rx_ring(sc_if) == ENOBUFS) {
2845		printf("sk%d: initialization failed: no "
2846		    "memory for rx buffers\n", sc_if->sk_unit);
2847		sk_stop(sc_if);
2848		SK_IF_UNLOCK(sc_if);
2849		return;
2850	}
2851	sk_init_tx_ring(sc_if);
2852
2853	/* Set interrupt moderation if changed via sysctl. */
2854	/* SK_LOCK(sc); */
2855	imr = sk_win_read_4(sc, SK_IMTIMERINIT);
2856	if (imr != SK_IM_USECS(sc->sk_int_mod)) {
2857		sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod));
2858		printf("skc%d: interrupt moderation is %d us\n",
2859		    sc->sk_unit, sc->sk_int_mod);
2860	}
2861	/* SK_UNLOCK(sc); */
2862
2863	/* Configure interrupt handling */
2864	CSR_READ_4(sc, SK_ISSR);
2865	if (sc_if->sk_port == SK_PORT_A)
2866		sc->sk_intrmask |= SK_INTRS1;
2867	else
2868		sc->sk_intrmask |= SK_INTRS2;
2869
2870	sc->sk_intrmask |= SK_ISR_EXTERNAL_REG;
2871
2872	CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2873
2874	/* Start BMUs. */
2875	SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_START);
2876
2877	switch(sc->sk_type) {
2878	case SK_GENESIS:
2879		/* Enable XMACs TX and RX state machines */
2880		SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_IGNPAUSE);
2881		SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
2882		break;
2883	case SK_YUKON:
2884	case SK_YUKON_LITE:
2885	case SK_YUKON_LP:
2886		reg = SK_YU_READ_2(sc_if, YUKON_GPCR);
2887		reg |= YU_GPCR_TXEN | YU_GPCR_RXEN;
2888		reg &= ~(YU_GPCR_SPEED_EN | YU_GPCR_DPLX_EN);
2889		SK_YU_WRITE_2(sc_if, YUKON_GPCR, reg);
2890	}
2891
2892	ifp->if_flags |= IFF_RUNNING;
2893	ifp->if_flags &= ~IFF_OACTIVE;
2894
2895	SK_IF_UNLOCK(sc_if);
2896
2897	return;
2898}
2899
2900static void
2901sk_stop(sc_if)
2902	struct sk_if_softc	*sc_if;
2903{
2904	int			i;
2905	struct sk_softc		*sc;
2906	struct ifnet		*ifp;
2907
2908	SK_IF_LOCK(sc_if);
2909	sc = sc_if->sk_softc;
2910	ifp = sc_if->sk_ifp;
2911
2912	untimeout(sk_tick, sc_if, sc_if->sk_tick_ch);
2913
2914	if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
2915		u_int32_t		val;
2916
2917		/* Put PHY back into reset. */
2918		val = sk_win_read_4(sc, SK_GPIO);
2919		if (sc_if->sk_port == SK_PORT_A) {
2920			val |= SK_GPIO_DIR0;
2921			val &= ~SK_GPIO_DAT0;
2922		} else {
2923			val |= SK_GPIO_DIR2;
2924			val &= ~SK_GPIO_DAT2;
2925		}
2926		sk_win_write_4(sc, SK_GPIO, val);
2927	}
2928
2929	/* Turn off various components of this interface. */
2930	SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
2931	switch (sc->sk_type) {
2932	case SK_GENESIS:
2933		SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_RESET);
2934		SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET);
2935		break;
2936	case SK_YUKON:
2937	case SK_YUKON_LITE:
2938	case SK_YUKON_LP:
2939		SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
2940		SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
2941		break;
2942	}
2943	SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
2944	SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2945	SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE);
2946	SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
2947	SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
2948	SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
2949	SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
2950	SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
2951	SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
2952
2953	/* Disable interrupts */
2954	if (sc_if->sk_port == SK_PORT_A)
2955		sc->sk_intrmask &= ~SK_INTRS1;
2956	else
2957		sc->sk_intrmask &= ~SK_INTRS2;
2958	CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
2959
2960	SK_XM_READ_2(sc_if, XM_ISR);
2961	SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
2962
2963	/* Free RX and TX mbufs still in the queues. */
2964	for (i = 0; i < SK_RX_RING_CNT; i++) {
2965		if (sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf != NULL) {
2966			m_freem(sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf);
2967			sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL;
2968		}
2969	}
2970
2971	for (i = 0; i < SK_TX_RING_CNT; i++) {
2972		if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) {
2973			m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf);
2974			sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL;
2975		}
2976	}
2977
2978	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
2979	SK_IF_UNLOCK(sc_if);
2980	return;
2981}
2982
2983static int
2984sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
2985{
2986	int error, value;
2987
2988	if (!arg1)
2989		return (EINVAL);
2990	value = *(int *)arg1;
2991	error = sysctl_handle_int(oidp, &value, 0, req);
2992	if (error || !req->newptr)
2993		return (error);
2994	if (value < low || value > high)
2995		return (EINVAL);
2996	*(int *)arg1 = value;
2997	return (0);
2998}
2999
3000static int
3001sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS)
3002{
3003	return (sysctl_int_range(oidp, arg1, arg2, req, SK_IM_MIN, SK_IM_MAX));
3004}
3005