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