xref: /dragonfly/sys/dev/netif/sln/if_sln.c (revision 81c11cd3)
1 /*
2  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  * 3. Neither the name of The DragonFly Project nor the names of its
15  *    contributors may be used to endorse or promote products derived
16  *    from this software without specific, prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD-4.7: /usr/src/sys/pci/silan.c,v 1.0 2003/01/10 gaoyonghong $
32  * $DragonFly: src/sys/dev/netif/sln/if_sln.c,v 1.3 2008/06/29 20:45:44 swildner Exp $
33  */
34 
35 #include <sys/param.h>
36 #include <sys/bus.h>
37 #include <sys/endian.h>
38 #include <sys/kernel.h>
39 #include <sys/interrupt.h>
40 #include <sys/malloc.h>
41 #include <sys/mbuf.h>
42 #include <sys/resource.h>
43 #include <sys/rman.h>
44 #include <sys/socket.h>
45 #include <sys/sockio.h>
46 #include <sys/systm.h>
47 
48 #include <bus/pci/pcidevs.h>
49 #include <bus/pci/pcireg.h>
50 #include <bus/pci/pcivar.h>
51 
52 #include <machine/clock.h>
53 
54 #include <net/bpf.h>
55 #include <net/ethernet.h>
56 #include <net/ifq_var.h>
57 #include <net/if.h>
58 #include <net/if_arp.h>
59 #include <net/if_dl.h>
60 #include <net/if_media.h>
61 #include <net/if_var.h>
62 
63 #include <vm/pmap.h>
64 #include <vm/vm.h>
65 
66 #include "if_slnreg.h"
67 #include "if_slnvar.h"
68 
69 /* Default to using PIO access for netcard driver */
70 #define SL_USEIOSPACE
71 
72 #ifdef SLN_DEBUG
73 #define PDEBUG(fmt, args...)	kprintf("%s: " fmt "\n" , __func__ , ## args)
74 #else
75 #define PDEBUG(fmt, args...)
76 #endif
77 
78 static const struct sln_dev {
79 	uint16_t vid;
80 	uint16_t did;
81 	const char *desc;
82 } sln_devs[] = {
83 	{PCI_VENDOR_SILAN, PCI_PRODUCT_SILAN_SC92031,
84 	 "Silan SC92031 Fast Ethernet" },
85 	{PCI_VENDOR_SILAN, PCI_PRODUCT_SILAN_8139D,
86 	 "Silan Rsltek 8139D Fast Ethernet" },
87 	{0, 0, NULL}
88 };
89 
90 static int	sln_probe(device_t);
91 static int	sln_attach(device_t);
92 static int	sln_detach(device_t);
93 static int	sln_shutdown(device_t);
94 static int	sln_suspend(device_t);
95 static int	sln_resume(device_t);
96 
97 static void	sln_reset(struct sln_softc *);
98 static void	sln_init(void *);
99 
100 static void	sln_tx(struct ifnet *);
101 static void	sln_rx(struct sln_softc *);
102 static void	sln_tx_intr(struct sln_softc *);
103 static void	sln_media_intr(struct sln_softc *);
104 static void	sln_interrupt(void *);
105 static int	sln_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
106 static void	sln_stop(struct sln_softc *);
107 static void	sln_watchdog(struct ifnet *);
108 
109 static int	sln_media_upd(struct ifnet *);
110 
111 static void	sln_media_stat(struct ifnet *, struct ifmediareq *);
112 static void	sln_mii_cmd(struct sln_softc *, uint32_t, u_long *);
113 static void	sln_media_cfg(struct sln_softc *);
114 static void	sln_mac_cfg(struct sln_softc *);
115 static uint32_t	sln_ether_crc32(caddr_t);
116 static void	sln_set_multi(struct sln_softc *);
117 static void	sln_init_tx(struct sln_softc *);
118 static void	sln_tick(void *);
119 
120 #ifdef SL_USEIOSPACE
121 #define SL_RID	SL_PCI_IOAD
122 #define SL_RES	SYS_RES_IOPORT
123 #else
124 #define SL_RID	SL_PCI_MEMAD
125 #define SL_RES	SYS_RES_MEMORY
126 #endif
127 
128 static device_method_t sln_methods[] = {
129 	DEVMETHOD(device_probe,		sln_probe),
130 	DEVMETHOD(device_attach,	sln_attach),
131 	DEVMETHOD(device_detach,	sln_detach),
132 	DEVMETHOD(device_shutdown,	sln_shutdown),
133 	DEVMETHOD(device_suspend,	sln_suspend),
134 	DEVMETHOD(device_resume,	sln_resume),
135 
136 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
137 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
138 
139 	{0, 0}
140 };
141 
142 static driver_t sln_driver = {
143 	"sln",
144 	sln_methods,
145 	sizeof(struct sln_softc)
146 };
147 
148 static devclass_t sln_devclass;
149 
150 DRIVER_MODULE(sln, pci, sln_driver, sln_devclass, 0, 0);
151 
152 static int
153 sln_probe(struct device *dev)
154 {
155 	const struct sln_dev *d;
156 	uint16_t did, vid;
157 
158 	vid = pci_get_vendor(dev);
159 	did = pci_get_device(dev);
160 
161 	for (d = sln_devs; d->desc != NULL; d++) {
162 		if (vid == d->vid && did == d->did) {
163 			device_set_desc(dev, d->desc);
164 			return 0;
165 		}
166 	}
167 	return ENXIO;
168 }
169 
170 /* the chip reset */
171 static void
172 sln_reset(struct sln_softc *sc)
173 {
174 	SLN_WRITE_4(sc, SL_CFG0, SL_SOFT_RESET);
175 	DELAY(200000);
176 	SLN_WRITE_4(sc, SL_CFG0, 0x0);
177 	DELAY(10000);
178 }
179 
180 /* Attach the interface. Allocate softc structures */
181 static int
182 sln_attach(device_t dev)
183 {
184 	struct sln_softc *sc = device_get_softc(dev);
185 	struct ifnet *ifp = &sc->arpcom.ac_if;
186 	unsigned char eaddr[ETHER_ADDR_LEN];
187 	int rid;
188 	int error = 0;
189 
190 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
191 
192 	/* TODO: power state change */
193 
194 	pci_enable_busmaster(dev);
195 
196 	rid = SL_RID;
197 	sc->sln_res = bus_alloc_resource_any(dev, SL_RES, &rid, RF_ACTIVE);
198 	if (sc->sln_res == NULL) {
199 		device_printf(dev, "couldn't map ports/memory\n");
200 		error = ENXIO;
201 		goto fail;
202 	}
203 	sc->sln_bustag = rman_get_bustag(sc->sln_res);
204 	sc->sln_bushandle = rman_get_bushandle(sc->sln_res);
205 
206 	/* alloc pci irq */
207 	rid = 0;
208 	sc->sln_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
209 	    RF_SHAREABLE | RF_ACTIVE);
210 	if (sc->sln_irq == NULL) {
211 		device_printf(dev, "couldn't map interrupt\n");
212 		bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res);
213 		error = ENXIO;
214 		goto fail;
215 	}
216 
217 	/* Get MAC address */
218 	((uint32_t *)(&eaddr))[0] = be32toh(SLN_READ_4(sc, SL_MAC_ADDR0));
219 	((uint16_t *)(&eaddr))[2] = be16toh(SLN_READ_4(sc, SL_MAC_ADDR1));
220 
221 	/* alloc rx buffer space */
222 	sc->sln_bufdata.sln_rx_buf = contigmalloc(SL_RX_BUFLEN,
223 	    M_DEVBUF, M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0);
224 	if (sc->sln_bufdata.sln_rx_buf == NULL) {
225 		device_printf(dev, "no memory for rx buffers!\n");
226 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq);
227 		bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res);
228 		error = ENXIO;
229 		goto fail;
230 	}
231 	callout_init(&sc->sln_state);
232 
233 	ifp->if_softc = sc;
234 	ifp->if_mtu = ETHERMTU;
235 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
236 	ifp->if_init = sln_init;
237 	ifp->if_start = sln_tx;
238 	ifp->if_ioctl = sln_ioctl;
239 	ifp->if_watchdog = sln_watchdog;
240 	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
241 	ifq_set_ready(&ifp->if_snd);
242 
243 	/* initial media */
244 	ifmedia_init(&sc->ifmedia, 0, sln_media_upd, sln_media_stat);
245 
246 	/* supported media types */
247 	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
248 	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
249 	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX, 0, NULL);
250 	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
251 	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL);
252 	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_HDX, 0, NULL);
253 	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
254 
255 	/* Choose a default media. */
256 	ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO);
257 
258 	ether_ifattach(ifp, eaddr, NULL);
259 
260 	error = bus_setup_intr(dev, sc->sln_irq, INTR_MPSAFE, sln_interrupt, sc,
261 			       &sc->sln_intrhand, ifp->if_serializer);
262 	if (error) {
263 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq);
264 		bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res);
265 		ether_ifdetach(ifp);
266 		device_printf(dev, "couldn't set up irq\n");
267 		goto fail;
268 	}
269 
270 	ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->sln_irq));
271 	KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);
272 
273 	return 0;
274 fail:
275 	return error;
276 }
277 
278 /* Stop the adapter and free any mbufs allocated to the RX and TX buffers */
279 static void
280 sln_stop(struct sln_softc *sc)
281 {
282 	struct ifnet *ifp = &sc->arpcom.ac_if;
283 	uint32_t intr_status;
284 	int i;
285 
286 	ASSERT_SERIALIZED(ifp->if_serializer);
287 
288 	ifp->if_timer = 0;
289 	callout_stop(&sc->sln_state);
290 
291 	/* disable Tx/Rx */
292 	sc->txcfg &= ~SL_TXCFG_EN;
293 	sc->rxcfg &= ~SL_RXCFG_EN;
294 	SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg);
295 	SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg);
296 
297 	/* Clear interrupt */
298 	SLN_WRITE_4(sc, SL_INT_MASK, 0);
299 	intr_status = SLN_READ_4(sc, SL_INT_STATUS);
300 
301 	/* Free the TX list buffers */
302 	for (i = 0; i < SL_TXD_CNT; i++) {
303 		if (sc->sln_bufdata.sln_tx_buf[i] != NULL) {
304 			m_freem(sc->sln_bufdata.sln_tx_buf[i]);
305 			sc->sln_bufdata.sln_tx_buf[i] = NULL;
306 			SLN_WRITE_4(sc, SL_TSAD0 + i * 4, 0);
307 		}
308 	}
309 
310 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
311 }
312 
313 static int
314 sln_detach(device_t dev)
315 {
316 	struct sln_softc *sc = device_get_softc(dev);
317 	struct ifnet *ifp = &sc->arpcom.ac_if;
318 
319 	lwkt_serialize_enter(ifp->if_serializer);
320 	sln_stop(sc);
321 	bus_teardown_intr(dev, sc->sln_irq, sc->sln_intrhand);
322 	lwkt_serialize_exit(ifp->if_serializer);
323 
324 	ether_ifdetach(ifp);
325 
326 	bus_generic_detach(dev);
327 
328 	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq);
329 	bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res);
330 
331 	contigfree(sc->sln_bufdata.sln_rx_buf, SL_RX_BUFLEN, M_DEVBUF);
332 
333 	return 0;
334 }
335 
336 static int
337 sln_media_upd(struct ifnet *ifp)
338 {
339 	struct sln_softc *sc = ifp->if_softc;
340 	struct ifmedia *ifm = &sc->ifmedia;
341 
342 	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
343 		return EINVAL;
344 
345 	if (ifp->if_flags & IFF_UP)
346 		sln_init(sc);
347 
348 	return 0;
349 }
350 
351 static void
352 sln_media_stat(struct ifnet *ifp, struct ifmediareq *ifmr)
353 {
354 	struct sln_softc *sc = ifp->if_softc;
355 	u_long phys[2];
356 	uint32_t temp;
357 
358 	ifmr->ifm_status = IFM_AVALID;
359 	ifmr->ifm_active = IFM_ETHER;
360 
361 	phys[0] = SL_MII_STAT;
362 	sln_mii_cmd(sc, SL_MII0_READ, phys);
363 
364 	if (phys[1] & SL_MIISTAT_LINK)
365 		ifmr->ifm_status |= IFM_ACTIVE;
366 
367 	temp = SLN_READ_4(sc, SL_PHY_CTRL);
368 
369 	if ((temp & (SL_PHYCTL_DUX | SL_PHYCTL_SPD100 | SL_PHYCTL_SPD10)) == 0x60800000)
370 		ifmr->ifm_active |= IFM_AUTO;
371 	else if ((temp & (SL_PHYCTL_DUX | SL_PHYCTL_SPD100)) == 0x40800000)
372 		ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
373 	else if ((temp & SL_PHYCTL_SPD100) == 0x40000000)
374 		ifmr->ifm_active |= IFM_100_TX | IFM_HDX;
375 	else if ((temp & (SL_PHYCTL_DUX | SL_PHYCTL_SPD10)) == 0x20800000)
376 		ifmr->ifm_active |= IFM_10_T | IFM_FDX;
377 	else if ((temp & SL_PHYCTL_SPD10) == 0x20000000)
378 		ifmr->ifm_active |= IFM_10_T | IFM_HDX;
379 
380 	sln_mii_cmd(sc, SL_MII0_SCAN, phys);
381 }
382 
383 /* command selected in MII command register  */
384 static void
385 sln_mii_cmd(struct sln_softc *sc, uint32_t cmd, u_long *phys)
386 {
387 	uint32_t mii_status;
388 
389 	SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER);
390 
391 	do {
392 		mii_status = 0;
393 		DELAY(10);
394 		mii_status = SLN_READ_4(sc, SL_MII_STATUS);
395 	} while (mii_status & SL_MIISTAT_BUSY);
396 
397 	switch (cmd) {
398 	case SL_MII0_SCAN:
399 		SLN_WRITE_4(sc, SL_MII_CMD1, 0x1 << 6);
400 		SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER | SL_MII0_SCAN);
401 		break;
402 
403 	case SL_MII0_READ:
404 		SLN_WRITE_4(sc, SL_MII_CMD1, phys[0] << 6);
405 		SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER | SL_MII0_READ);
406 		break;
407 
408 	default:		/* WRITE */
409 		SLN_WRITE_4(sc, SL_MII_CMD1, phys[0] << 6 | phys[1] << 11);
410 		SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER | SL_MII0_WRITE);
411 		break;
412 	}
413 
414 	do {
415 		DELAY(10);
416 		mii_status = SLN_READ_4(sc, SL_MII_STATUS);
417 	} while (mii_status & SL_MIISTAT_BUSY);
418 
419 	if (SL_MII0_READ == cmd)
420 		phys[1] = (mii_status >> 13) & 0xffff;
421 }
422 
423 /* Set media speed and duplex mode */
424 static void
425 sln_media_cfg(struct sln_softc *sc)
426 {
427 	u_long phys[2];
428 	uint32_t mediatype;
429 	uint32_t temp;
430 
431 	mediatype = (&sc->ifmedia)->ifm_cur->ifm_media;
432 
433 	temp = SLN_READ_4(sc, SL_PHY_CTRL);
434 	temp &= ~(SL_PHYCTL_DUX | SL_PHYCTL_SPD100 | SL_PHYCTL_SPD10);
435 	temp |= (SL_PHYCTL_ANE | SL_PHYCTL_RESET);
436 
437 	/************************************************/
438 	/* currently set media word by selected media   */
439 	/*                                              */
440 	/* IFM_ETHER = 0x00000020                       */
441 	/* IFM_AUTO=0, IFM_10_T=3,  IFM_100_TX=6        */
442 	/* IFM_FDX=0x00100000    IFM_HDX=0x00200000     */
443 	/************************************************/
444 	switch (mediatype) {
445 	case 0x00000020:
446 		PDEBUG(" autoselet supported\n");
447 		temp |= (SL_PHYCTL_DUX | SL_PHYCTL_SPD100 | SL_PHYCTL_SPD10);
448 		sc->ifmedia.ifm_media = IFM_ETHER | IFM_AUTO;
449 		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO);
450 		break;
451 	case 0x23:
452 	case 0x00200023:
453 		PDEBUG(" 10Mbps half_duplex supported\n");
454 		temp |= SL_PHYCTL_SPD10;
455 		sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX;
456 		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX);
457 		break;
458 
459 	case 0x00100023:
460 		PDEBUG("10Mbps full_duplex supported\n");
461 		temp |= (SL_PHYCTL_SPD10 | SL_PHYCTL_DUX);
462 		sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_FDX;
463 		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX);
464 		break;
465 
466 	case 0x26:
467 	case 0x00200026:
468 		PDEBUG("100Mbps half_duplex supported\n");
469 		temp |= SL_PHYCTL_SPD100;
470 		sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_HDX;
471 		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_HDX);
472 		break;
473 
474 	case 0x00100026:
475 		PDEBUG("100Mbps full_duplex supported\n");
476 		temp |= (SL_PHYCTL_SPD100 | SL_PHYCTL_DUX);
477 		sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_FDX;
478 		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX);
479 		break;
480 
481 	default:
482 		break;
483 	}
484 
485 	SLN_WRITE_4(sc, SL_PHY_CTRL, temp);
486 
487 	DELAY(10000);
488 	temp &= ~SL_PHYCTL_RESET;
489 	SLN_WRITE_4(sc, SL_PHY_CTRL, temp);
490 
491 	DELAY(1000);
492 	phys[0] = SL_MII_JAB;
493 	phys[1] = SL_PHY_16_JAB_ENB | SL_PHY_16_PORT_ENB;
494 	sln_mii_cmd(sc, SL_MII0_WRITE, phys);
495 
496 	sc->connect = 0;
497 	sln_mii_cmd(sc, SL_MII0_SCAN, phys);
498 }
499 
500 static void
501 sln_mac_cfg(struct sln_softc *sc)
502 {
503 	struct ifnet *ifp = &sc->arpcom.ac_if;
504 	u_long flowcfg = 0;
505 
506 	/* Set the initial TX/RX/Flow Control configuration */
507 	sc->rxcfg = SL_RXCFG_LOW_THRESHOLD | SL_RXCFG_HIGH_THRESHOLD;
508 	sc->txcfg = TX_CFG_DEFAULT;
509 
510 	if (sc->txenablepad)
511 		sc->txcfg |= 0x20000000;
512 
513 	if (sc->media_speed == IFM_10_T)
514 		sc->txcfg |= SL_TXCFG_DATARATE;
515 
516 	if (sc->media_duplex == IFM_FDX) {
517 		sc->rxcfg |= SL_RXCFG_FULLDX;
518 		sc->txcfg |= SL_TXCFG_FULLDX;
519 		flowcfg = SL_FLOWCTL_FULLDX | SL_FLOWCTL_EN;
520 	} else {
521 		sc->rxcfg &= ~SL_RXCFG_FULLDX;
522 		sc->txcfg &= ~SL_TXCFG_FULLDX;
523 	}
524 
525 	/* if promiscuous mode, set the allframes bit. */
526 	if (ifp->if_flags & IFF_PROMISC)
527 		sc->rxcfg |= (SL_RXCFG_EN | SL_RXCFG_RCV_SMALL | SL_RXCFG_RCV_HUGE | SL_RXCFG_RCV_ERR | SL_RXCFG_RCV_BROAD | SL_RXCFG_RCV_MULTI | SL_RXCFG_RCV_ALL);
528 	else
529 		sc->rxcfg &= ~(SL_RXCFG_EN | SL_RXCFG_RCV_SMALL | SL_RXCFG_RCV_HUGE | SL_RXCFG_RCV_ERR | SL_RXCFG_RCV_BROAD | SL_RXCFG_RCV_MULTI | SL_RXCFG_RCV_ALL);
530 
531 	/* Set capture broadcast bit to capture broadcast frames */
532 	if (ifp->if_flags & IFF_BROADCAST)
533 		sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_BROAD;
534 	else
535 		sc->rxcfg &= ~(SL_RXCFG_EN | SL_RXCFG_RCV_BROAD);
536 
537 	/* Program the multicast filter, if necessary */
538 	sln_set_multi(sc);
539 
540 	SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg);
541 	SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg);
542 	SLN_WRITE_4(sc, SL_FLOW_CTRL, flowcfg);
543 }
544 
545 static u_char shade_map[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
546 			      0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };
547 
548 /* Calculate CRC32 of a multicast group address */
549 static uint32_t
550 sln_ether_crc32(caddr_t addr)
551 {
552 	uint32_t crc, crcr;
553 	int i, j;
554 	unsigned char data = 0;
555 	/* Compute CRC for the address value. */
556 
557 	crc = 0xFFFFFFFF;	/* initial value */
558 
559 	for (i = ETHER_ADDR_LEN; i > 0; i--) {
560 		data = *addr++;
561 
562 		for (j = 0; j < 8; j++) {
563 			if (((data & 0x1) ^ (crc & 0x1)) != 0) {
564 				crc >>= 1;
565 				crc ^= 0xEDB88320;
566 			} else {
567 				crc >>= 1;
568 			}
569 			data >>= 1;
570 		}
571 	}
572 
573 	crcr = shade_map[crc >> 28];
574 	crcr |= (shade_map[(crc >> 24) & 0xf] << 4);
575 	crcr |= (shade_map[(crc >> 20) & 0xf] << 8);
576 	crcr |= (shade_map[(crc >> 16) & 0xf] << 12);
577 	crcr |= (shade_map[(crc >> 12) & 0xf] << 16);
578 	crcr |= (shade_map[(crc >> 8) & 0xf] << 20);
579 	crcr |= (shade_map[(crc >> 4) & 0xf] << 24);
580 	crcr |= (shade_map[crc & 0xf] << 28);
581 
582 	return crcr;
583 }
584 
585 /* Program the 64-bit multicast hash filter */
586 static void
587 sln_set_multi(struct sln_softc *sc)
588 {
589 	struct ifnet *ifp = &sc->arpcom.ac_if;
590 	uint32_t crc = 0;
591 	uint32_t mc_g[2] = {0, 0};
592 	struct ifmultiaddr *ifma;
593 	int j;
594 
595 	if (ifp->if_flags & IFF_PROMISC) {
596 		kprintf("Promisc mode is enabled\n");
597 		sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_MULTI;
598 		mc_g[0] = mc_g[1] = 0xFFFFFFFF;
599 	} else if (ifp->if_flags & IFF_ALLMULTI) {
600 		kprintf("Allmulti mode is enabled\n");
601 		sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_MULTI;
602 		mc_g[0] = mc_g[1] = 0xFFFFFFFF;
603 	} else if (ifp->if_flags & IFF_MULTICAST) {
604 		kprintf("Multicast mode is enabled\n");
605 		sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_MULTI;
606 
607 		/* first, zero all the existing hash bits */
608 		mc_g[0] = mc_g[1] = 0;
609 
610 		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
611 			j = 0;
612 
613 			if ((ifma->ifma_addr->sa_family) != AF_LINK)
614 				continue;
615 
616 			crc = ~sln_ether_crc32(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
617 			crc >>= 24;
618 
619 			if (crc & 0x1)
620 				j |= 0x2;
621 			if (crc & 0x2)
622 				j |= 0x1;
623 			if (crc & 0x10)
624 				j |= 0x20;
625 			if (crc & 0x20)
626 				j |= 0x10;
627 			if (crc & 0x40)
628 				j |= 0x8;
629 			if (crc & 0x80)
630 				j |= 0x4;
631 
632 			if (j > 31)
633 				mc_g[0] |= (0x1 << (j - 32));
634 			else
635 				mc_g[1] |= (0x1 << j);
636 		}
637 	} else {
638 		sc->rxcfg &= ~(SL_RXCFG_EN | SL_RXCFG_RCV_MULTI);
639 	}
640 
641 	SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg);
642 	SLN_WRITE_4(sc, SL_MULTI_GROUP0, mc_g[0]);
643 	SLN_WRITE_4(sc, SL_MULTI_GROUP1, mc_g[1]);
644 }
645 
646 /* Initialize the TX/Rx descriptors */
647 static void
648 sln_init_tx(struct sln_softc *sc)
649 {
650 	int i;
651 
652 	sc->sln_bufdata.cur_tx = 0;
653 	sc->sln_bufdata.dirty_tx = 0;
654 
655 	for (i = 0; i < SL_TXD_CNT; i++) {
656 		sc->sln_bufdata.sln_tx_buf[i] = NULL;
657 		SLN_WRITE_4(sc, SL_TSAD0 + (i * 4), 0);
658 	}
659 }
660 
661 /* Software & Hardware Initialize */
662 static void
663 sln_init(void *x)
664 {
665 	struct sln_softc *sc = x;
666 	struct ifnet *ifp = &sc->arpcom.ac_if;
667 
668 	PDEBUG("sln_init\n");
669 
670 	ASSERT_SERIALIZED(ifp->if_serializer);
671 
672 	sln_stop(sc);
673 
674 	/* soft reset the chip */
675 	sln_reset(sc);
676 
677 	/* disable interrupt */
678 	SLN_WRITE_4(sc, SL_INT_MASK, 0);
679 
680 	/* SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER); */
681 
682 	/* clear multicast address */
683 	SLN_WRITE_4(sc, SL_MULTI_GROUP0, 0);
684 	SLN_WRITE_4(sc, SL_MULTI_GROUP1, 0);
685 
686 	/* Init the RX buffer start address register. */
687 	SLN_WRITE_4(sc, SL_RBSA, vtophys(sc->sln_bufdata.sln_rx_buf));
688 	sc->sln_bufdata.dirty_rx = vtophys(sc->sln_bufdata.sln_rx_buf);
689 
690 	/* Init TX descriptors. */
691 	sln_init_tx(sc);
692 
693 	/* configure RX buffer size */
694 	if (sc->tx_early_ctrl && sc->rx_early_ctrl)
695 		SLN_WRITE_4(sc, SL_CFG1, SL_EARLY_RX | SL_EARLY_TX | SL_RXBUF_64 | SL_RXFIFO_1024BYTES);
696 	else if (sc->tx_early_ctrl)
697 		SLN_WRITE_4(sc, SL_CFG1, SL_EARLY_TX | SL_RXBUF_64);
698 	else if (sc->rx_early_ctrl)
699 		SLN_WRITE_4(sc, SL_CFG1, SL_EARLY_RX | SL_RXBUF_64 | SL_RXFIFO_1024BYTES);
700 	else
701 		SLN_WRITE_4(sc, SL_CFG1, SL_RXBUF_64);
702 
703 	/* MII media configuration */
704 	sln_media_cfg(sc);
705 
706 	if (sc->connect) {
707 		/* Enable transmit and receive */
708 		sc->rxcfg |= SL_RXCFG_EN;
709 		sc->txcfg |= SL_TXCFG_EN;
710 	} else {
711 		sc->rxcfg &= ~SL_RXCFG_EN;
712 		sc->txcfg &= ~SL_TXCFG_EN;
713 	}
714 
715 	SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg);
716 	SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg);
717 
718 	/* Enable interrupts */
719 	SLN_WRITE_4(sc, SL_INT_MASK, SL_INRTS);
720 
721 	sc->suspended = 0;
722 
723 	ifp->if_flags |= IFF_RUNNING;
724 	ifp->if_flags &= ~IFF_OACTIVE;
725 
726 	callout_reset(&sc->sln_state, hz, sln_tick, sc);
727 }
728 
729 /* Transmit Packet */
730 static void
731 sln_tx(struct ifnet *ifp)
732 {
733 	struct sln_softc *sc = ifp->if_softc;
734 	struct mbuf *m_head = NULL;
735 	struct mbuf *m_new = NULL;
736 	int entry;
737 
738 	ASSERT_SERIALIZED(ifp->if_serializer);
739 
740 	if (!sc->connect) {
741 		ifq_purge(&ifp->if_snd);
742 		return;
743 	}
744 
745 	if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
746 		return;
747 
748 	while (SL_CUR_TXBUF(sc) == NULL) {	/* SL_CUR_TXBUF(x) = x->sln_bufdata.sln_tx_buf[x->sln_bufdata.cur_tx] */
749 		entry = sc->sln_bufdata.cur_tx;
750 
751 		m_head = ifq_dequeue(&ifp->if_snd, NULL);
752 		if (m_head == NULL)
753 			break;
754 
755 		MGETHDR(m_new, MB_DONTWAIT, MT_DATA);
756 		if (m_new == NULL) {
757 			if_printf(ifp, "no memory for tx descriptor");
758 			m_freem(m_head);
759 			break;
760 		}
761 		if ((m_head->m_pkthdr.len > MHLEN) || (60 > MHLEN)) {
762 			MCLGET(m_new, MB_DONTWAIT);
763 			if (!(m_new->m_flags & M_EXT)) {
764 				m_freem(m_new);
765 				m_freem(m_head);
766 				if_printf(ifp, "no memory for tx descriptor");
767 				break;
768 			}
769 		}
770 		m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t));
771 		m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
772 		m_freem(m_head);
773 		m_head = m_new;
774 		SL_CUR_TXBUF(sc) = m_head;
775 
776 		/*
777 		 * if there's a BPF listener, bounce a copy of this frame to
778 		 * him
779 		 */
780 		BPF_MTAP(ifp, SL_CUR_TXBUF(sc));
781 
782 		/* Transmit the frame */
783 		SLN_WRITE_4(sc, ((entry * 4) + SL_TSAD0),
784 		    vtophys(mtod(SL_CUR_TXBUF(sc), caddr_t)));
785 
786 		/* calculate length of the frame */
787 		if ((SL_CUR_TXBUF(sc)->m_pkthdr.len < 60) && (!sc->txenablepad)) {
788 			memset(mtod(m_head, char *)+m_head->m_pkthdr.len, 0x20, 60 - m_head->m_pkthdr.len);
789 			SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, 60);
790 		} else if (SL_CUR_TXBUF(sc)->m_pkthdr.len < 100)
791 			SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, SL_CUR_TXBUF(sc)->m_pkthdr.len);
792 		else if (SL_CUR_TXBUF(sc)->m_pkthdr.len < 300)
793 			SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, 0x30000 | SL_CUR_TXBUF(sc)->m_pkthdr.len);
794 		else
795 			SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, 0x50000 | SL_CUR_TXBUF(sc)->m_pkthdr.len);
796 		sc->sln_bufdata.cur_tx = (entry + 1) % SL_TXD_CNT;
797 
798 		PDEBUG("Queue tx packet size %d to tx-descriptor %d.\n", m_head->m_pkthdr.len, entry);
799 	}
800 
801 	/* Tx buffer chain full */
802 	if (SL_CUR_TXBUF(sc) != NULL)
803 		ifp->if_flags |= IFF_OACTIVE;
804 
805 	/* Set a timeout in case the chip goes out to lunch */
806 	ifp->if_timer = 5;
807 }
808 
809 /* Receive Data handler */
810 static void
811 sln_rx(struct sln_softc *sc)
812 {
813 	struct mbuf *m;
814 	struct ifnet *ifp = &sc->arpcom.ac_if;
815 	uint32_t rxstat = 0;
816 	uint32_t rx_offset;
817 	caddr_t rx_bufpos = NULL;
818 	uint32_t cur_rx = 0;
819 	uint32_t dirty_rx;
820 	long rx_len;
821 	u_long rx_space;
822 	u_long rx_size = 0;
823 	u_long rx_size_align = 0;
824 	uint32_t rx_bytes = 0;
825 	u_long pkt_size = 0;
826 
827 	cur_rx = SLN_READ_4(sc, SL_RBW_PTR);
828 	dirty_rx = sc->sln_bufdata.dirty_rx;
829 
830 	/*
831 	 * cur_rx is only 17 bits in the RxBufWPtr register. if cur_rx can be
832 	 * used in physical space, we need to change it to 32 bits physical
833 	 * address
834 	 */
835 	cur_rx |= vtophys(sc->sln_bufdata.sln_rx_buf) & (~(u_long) (SL_RX_BUFLEN - 1));
836 
837 	if (cur_rx < vtophys(sc->sln_bufdata.sln_rx_buf))
838 		cur_rx += SL_RX_BUFLEN;
839 
840 	if (cur_rx >= dirty_rx)
841 		rx_len = (long)(cur_rx - dirty_rx);
842 	else
843 		rx_len = SL_RX_BUFLEN - (long)(dirty_rx - cur_rx);
844 
845 	if ((rx_len > SL_RX_BUFLEN) || (rx_len < 0)) {
846 		if_printf(ifp, "rx len is fail\n");
847 		return;
848 	}
849 	if (rx_len == 0)
850 		return;
851 
852 	rx_offset = (dirty_rx - vtophys(sc->sln_bufdata.sln_rx_buf)) & (u_long) (SL_RX_BUFLEN - 1);
853 
854 	while (rx_len > 0) {
855 		rx_bufpos = sc->sln_bufdata.sln_rx_buf + rx_offset;
856 		rxstat = *(uint32_t *) rx_bufpos;
857 		rx_size = (rxstat >> 20) & 0x0FFF;
858 		rx_size_align = (rx_size + 3) & ~3;	/* for 4 bytes aligned */
859 		pkt_size = rx_size - ETHER_CRC_LEN;	/* Omit the four octet
860 							 * CRC from the length. */
861 
862 		PDEBUG("rx len: %ld  rx frame size:%ld  rx state:0x%x\n", rx_len, rx_size, rxstat);
863 
864 		/* errors receive packets caculatation */
865 		if (rxstat == 0 || rx_size < 16 || !(rxstat & SL_RXSTAT_RXOK)) {
866 			ifp->if_ierrors++;
867 
868 			if (!(rxstat & SL_RXSTAT_RXOK))
869 				if_printf(ifp, "receiver ok error\n");
870 
871 			if (!(rxstat & SL_RXSTAT_CRCOK))
872 				if_printf(ifp, "crc error\n");
873 
874 			if (rxstat & SL_RXSTAT_ALIGNERR)
875 				if_printf(ifp, "frame alignment error\n");
876 
877 			if (rxstat & (SL_RXSTAT_HUGEFRM | SL_RXSTAT_SMALLFRM))
878 				if_printf(ifp, "received frame length is error\n");
879 
880 			break;
881 		}
882 		rx_len -= (long)(rx_size_align + 4);	/* 4 bytes for receive
883 							 * frame head */
884 
885 		if (rx_len < 0) {
886 			kprintf("rx packets len is too small\n");
887 			break;
888 		}
889 #ifdef SLN_PDEBUG
890 		caddr_t p = NULL;
891 
892 		if_printf(ifp, "rx frame content\n");
893 		p = rx_bufpos;
894 		for (i = 0; i < 30; i++, p++) {
895 			if (i % 10 == 0)
896 				kprintf("\n");
897 			if_printf(ifp, "%x  ", (u_char)*p);
898 		}
899 		if_printf(ifp, "\n");
900 #endif
901 		/* No errors; receive the packet. */
902 		rx_bytes = rx_bytes + rx_size + 4;	/* 4 bytes for receive
903 							 * frame header */
904 
905 		if (rx_bufpos == (sc->sln_bufdata.sln_rx_buf + SL_RX_BUFLEN))
906 			rx_bufpos = sc->sln_bufdata.sln_rx_buf;
907 
908 		rx_bufpos = rx_bufpos + 4;	/* 4 bytes for receive frame
909 						 * header */
910 		rx_space = (u_long)((sc->sln_bufdata.sln_rx_buf + SL_RX_BUFLEN) - rx_bufpos);
911 
912 		if (pkt_size > rx_space) {
913 			m = m_devget(rx_bufpos - 2, pkt_size + 2, 0, ifp, NULL);	/* 2 for etherer head
914 											 * align */
915 
916 			if (m == NULL) {
917 				ifp->if_ierrors++;
918 				if_printf(ifp,
919 				    "out of mbufs, tried to copy %ld bytes\n",
920 				    rx_space);
921 			} else {
922 				m_adj(m, 2);
923 				m_copyback(m, rx_space, pkt_size - rx_space, sc->sln_bufdata.sln_rx_buf);
924 			}
925 		} else {
926 			m = m_devget(rx_bufpos - 2, pkt_size + 2, 0, ifp, NULL);
927 
928 			if (m == NULL) {
929 				ifp->if_ierrors++;
930 				if_printf(ifp,
931 				    "out of mbufs, tried to copy %ld bytes\n",
932 				    pkt_size);
933 				if_printf(ifp, "ierrors = %ld\n", ifp->if_ierrors);
934 
935 			} else {
936 				m_adj(m, 2);
937 			}
938 		}
939 
940 		ifp->if_ipackets++;
941 		PDEBUG("ipackets = %ld\n", ifp->if_ipackets);
942 
943 		ifp->if_input(ifp, m);
944 
945 		rx_offset = (rx_offset + rx_size + 4) & (u_long) (SL_RX_BUFLEN - 1);	/* 4 bytes for receive
946 											 * frame head */
947 	}
948 
949 	sc->sln_bufdata.dirty_rx = cur_rx;
950 
951 	SLN_WRITE_4(sc, SL_RBR_PTR, cur_rx);
952 }
953 
954 /* Transmit OK/ERR handler */
955 static void
956 sln_tx_intr(struct sln_softc *sc)
957 {
958 	struct ifnet *ifp = &sc->arpcom.ac_if;
959 	uint32_t txstat;
960 	int entry;
961 
962 	do {
963 		entry = sc->sln_bufdata.dirty_tx;
964 		txstat = SLN_READ_4(sc, SL_TSD0 + entry * 4);
965 
966 		if (!(txstat & (SL_TXSD_TOK | SL_TXSD_TUN | SL_TXSD_TABT)))
967 			break;	/* It still hasn't been sent */
968 
969 		if (SL_DIRTY_TXBUF(sc) != NULL) {	/* SL_DIRTY_TXBUF(x) =
970 							 * x->sln_bufdata.sln_tx_
971 							 * buf[x->sln_bufdata.dir
972 							 * ty_tx] */
973 			m_freem(SL_DIRTY_TXBUF(sc));
974 			SL_DIRTY_TXBUF(sc) = NULL;
975 		}
976 		if (txstat & SL_TXSD_TOK) {
977 			ifp->if_opackets++;
978 			ifp->if_obytes += txstat & SL_TXSD_LENMASK;
979 			PDEBUG("opackets = %ld\n", ifp->if_opackets);
980 			ifp->if_collisions += (txstat & SL_TXSD_NCC) >> 22;
981 		} else {
982 			ifp->if_oerrors++;
983 			if ((txstat & (SL_TXSD_TABT | SL_TXSD_OWC))) {
984 				sc->txcfg = TX_CFG_DEFAULT;
985 
986 				if (sc->txenablepad)
987 					sc->txcfg |= 0x20000000;
988 
989 				SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg);
990 			}
991 		}
992 		PDEBUG("tx done descriprtor %x\n", entry);
993 		sc->sln_bufdata.dirty_tx = (entry + 1) % SL_TXD_CNT;
994 
995 		ifp->if_flags &= ~IFF_OACTIVE;
996 	} while (sc->sln_bufdata.dirty_tx != sc->sln_bufdata.cur_tx);
997 
998 	if (sc->sln_bufdata.dirty_tx == sc->sln_bufdata.cur_tx)
999 		ifp->if_timer = 0;
1000 	else
1001 		ifp->if_timer = 5;
1002 }
1003 
1004 static void
1005 sln_media_intr(struct sln_softc *sc)
1006 {
1007 	u_long phys[2];
1008 	struct ifnet *ifp = &sc->arpcom.ac_if;
1009 
1010 	phys[0] = SL_MII_STAT;
1011 	sln_mii_cmd(sc, SL_MII0_READ, phys);
1012 
1013 	PDEBUG("mii_stat:0x%lx\n", phys[1]);
1014 
1015 	if (0 == (phys[1] & SL_MIISTAT_LINK)) {
1016 		kprintf("media is unconnect,linked down,or uncompatible\n");
1017 		sc->connect = 0;
1018 		sln_mii_cmd(sc, SL_MII0_SCAN, phys);
1019 		/* disable tx/rx */
1020 		sc->txcfg &= ~SL_TXCFG_EN;
1021 		sc->rxcfg &= ~SL_RXCFG_EN;
1022 		SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg);
1023 		SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg);
1024 
1025 		return;
1026 	}
1027 	/* Link is good. Report modes and set duplex mode. */
1028 	PDEBUG("media is connecting---> ");
1029 	sc->connect = 1;
1030 
1031 	phys[0] = SL_MII_STAT_OUTPUT;
1032 	sln_mii_cmd(sc, SL_MII0_READ, phys);
1033 	sc->media_duplex = ((phys[1] & 0x0004) == 0) ? IFM_HDX : IFM_FDX;
1034 	sc->media_speed = ((phys[1] & 0x0002) == 0) ? IFM_10_T : IFM_100_TX;
1035 
1036 	if_printf(ifp, "media option:%dM %s-duplex\n",
1037 	    sc->media_speed == 0x6 ? 100 : 10,
1038 	    sc->media_duplex == 0x100000 ? "full" : "half");
1039 
1040 	sln_mii_cmd(sc, SL_MII0_SCAN, phys);
1041 
1042 	sln_mac_cfg(sc);
1043 
1044 	/* Enable tx/rx */
1045 	sc->rxcfg |= SL_RXCFG_EN;
1046 	sc->txcfg |= SL_TXCFG_EN;
1047 	SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg);
1048 	SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg);
1049 }
1050 
1051 /* Interrupt Handler */
1052 static void
1053 sln_interrupt(void *arg)
1054 {
1055 	struct sln_softc *sc = arg;
1056 	struct ifnet *ifp = &sc->arpcom.ac_if;
1057 	uint32_t int_status;
1058 
1059 	ASSERT_SERIALIZED(ifp->if_serializer);
1060 
1061 	if (sc->suspended || (ifp->if_flags & IFF_RUNNING) == 0)
1062 		return;
1063 
1064 	/* Disable interrupts. */
1065 	SLN_WRITE_4(sc, SL_INT_MASK, 0);
1066 
1067 	int_status = SLN_READ_4(sc, SL_INT_STATUS);
1068 
1069 	if ((int_status == 0xffffffff) || (int_status & SL_INRTS) == 0)
1070 		goto back;
1071 
1072 	int_status = int_status & SL_INRTS;
1073 	PDEBUG("int_status = 0x%x\n", int_status);
1074 
1075 	while (0 != int_status) {
1076 		if (int_status & SL_INT_ROK)
1077 			sln_rx(sc);
1078 
1079 		if (int_status & SL_INT_TOK)
1080 			sln_tx_intr(sc);
1081 
1082 		if (int_status & SL_INT_RBO) {
1083 			ifp->if_ierrors++;
1084 			PDEBUG("rx buffer is overflow\n");
1085 		}
1086 
1087 		if (int_status & (SL_INT_LINKFAIL | SL_INT_LINKOK))
1088 			sln_media_intr(sc);
1089 
1090 		int_status = SLN_READ_4(sc, SL_INT_STATUS);
1091 	}
1092 
1093 	/* Data in Tx buffer waiting for transimission */
1094 	if (!ifq_is_empty(&ifp->if_snd))
1095 		if_devstart(ifp);
1096 back:
1097 	/* Re-enable interrupts. */
1098 	SLN_WRITE_4(sc, SL_INT_MASK, SL_INRTS);
1099 }
1100 
1101 static void
1102 sln_tick(void *x)
1103 {
1104 	struct sln_softc *sc = x;
1105 
1106 	callout_reset(&sc->sln_state, hz, sln_tick, sc);
1107 }
1108 
1109 static int
1110 sln_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
1111 {
1112 	struct sln_softc *sc = ifp->if_softc;
1113 	struct ifreq *ifr = (struct ifreq *)data;
1114 	int error = 0;
1115 
1116 	ASSERT_SERIALIZED(ifp->if_serializer);
1117 
1118 	switch (cmd) {
1119 	case SIOCSIFFLAGS:
1120 		if (ifp->if_flags & IFF_UP) {
1121 			if ((ifp->if_flags & IFF_RUNNING) == 0)
1122 				sln_init(sc);
1123 		} else {
1124 			if (ifp->if_flags & IFF_RUNNING)
1125 				sln_stop(sc);
1126 		}
1127 		break;
1128 	case SIOCADDMULTI:
1129 	case SIOCDELMULTI:
1130 		sln_set_multi(sc);
1131 		break;
1132 	case SIOCGIFMEDIA:
1133 	case SIOCSIFMEDIA:
1134 		error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
1135 		break;
1136 	default:
1137 		error = ether_ioctl(ifp, cmd, data);
1138 		break;
1139 	}
1140 	return error;
1141 }
1142 
1143 static void
1144 sln_watchdog(struct ifnet *ifp)
1145 {
1146 	struct sln_softc *sc = ifp->if_softc;
1147 
1148 	ASSERT_SERIALIZED(ifp->if_serializer);
1149 
1150 	if_printf(ifp, "watchdog timeout!\n");
1151 	ifp->if_oerrors++;
1152 
1153 	sln_tx_intr(sc);
1154 	sln_rx(sc);
1155 	sln_init(sc);
1156 
1157 	if (!ifq_is_empty(&ifp->if_snd))
1158 		if_devstart(ifp);
1159 }
1160 
1161 /* Stop all chip I/O */
1162 static int
1163 sln_shutdown(device_t dev)
1164 {
1165 	struct sln_softc *sc = device_get_softc(dev);
1166 	struct ifnet *ifp = &sc->arpcom.ac_if;
1167 
1168 	lwkt_serialize_enter(ifp->if_serializer);
1169 	sln_stop(sc);
1170 	lwkt_serialize_exit(ifp->if_serializer);
1171 
1172 	return 0;
1173 }
1174 
1175 /* device suspend routine */
1176 static int
1177 sln_suspend(device_t dev)
1178 {
1179 	struct sln_softc *sc = device_get_softc(dev);
1180 	struct ifnet *ifp = &sc->arpcom.ac_if;
1181 
1182 	lwkt_serialize_enter(ifp->if_serializer);
1183 	sln_stop(sc);
1184 	sc->suspended = 1;
1185 	lwkt_serialize_exit(ifp->if_serializer);
1186 
1187 	return 0;
1188 }
1189 
1190 /* device resume routine */
1191 static int
1192 sln_resume(device_t dev)
1193 {
1194 	struct sln_softc *sc = device_get_softc(dev);
1195 	struct ifnet *ifp = &sc->arpcom.ac_if;
1196 
1197 	lwkt_serialize_enter(ifp->if_serializer);
1198 	if (ifp->if_flags & IFF_UP)
1199 		sln_init(sc);
1200 	sc->suspended = 0;
1201 	lwkt_serialize_exit(ifp->if_serializer);
1202 
1203 	return 0;
1204 }
1205