FreeBSD/Linux Kernel Cross Reference
sys/pci/if_sis.c
1 /*
2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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 the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * $FreeBSD$
33 */
34
35 /*
36 * SiS 900/SiS 7016 fast ethernet PCI NIC driver. Datasheets are
37 * available from http://www.sis.com.tw.
38 *
39 * Written by Bill Paul <wpaul@ee.columbia.edu>
40 * Electrical Engineering Department
41 * Columbia University, New York City
42 */
43
44 /*
45 * The SiS 900 is a fairly simple chip. It uses bus master DMA with
46 * simple TX and RX descriptors of 3 longwords in size. The receiver
47 * has a single perfect filter entry for the station address and a
48 * 128-bit multicast hash table. The SiS 900 has a built-in MII-based
49 * transceiver while the 7016 requires an external transceiver chip.
50 * Both chips offer the standard bit-bang MII interface as well as
51 * an enchanced PHY interface which simplifies accessing MII registers.
52 *
53 * The only downside to this chipset is that RX descriptors must be
54 * longword aligned.
55 */
56
57 #include "bpfilter.h"
58
59 #include <sys/param.h>
60 #include <sys/systm.h>
61 #include <sys/sockio.h>
62 #include <sys/mbuf.h>
63 #include <sys/malloc.h>
64 #include <sys/kernel.h>
65 #include <sys/socket.h>
66
67 #include <net/if.h>
68 #include <net/if_arp.h>
69 #include <net/ethernet.h>
70 #include <net/if_dl.h>
71 #include <net/if_media.h>
72
73 #if NBPFILTER > 0
74 #include <net/bpf.h>
75 #endif
76
77 #include <vm/vm.h> /* for vtophys */
78 #include <vm/pmap.h> /* for vtophys */
79 #include <machine/clock.h> /* for DELAY */
80 #include <machine/bus_pio.h>
81 #include <machine/bus_memio.h>
82 #include <machine/bus.h>
83
84 #include <pci/pcireg.h>
85 #include <pci/pcivar.h>
86
87 #define SIS_USEIOSPACE
88
89 #include <pci/if_sisreg.h>
90
91 #ifndef lint
92 static const char rcsid[] =
93 "$FreeBSD$";
94 #endif
95
96 /*
97 * Various supported device vendors/types and their names.
98 */
99 static struct sis_type sis_devs[] = {
100 { SIS_VENDORID, SIS_DEVICEID_900, "SiS 900 10/100BaseTX" },
101 { SIS_VENDORID, SIS_DEVICEID_7016, "SiS 7016 10/100BaseTX" },
102 { 0, 0, NULL }
103 };
104
105 static struct sis_type sis_phys[] = {
106 { 0, 0, "<MII-compilant physical interface>" },
107 { 0, 0, NULL }
108 };
109
110 static unsigned long sis_count = 0;
111 static const char *sis_probe __P((pcici_t, pcidi_t));
112 static void sis_attach __P((pcici_t, int));
113
114 static int sis_newbuf __P((struct sis_softc *,
115 struct sis_desc *,
116 struct mbuf *));
117 static int sis_encap __P((struct sis_softc *,
118 struct mbuf *, u_int32_t *));
119 static void sis_rxeof __P((struct sis_softc *));
120 static void sis_rxeoc __P((struct sis_softc *));
121 static void sis_txeof __P((struct sis_softc *));
122 static void sis_intr __P((void *));
123 static void sis_start __P((struct ifnet *));
124 static int sis_ioctl __P((struct ifnet *, u_long, caddr_t));
125 static void sis_init __P((void *));
126 static void sis_stop __P((struct sis_softc *));
127 static void sis_watchdog __P((struct ifnet *));
128 static void sis_shutdown __P((int, void *));
129 static int sis_ifmedia_upd __P((struct ifnet *));
130 static void sis_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
131
132 static void sis_delay __P((struct sis_softc *));
133 static void sis_eeprom_idle __P((struct sis_softc *));
134 static void sis_eeprom_putbyte __P((struct sis_softc *, int));
135 static void sis_eeprom_getword __P((struct sis_softc *, int, u_int16_t *));
136 static void sis_read_eeprom __P((struct sis_softc *, caddr_t, int,
137 int, int));
138 static void sis_setmulti __P((struct sis_softc *));
139 static u_int32_t sis_calchash __P((caddr_t));
140 static void sis_reset __P((struct sis_softc *));
141 static int sis_list_rx_init __P((struct sis_softc *));
142 static int sis_list_tx_init __P((struct sis_softc *));
143
144 static u_int16_t sis_phy_readreg __P((struct sis_softc *, int));
145 static void sis_phy_writereg __P((struct sis_softc *, int, int));
146
147 static void sis_autoneg_xmit __P((struct sis_softc *));
148 static void sis_autoneg_mii __P((struct sis_softc *, int, int));
149 static void sis_setmode_mii __P((struct sis_softc *, int));
150 static void sis_getmode_mii __P((struct sis_softc *));
151
152
153 #define SIS_SETBIT(sc, reg, x) \
154 CSR_WRITE_4(sc, reg, \
155 CSR_READ_4(sc, reg) | (x))
156
157 #define SIS_CLRBIT(sc, reg, x) \
158 CSR_WRITE_4(sc, reg, \
159 CSR_READ_4(sc, reg) & ~(x))
160
161 #define SIO_SET(x) \
162 CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) | x)
163
164 #define SIO_CLR(x) \
165 CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) & ~x)
166
167 static void sis_delay(sc)
168 struct sis_softc *sc;
169 {
170 int idx;
171
172 for (idx = (300 / 33) + 1; idx > 0; idx--)
173 CSR_READ_4(sc, SIS_CSR);
174
175 return;
176 }
177
178 static void sis_eeprom_idle(sc)
179 struct sis_softc *sc;
180 {
181 register int i;
182
183 SIO_SET(SIS_EECTL_CSEL);
184 sis_delay(sc);
185 SIO_SET(SIS_EECTL_CLK);
186 sis_delay(sc);
187
188 for (i = 0; i < 25; i++) {
189 SIO_CLR(SIS_EECTL_CLK);
190 sis_delay(sc);
191 SIO_SET(SIS_EECTL_CLK);
192 sis_delay(sc);
193 }
194
195 SIO_CLR(SIS_EECTL_CLK);
196 sis_delay(sc);
197 SIO_CLR(SIS_EECTL_CSEL);
198 sis_delay(sc);
199 CSR_WRITE_4(sc, SIS_EECTL, 0x00000000);
200
201 return;
202 }
203
204 /*
205 * Send a read command and address to the EEPROM, check for ACK.
206 */
207 static void sis_eeprom_putbyte(sc, addr)
208 struct sis_softc *sc;
209 int addr;
210 {
211 register int d, i;
212
213 d = addr | SIS_EECMD_READ;
214
215 /*
216 * Feed in each bit and stobe the clock.
217 */
218 for (i = 0x400; i; i >>= 1) {
219 if (d & i) {
220 SIO_SET(SIS_EECTL_DIN);
221 } else {
222 SIO_CLR(SIS_EECTL_DIN);
223 }
224 sis_delay(sc);
225 SIO_SET(SIS_EECTL_CLK);
226 sis_delay(sc);
227 SIO_CLR(SIS_EECTL_CLK);
228 sis_delay(sc);
229 }
230
231 return;
232 }
233
234 /*
235 * Read a word of data stored in the EEPROM at address 'addr.'
236 */
237 static void sis_eeprom_getword(sc, addr, dest)
238 struct sis_softc *sc;
239 int addr;
240 u_int16_t *dest;
241 {
242 register int i;
243 u_int16_t word = 0;
244
245 /* Force EEPROM to idle state. */
246 sis_eeprom_idle(sc);
247
248 /* Enter EEPROM access mode. */
249 sis_delay(sc);
250 SIO_SET(SIS_EECTL_CSEL);
251 sis_delay(sc);
252 SIO_SET(SIS_EECTL_CLK);
253 sis_delay(sc);
254
255 /*
256 * Send address of word we want to read.
257 */
258 sis_eeprom_putbyte(sc, addr);
259
260 /*
261 * Start reading bits from EEPROM.
262 */
263 for (i = 0x8000; i; i >>= 1) {
264 SIO_SET(SIS_EECTL_CLK);
265 sis_delay(sc);
266 if (CSR_READ_4(sc, SIS_EECTL) & SIS_EECTL_DOUT)
267 word |= i;
268 sis_delay(sc);
269 SIO_CLR(SIS_EECTL_CLK);
270 sis_delay(sc);
271 }
272
273 /* Turn off EEPROM access mode. */
274 sis_eeprom_idle(sc);
275
276 *dest = word;
277
278 return;
279 }
280
281 /*
282 * Read a sequence of words from the EEPROM.
283 */
284 static void sis_read_eeprom(sc, dest, off, cnt, swap)
285 struct sis_softc *sc;
286 caddr_t dest;
287 int off;
288 int cnt;
289 int swap;
290 {
291 int i;
292 u_int16_t word = 0, *ptr;
293
294 for (i = 0; i < cnt; i++) {
295 sis_eeprom_getword(sc, off + i, &word);
296 ptr = (u_int16_t *)(dest + (i * 2));
297 if (swap)
298 *ptr = ntohs(word);
299 else
300 *ptr = word;
301 }
302
303 return;
304 }
305
306 static u_int16_t sis_phy_readreg(sc, reg)
307 struct sis_softc *sc;
308 int reg;
309 {
310 int i, val;
311
312 if (sc->sis_type == SIS_TYPE_900 && sc->sis_phy_addr != 0)
313 return(0);
314
315 CSR_WRITE_4(sc, SIS_PHYCTL, (sc->sis_phy_addr << 11) |
316 (reg << 6) | SIS_PHYOP_READ);
317 SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
318
319 for (i = 0; i < SIS_TIMEOUT; i++) {
320 if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
321 break;
322 }
323
324 if (i == SIS_TIMEOUT) {
325 printf("sis%d: PHY failed to come ready\n", sc->sis_unit);
326 return(0);
327 }
328
329 val = (CSR_READ_4(sc, SIS_PHYCTL) >> 16) & 0xFFFF;
330
331 if (val == 0xFFFF)
332 return(0);
333
334 return(val);
335 }
336
337 static void sis_phy_writereg(sc, reg, data)
338 struct sis_softc *sc;
339 int reg, data;
340 {
341 int i;
342
343 if (sc->sis_type == SIS_TYPE_900 && sc->sis_phy_addr != 0)
344 return;
345
346 CSR_WRITE_4(sc, SIS_PHYCTL, (data << 16) | (sc->sis_phy_addr << 11) |
347 (reg << 6) | SIS_PHYOP_WRITE);
348 SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
349
350 for (i = 0; i < SIS_TIMEOUT; i++) {
351 if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
352 break;
353 }
354
355 if (i == SIS_TIMEOUT)
356 printf("sis%d: PHY failed to come ready\n", sc->sis_unit);
357
358 return;
359 }
360
361 static void sis_setcfg(sc, media)
362 struct sis_softc *sc;
363 u_int16_t media;
364 {
365 if (media & PHY_BMCR_DUPLEX) {
366 SIS_SETBIT(sc, SIS_TX_CFG,
367 (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
368 SIS_SETBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
369 } else {
370 SIS_CLRBIT(sc, SIS_TX_CFG,
371 (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
372 SIS_CLRBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
373 }
374
375 return;
376 }
377
378 /*
379 * Initiate an autonegotiation session.
380 */
381 static void sis_autoneg_xmit(sc)
382 struct sis_softc *sc;
383 {
384 u_int16_t phy_sts;
385
386 sis_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
387 DELAY(500);
388 while(sis_phy_readreg(sc, PHY_BMCR)
389 & PHY_BMCR_RESET);
390
391 phy_sts = sis_phy_readreg(sc, PHY_BMCR);
392 phy_sts |= PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR;
393 sis_phy_writereg(sc, PHY_BMCR, phy_sts);
394
395 return;
396 }
397
398 /*
399 * Invoke autonegotiation on a PHY.
400 */
401 static void sis_autoneg_mii(sc, flag, verbose)
402 struct sis_softc *sc;
403 int flag;
404 int verbose;
405 {
406 u_int16_t phy_sts = 0, media, advert, ability;
407 struct ifnet *ifp;
408 struct ifmedia *ifm;
409
410 ifm = &sc->ifmedia;
411 ifp = &sc->arpcom.ac_if;
412
413 ifm->ifm_media = IFM_ETHER | IFM_AUTO;
414
415 /*
416 * The 100baseT4 PHY on the 3c905-T4 has the 'autoneg supported'
417 * bit cleared in the status register, but has the 'autoneg enabled'
418 * bit set in the control register. This is a contradiction, and
419 * I'm not sure how to handle it. If you want to force an attempt
420 * to autoneg for 100baseT4 PHYs, #define FORCE_AUTONEG_TFOUR
421 * and see what happens.
422 */
423 #ifndef FORCE_AUTONEG_TFOUR
424 /*
425 * First, see if autoneg is supported. If not, there's
426 * no point in continuing.
427 */
428 phy_sts = sis_phy_readreg(sc, PHY_BMSR);
429 if (!(phy_sts & PHY_BMSR_CANAUTONEG)) {
430 if (verbose)
431 printf("sis%d: autonegotiation not supported\n",
432 sc->sis_unit);
433 ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
434 return;
435 }
436 #endif
437
438 switch (flag) {
439 case SIS_FLAG_FORCEDELAY:
440 /*
441 * XXX Never use this option anywhere but in the probe
442 * routine: making the kernel stop dead in its tracks
443 * for three whole seconds after we've gone multi-user
444 * is really bad manners.
445 */
446 sis_autoneg_xmit(sc);
447 DELAY(5000000);
448 break;
449 case SIS_FLAG_SCHEDDELAY:
450 /*
451 * Wait for the transmitter to go idle before starting
452 * an autoneg session, otherwise sis_start() may clobber
453 * our timeout, and we don't want to allow transmission
454 * during an autoneg session since that can screw it up.
455 */
456 if (sc->sis_cdata.sis_tx_cnt) {
457 sc->sis_want_auto = 1;
458 return;
459 }
460 sis_autoneg_xmit(sc);
461 ifp->if_timer = 5;
462 sc->sis_autoneg = 1;
463 sc->sis_want_auto = 0;
464 return;
465 break;
466 case SIS_FLAG_DELAYTIMEO:
467 ifp->if_timer = 0;
468 sc->sis_autoneg = 0;
469 break;
470 default:
471 printf("sis%d: invalid autoneg flag: %d\n", sc->sis_unit, flag);
472 return;
473 }
474
475 if (sis_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_AUTONEGCOMP) {
476 if (verbose)
477 printf("sis%d: autoneg complete, ", sc->sis_unit);
478 phy_sts = sis_phy_readreg(sc, PHY_BMSR);
479 } else {
480 if (verbose)
481 printf("sis%d: autoneg not complete, ", sc->sis_unit);
482 }
483
484 media = sis_phy_readreg(sc, PHY_BMCR);
485
486 /* Link is good. Report modes and set duplex mode. */
487 if (sis_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT) {
488 if (verbose)
489 printf("link status good ");
490 advert = sis_phy_readreg(sc, PHY_ANAR);
491 ability = sis_phy_readreg(sc, PHY_LPAR);
492
493 if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4) {
494 ifm->ifm_media = IFM_ETHER|IFM_100_T4;
495 media |= PHY_BMCR_SPEEDSEL;
496 media &= ~PHY_BMCR_DUPLEX;
497 printf("(100baseT4)\n");
498 } else if (advert & PHY_ANAR_100BTXFULL &&
499 ability & PHY_ANAR_100BTXFULL) {
500 ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX;
501 media |= PHY_BMCR_SPEEDSEL;
502 media |= PHY_BMCR_DUPLEX;
503 printf("(full-duplex, 100Mbps)\n");
504 } else if (advert & PHY_ANAR_100BTXHALF &&
505 ability & PHY_ANAR_100BTXHALF) {
506 ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX;
507 media |= PHY_BMCR_SPEEDSEL;
508 media &= ~PHY_BMCR_DUPLEX;
509 printf("(half-duplex, 100Mbps)\n");
510 } else if (advert & PHY_ANAR_10BTFULL &&
511 ability & PHY_ANAR_10BTFULL) {
512 ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX;
513 media &= ~PHY_BMCR_SPEEDSEL;
514 media |= PHY_BMCR_DUPLEX;
515 printf("(full-duplex, 10Mbps)\n");
516 } else if (advert & PHY_ANAR_10BTHALF &&
517 ability & PHY_ANAR_10BTHALF) {
518 ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
519 media &= ~PHY_BMCR_SPEEDSEL;
520 media &= ~PHY_BMCR_DUPLEX;
521 printf("(half-duplex, 10Mbps)\n");
522 }
523
524 media &= ~PHY_BMCR_AUTONEGENBL;
525
526 /* Set ASIC's duplex mode to match the PHY. */
527 sis_phy_writereg(sc, PHY_BMCR, media);
528 sis_setcfg(sc, media);
529 } else {
530 if (verbose)
531 printf("no carrier\n");
532 }
533
534 sis_init(sc);
535
536 if (sc->sis_tx_pend) {
537 sc->sis_autoneg = 0;
538 sc->sis_tx_pend = 0;
539 sis_start(ifp);
540 }
541
542 return;
543 }
544
545 static void sis_getmode_mii(sc)
546 struct sis_softc *sc;
547 {
548 u_int16_t bmsr;
549 struct ifnet *ifp;
550
551 ifp = &sc->arpcom.ac_if;
552
553 bmsr = sis_phy_readreg(sc, PHY_BMSR);
554 if (bootverbose)
555 printf("sis%d: PHY status word: %x\n", sc->sis_unit, bmsr);
556
557 /* fallback */
558 sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
559
560 if (bmsr & PHY_BMSR_10BTHALF) {
561 if (bootverbose)
562 printf("sis%d: 10Mbps half-duplex mode supported\n",
563 sc->sis_unit);
564 ifmedia_add(&sc->ifmedia,
565 IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
566 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
567 }
568
569 if (bmsr & PHY_BMSR_10BTFULL) {
570 if (bootverbose)
571 printf("sis%d: 10Mbps full-duplex mode supported\n",
572 sc->sis_unit);
573 ifmedia_add(&sc->ifmedia,
574 IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
575 sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX;
576 }
577
578 if (bmsr & PHY_BMSR_100BTXHALF) {
579 if (bootverbose)
580 printf("sis%d: 100Mbps half-duplex mode supported\n",
581 sc->sis_unit);
582 ifp->if_baudrate = 100000000;
583 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
584 ifmedia_add(&sc->ifmedia,
585 IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL);
586 sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX;
587 }
588
589 if (bmsr & PHY_BMSR_100BTXFULL) {
590 if (bootverbose)
591 printf("sis%d: 100Mbps full-duplex mode supported\n",
592 sc->sis_unit);
593 ifp->if_baudrate = 100000000;
594 ifmedia_add(&sc->ifmedia,
595 IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
596 sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX;
597 }
598
599 /* Some also support 100BaseT4. */
600 if (bmsr & PHY_BMSR_100BT4) {
601 if (bootverbose)
602 printf("sis%d: 100baseT4 mode supported\n", sc->sis_unit);
603 ifp->if_baudrate = 100000000;
604 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_T4, 0, NULL);
605 sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_T4;
606 #ifdef FORCE_AUTONEG_TFOUR
607 if (bootverbose)
608 printf("sis%d: forcing on autoneg support for BT4\n",
609 sc->sis_unit);
610 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0 NULL):
611 sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO;
612 #endif
613 }
614
615 if (bmsr & PHY_BMSR_CANAUTONEG) {
616 if (bootverbose)
617 printf("sis%d: autoneg supported\n", sc->sis_unit);
618 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
619 sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO;
620 }
621
622 return;
623 }
624
625 /*
626 * Set speed and duplex mode.
627 */
628 static void sis_setmode_mii(sc, media)
629 struct sis_softc *sc;
630 int media;
631 {
632 u_int16_t bmcr;
633 struct ifnet *ifp;
634
635 ifp = &sc->arpcom.ac_if;
636
637 /*
638 * If an autoneg session is in progress, stop it.
639 */
640 if (sc->sis_autoneg) {
641 printf("sis%d: canceling autoneg session\n", sc->sis_unit);
642 ifp->if_timer = sc->sis_autoneg = sc->sis_want_auto = 0;
643 bmcr = sis_phy_readreg(sc, PHY_BMCR);
644 bmcr &= ~PHY_BMCR_AUTONEGENBL;
645 sis_phy_writereg(sc, PHY_BMCR, bmcr);
646 }
647
648 printf("sis%d: selecting MII, ", sc->sis_unit);
649
650 bmcr = sis_phy_readreg(sc, PHY_BMCR);
651
652 bmcr &= ~(PHY_BMCR_AUTONEGENBL|PHY_BMCR_SPEEDSEL|
653 PHY_BMCR_DUPLEX|PHY_BMCR_LOOPBK);
654
655 if (IFM_SUBTYPE(media) == IFM_100_T4) {
656 printf("100Mbps/T4, half-duplex\n");
657 bmcr |= PHY_BMCR_SPEEDSEL;
658 bmcr &= ~PHY_BMCR_DUPLEX;
659 }
660
661 if (IFM_SUBTYPE(media) == IFM_100_TX) {
662 printf("100Mbps, ");
663 bmcr |= PHY_BMCR_SPEEDSEL;
664 }
665
666 if (IFM_SUBTYPE(media) == IFM_10_T) {
667 printf("10Mbps, ");
668 bmcr &= ~PHY_BMCR_SPEEDSEL;
669 }
670
671 if ((media & IFM_GMASK) == IFM_FDX) {
672 printf("full duplex\n");
673 bmcr |= PHY_BMCR_DUPLEX;
674 } else {
675 printf("half duplex\n");
676 bmcr &= ~PHY_BMCR_DUPLEX;
677 }
678
679 sis_phy_writereg(sc, PHY_BMCR, bmcr);
680 sis_setcfg(sc, bmcr);
681
682 return;
683 }
684
685 static u_int32_t sis_calchash(addr)
686 caddr_t addr;
687 {
688 u_int32_t crc, carry;
689 int i, j;
690 u_int8_t c;
691
692 /* Compute CRC for the address value. */
693 crc = 0xFFFFFFFF; /* initial value */
694
695 for (i = 0; i < 6; i++) {
696 c = *(addr + i);
697 for (j = 0; j < 8; j++) {
698 carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
699 crc <<= 1;
700 c >>= 1;
701 if (carry)
702 crc = (crc ^ 0x04c11db6) | carry;
703 }
704 }
705
706 /* return the filter bit position */
707 return((crc >> 25) & 0x0000007F);
708 }
709
710 static void sis_setmulti(sc)
711 struct sis_softc *sc;
712 {
713 struct ifnet *ifp;
714 struct ifmultiaddr *ifma;
715 u_int32_t h = 0, i, filtsave;
716
717 ifp = &sc->arpcom.ac_if;
718
719 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
720 SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
721 return;
722 }
723
724 SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
725
726 filtsave = CSR_READ_4(sc, SIS_RXFILT_CTL);
727
728 /* first, zot all the existing hash bits */
729 for (i = 0; i < 8; i++) {
730 CSR_WRITE_4(sc, SIS_RXFILT_CTL, (4 + ((i * 16) >> 4)) << 16);
731 CSR_WRITE_4(sc, SIS_RXFILT_DATA, 0);
732 }
733
734 /* now program new ones */
735 for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
736 ifma = ifma->ifma_link.le_next) {
737 if (ifma->ifma_addr->sa_family != AF_LINK)
738 continue;
739 h = sis_calchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
740 CSR_WRITE_4(sc, SIS_RXFILT_CTL, (4 + (h >> 4)) << 16);
741 SIS_SETBIT(sc, SIS_RXFILT_DATA, (1 << (h & 0xF)));
742 }
743
744 CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave);
745
746 return;
747 }
748
749 static void sis_reset(sc)
750 struct sis_softc *sc;
751 {
752 register int i;
753
754 SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RESET);
755
756 for (i = 0; i < SIS_TIMEOUT; i++) {
757 if (!(CSR_READ_4(sc, SIS_CSR) & SIS_CSR_RESET))
758 break;
759 }
760
761 if (i == SIS_TIMEOUT)
762 printf("sis%d: reset never completed\n", sc->sis_unit);
763
764 /* Wait a little while for the chip to get its brains in order. */
765 DELAY(1000);
766 return;
767 }
768
769 /*
770 * Probe for a SiS chip. Check the PCI vendor and device
771 * IDs against our list and return a device name if we find a match.
772 */
773 static const char *
774 sis_probe(config_id, device_id)
775 pcici_t config_id;
776 pcidi_t device_id;
777 {
778 struct sis_type *t;
779
780 t = sis_devs;
781
782 while(t->sis_name != NULL) {
783 if ((device_id & 0xFFFF) == t->sis_vid &&
784 ((device_id >> 16) & 0xFFFF) == t->sis_did) {
785 return(t->sis_name);
786 }
787 t++;
788 }
789
790 return(NULL);
791 }
792
793 /*
794 * Attach the interface. Allocate softc structures, do ifmedia
795 * setup and ethernet/BPF attach.
796 */
797 static void
798 sis_attach(config_id, unit)
799 pcici_t config_id;
800 int unit;
801 {
802 int s, i;
803 #ifndef SIS_USEIOSPACE
804 vm_offset_t pbase, vbase;
805 #endif
806 u_char eaddr[ETHER_ADDR_LEN];
807 u_int32_t command;
808 struct sis_softc *sc;
809 struct ifnet *ifp;
810 int media = IFM_ETHER|IFM_100_TX|IFM_FDX;
811 struct sis_type *p;
812 u_int16_t phy_vid, phy_did, phy_sts;
813 u_int16_t did;
814
815 s = splimp();
816
817 sc = malloc(sizeof(struct sis_softc), M_DEVBUF, M_NOWAIT);
818 if (sc == NULL) {
819 printf("sis%d: no memory for softc struct!\n", unit);
820 goto fail;
821 }
822 bzero(sc, sizeof(struct sis_softc));
823
824 did = (pci_conf_read(config_id, SIS_PCI_VENDOR_ID) >> 16) & 0xFFFF;
825 if (did == SIS_DEVICEID_900)
826 sc->sis_type = SIS_TYPE_900;
827 if (did == SIS_DEVICEID_7016)
828 sc->sis_type = SIS_TYPE_7016;
829
830 /*
831 * Handle power management nonsense.
832 */
833
834 command = pci_conf_read(config_id, SIS_PCI_CAPID) & 0x000000FF;
835 if (command == 0x01) {
836
837 command = pci_conf_read(config_id, SIS_PCI_PWRMGMTCTRL);
838 if (command & SIS_PSTATE_MASK) {
839 u_int32_t iobase, membase, irq;
840
841 /* Save important PCI config data. */
842 iobase = pci_conf_read(config_id, SIS_PCI_LOIO);
843 membase = pci_conf_read(config_id, SIS_PCI_LOMEM);
844 irq = pci_conf_read(config_id, SIS_PCI_INTLINE);
845
846 /* Reset the power state. */
847 printf("sis%d: chip is in D%d power mode "
848 "-- setting to D0\n", unit, command & SIS_PSTATE_MASK);
849 command &= 0xFFFFFFFC;
850 pci_conf_write(config_id, SIS_PCI_PWRMGMTCTRL, command);
851
852 /* Restore PCI config data. */
853 pci_conf_write(config_id, SIS_PCI_LOIO, iobase);
854 pci_conf_write(config_id, SIS_PCI_LOMEM, membase);
855 pci_conf_write(config_id, SIS_PCI_INTLINE, irq);
856 }
857 }
858
859 /*
860 * Map control/status registers.
861 */
862 command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
863 command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
864 pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, command);
865 command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
866
867 #ifdef SIS_USEIOSPACE
868 if (!(command & PCIM_CMD_PORTEN)) {
869 printf("sis%d: failed to enable I/O ports!\n", unit);
870 free(sc, M_DEVBUF);
871 goto fail;
872 }
873
874 if (!pci_map_port(config_id, SIS_PCI_LOIO,
875 (u_short *)&(sc->sis_bhandle))) {
876 printf ("sis%d: couldn't map ports\n", unit);
877 goto fail;
878 }
879 #ifdef __i386__
880 sc->sis_btag = I386_BUS_SPACE_IO;
881 #endif
882 #ifdef __alpha__
883 sc->sis_btag = ALPHA_BUS_SPACE_IO;
884 #endif
885 #else
886 if (!(command & PCIM_CMD_MEMEN)) {
887 printf("sis%d: failed to enable memory mapping!\n", unit);
888 goto fail;
889 }
890
891 if (!pci_map_mem(config_id, SIS_PCI_LOMEM, &vbase, &pbase)) {
892 printf ("sis%d: couldn't map memory\n", unit);
893 goto fail;
894 }
895 #ifdef __i386__
896 sc->sis_btag = I386_BUS_SPACE_MEM;
897 #endif
898 #ifdef __alpha__
899 sc->sis_btag = ALPHA_BUS_SPACE_MEM;
900 #endif
901 sc->sis_bhandle = vbase;
902 #endif
903
904 /* Allocate interrupt */
905 if (!pci_map_int(config_id, sis_intr, sc, &net_imask)) {
906 printf("sis%d: couldn't map interrupt\n", unit);
907 goto fail;
908 }
909
910 /* Reset the adapter. */
911 sis_reset(sc);
912
913 /*
914 * Get station address from the EEPROM.
915 */
916 sis_read_eeprom(sc, (caddr_t)&eaddr, SIS_EE_NODEADDR, 3, 0);
917
918 /*
919 * A SiS chip was detected. Inform the world.
920 */
921 printf("sis%d: Ethernet address: %6D\n", unit, eaddr, ":");
922
923 sc->sis_unit = unit;
924 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
925
926 sc->sis_ldata = contigmalloc(sizeof(struct sis_list_data), M_DEVBUF,
927 M_NOWAIT, 0x100000, 0xffffffff, PAGE_SIZE, 0);
928
929 if (sc->sis_ldata == NULL) {
930 printf("sis%d: no memory for list buffers!\n", unit);
931 free(sc, M_DEVBUF);
932 goto fail;
933 }
934 bzero(sc->sis_ldata, sizeof(struct sis_list_data));
935
936 ifp = &sc->arpcom.ac_if;
937 ifp->if_softc = sc;
938 ifp->if_unit = unit;
939 ifp->if_name = "sis";
940 ifp->if_mtu = ETHERMTU;
941 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
942 ifp->if_ioctl = sis_ioctl;
943 ifp->if_output = ether_output;
944 ifp->if_start = sis_start;
945 ifp->if_watchdog = sis_watchdog;
946 ifp->if_init = sis_init;
947 ifp->if_baudrate = 10000000;
948 ifp->if_snd.ifq_maxlen = SIS_TX_LIST_CNT - 1;
949
950 if (bootverbose)
951 printf("sis%d: probing for a PHY\n", sc->sis_unit);
952 for (i = SIS_PHYADDR_MIN; i < SIS_PHYADDR_MAX + 1; i++) {
953 if (bootverbose)
954 printf("sis%d: checking address: %d\n",
955 sc->sis_unit, i);
956 sc->sis_phy_addr = i;
957 sis_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
958 DELAY(500);
959 while(sis_phy_readreg(sc, PHY_BMCR)
960 & PHY_BMCR_RESET);
961 if ((phy_sts = sis_phy_readreg(sc, PHY_BMSR)))
962 break;
963 }
964 if (phy_sts) {
965 phy_vid = sis_phy_readreg(sc, PHY_VENID);
966 phy_did = sis_phy_readreg(sc, PHY_DEVID);
967 if (bootverbose)
968 printf("sis%d: found PHY at address %d, ",
969 sc->sis_unit, sc->sis_phy_addr);
970 if (bootverbose)
971 printf("vendor id: %x device id: %x\n",
972 phy_vid, phy_did);
973 p = sis_phys;
974 while(p->sis_vid) {
975 if (phy_vid == p->sis_vid &&
976 (phy_did | 0x000F) == p->sis_did) {
977 sc->sis_pinfo = p;
978 break;
979 }
980 p++;
981 }
982 if (sc->sis_pinfo == NULL)
983 sc->sis_pinfo = &sis_phys[PHY_UNKNOWN];
984 if (bootverbose)
985 printf("sis%d: PHY type: %s\n",
986 sc->sis_unit, sc->sis_pinfo->sis_name);
987 } else {
988 printf("sis%d: MII without any phy!\n", sc->sis_unit);
989 free(sc->sis_ldata, M_DEVBUF);
990 free(sc, M_DEVBUF);
991 goto fail;
992 }
993
994 /*
995 * Do ifmedia setup.
996 */
997 ifmedia_init(&sc->ifmedia, 0, sis_ifmedia_upd, sis_ifmedia_sts);
998
999 sis_getmode_mii(sc);
1000 sis_autoneg_mii(sc, SIS_FLAG_FORCEDELAY, 1);
1001
1002 media = sc->ifmedia.ifm_media;
1003 sis_stop(sc);
1004
1005 ifmedia_set(&sc->ifmedia, media);
1006
1007 /*
1008 * Call MI attach routines.
1009 */
1010 if_attach(ifp);
1011 ether_ifattach(ifp);
1012
1013 #if NBPFILTER > 0
1014 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
1015 #endif
1016 at_shutdown(sis_shutdown, sc, SHUTDOWN_POST_SYNC);
1017
1018 fail:
1019 splx(s);
1020 return;
1021 }
1022
1023
1024 /*
1025 * Initialize the transmit descriptors.
1026 */
1027 static int sis_list_tx_init(sc)
1028 struct sis_softc *sc;
1029 {
1030 struct sis_list_data *ld;
1031 struct sis_ring_data *cd;
1032 int i;
1033
1034 cd = &sc->sis_cdata;
1035 ld = sc->sis_ldata;
1036
1037 for (i = 0; i < SIS_TX_LIST_CNT; i++) {
1038 if (i == (SIS_TX_LIST_CNT - 1)) {
1039 ld->sis_tx_list[i].sis_nextdesc =
1040 &ld->sis_tx_list[0];
1041 ld->sis_tx_list[i].sis_next =
1042 vtophys(&ld->sis_tx_list[0]);
1043 } else {
1044 ld->sis_tx_list[i].sis_nextdesc =
1045 &ld->sis_tx_list[i + 1];
1046 ld->sis_tx_list[i].sis_next =
1047 vtophys(&ld->sis_tx_list[i + 1]);
1048 }
1049 ld->sis_tx_list[i].sis_mbuf = NULL;
1050 ld->sis_tx_list[i].sis_ptr = 0;
1051 ld->sis_tx_list[i].sis_ctl = 0;
1052 }
1053
1054 cd->sis_tx_prod = cd->sis_tx_cons = cd->sis_tx_cnt = 0;
1055
1056 return(0);
1057 }
1058
1059
1060 /*
1061 * Initialize the RX descriptors and allocate mbufs for them. Note that
1062 * we arrange the descriptors in a closed ring, so that the last descriptor
1063 * points back to the first.
1064 */
1065 static int sis_list_rx_init(sc)
1066 struct sis_softc *sc;
1067 {
1068 struct sis_list_data *ld;
1069 struct sis_ring_data *cd;
1070 int i;
1071
1072 ld = sc->sis_ldata;
1073 cd = &sc->sis_cdata;
1074
1075 for (i = 0; i < SIS_RX_LIST_CNT; i++) {
1076 if (sis_newbuf(sc, &ld->sis_rx_list[i], NULL) == ENOBUFS)
1077 return(ENOBUFS);
1078 if (i == (SIS_RX_LIST_CNT - 1)) {
1079 ld->sis_rx_list[i].sis_nextdesc =
1080 &ld->sis_rx_list[0];
1081 ld->sis_rx_list[i].sis_next =
1082 vtophys(&ld->sis_rx_list[0]);
1083 } else {
1084 ld->sis_rx_list[i].sis_nextdesc =
1085 &ld->sis_rx_list[i + 1];
1086 ld->sis_rx_list[i].sis_next =
1087 vtophys(&ld->sis_rx_list[i + 1]);
1088 }
1089 }
1090
1091 cd->sis_rx_prod = 0;
1092
1093 return(0);
1094 }
1095
1096 /*
1097 * Initialize an RX descriptor and attach an MBUF cluster.
1098 */
1099 static int sis_newbuf(sc, c, m)
1100 struct sis_softc *sc;
1101 struct sis_desc *c;
1102 struct mbuf *m;
1103 {
1104 struct mbuf *m_new = NULL;
1105
1106 if (m == NULL) {
1107 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1108 if (m_new == NULL) {
1109 printf("sis%d: no memory for rx list "
1110 "-- packet dropped!\n", sc->sis_unit);
1111 return(ENOBUFS);
1112 }
1113
1114 MCLGET(m_new, M_DONTWAIT);
1115 if (!(m_new->m_flags & M_EXT)) {
1116 printf("sis%d: no memory for rx list "
1117 "-- packet dropped!\n", sc->sis_unit);
1118 m_freem(m_new);
1119 return(ENOBUFS);
1120 }
1121 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1122 } else {
1123 m_new = m;
1124 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1125 m_new->m_data = m_new->m_ext.ext_buf;
1126 }
1127
1128 m_adj(m_new, sizeof(u_int64_t));
1129
1130 c->sis_mbuf = m_new;
1131 c->sis_ptr = vtophys(mtod(m_new, caddr_t));
1132 c->sis_ctl = SIS_RXLEN;
1133
1134 return(0);
1135 }
1136
1137 /*
1138 * A frame has been uploaded: pass the resulting mbuf chain up to
1139 * the higher level protocols.
1140 */
1141 static void sis_rxeof(sc)
1142 struct sis_softc *sc;
1143 {
1144 struct ether_header *eh;
1145 struct mbuf *m;
1146 struct ifnet *ifp;
1147 struct sis_desc *cur_rx;
1148 int i, total_len = 0;
1149 u_int32_t rxstat;
1150
1151 ifp = &sc->arpcom.ac_if;
1152 i = sc->sis_cdata.sis_rx_prod;
1153
1154 while(SIS_OWNDESC(&sc->sis_ldata->sis_rx_list[i])) {
1155 struct mbuf *m0 = NULL;
1156
1157 cur_rx = &sc->sis_ldata->sis_rx_list[i];
1158 rxstat = cur_rx->sis_rxstat;
1159 m = cur_rx->sis_mbuf;
1160 cur_rx->sis_mbuf = NULL;
1161 total_len = SIS_RXBYTES(cur_rx);
1162 SIS_INC(i, SIS_RX_LIST_CNT);
1163
1164 /*
1165 * If an error occurs, update stats, clear the
1166 * status word and leave the mbuf cluster in place:
1167 * it should simply get re-used next time this descriptor
1168 * comes up in the ring.
1169 */
1170 if (!(rxstat & SIS_CMDSTS_PKT_OK)) {
1171 ifp->if_ierrors++;
1172 if (rxstat & SIS_RXSTAT_COLL)
1173 ifp->if_collisions++;
1174 sis_newbuf(sc, cur_rx, m);
1175 continue;
1176 }
1177
1178 /* No errors; receive the packet. */
1179 m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
1180 total_len + ETHER_ALIGN, 0, ifp, NULL);
1181 sis_newbuf(sc, cur_rx, m);
1182 if (m0 == NULL) {
1183 ifp->if_ierrors++;
1184 continue;
1185 }
1186 m_adj(m0, ETHER_ALIGN);
1187 m = m0;
1188
1189 ifp->if_ipackets++;
1190 eh = mtod(m, struct ether_header *);
1191 #if NBPFILTER > 0
1192 /*
1193 * Handle BPF listeners. Let the BPF user see the packet, but
1194 * don't pass it up to the ether_input() layer unless it's
1195 * a broadcast packet, multicast packet, matches our ethernet
1196 * address or the interface is in promiscuous mode.
1197 */
1198 if (ifp->if_bpf) {
1199 bpf_mtap(ifp, m);
1200 if (ifp->if_flags & IFF_PROMISC &&
1201 (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
1202 ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
1203 m_freem(m);
1204 continue;
1205 }
1206 }
1207 #endif
1208 /* Remove header from mbuf and pass it on. */
1209 m_adj(m, sizeof(struct ether_header));
1210 ether_input(ifp, eh, m);
1211 }
1212
1213 sc->sis_cdata.sis_rx_prod = i;
1214
1215 return;
1216 }
1217
1218 void sis_rxeoc(sc)
1219 struct sis_softc *sc;
1220 {
1221 sis_rxeof(sc);
1222 sis_init(sc);
1223 return;
1224 }
1225
1226 /*
1227 * A frame was downloaded to the chip. It's safe for us to clean up
1228 * the list buffers.
1229 */
1230
1231 static void sis_txeof(sc)
1232 struct sis_softc *sc;
1233 {
1234 struct sis_desc *cur_tx = NULL;
1235 struct ifnet *ifp;
1236 u_int32_t idx;
1237
1238 ifp = &sc->arpcom.ac_if;
1239
1240 /* Clear the timeout timer. */
1241 ifp->if_timer = 0;
1242
1243 /*
1244 * Go through our tx list and free mbufs for those
1245 * frames that have been transmitted.
1246 */
1247 idx = sc->sis_cdata.sis_tx_cons;
1248 while (idx != sc->sis_cdata.sis_tx_prod) {
1249 cur_tx = &sc->sis_ldata->sis_tx_list[idx];
1250
1251 if (SIS_OWNDESC(cur_tx))
1252 break;
1253
1254 if (cur_tx->sis_ctl & SIS_CMDSTS_MORE) {
1255 sc->sis_cdata.sis_tx_cnt--;
1256 SIS_INC(idx, SIS_TX_LIST_CNT);
1257 continue;
1258 }
1259
1260 if (!(cur_tx->sis_ctl & SIS_CMDSTS_PKT_OK)) {
1261 ifp->if_oerrors++;
1262 if (cur_tx->sis_txstat & SIS_TXSTAT_EXCESSCOLLS)
1263 ifp->if_collisions++;
1264 if (cur_tx->sis_txstat & SIS_TXSTAT_OUTOFWINCOLL)
1265 ifp->if_collisions++;
1266 }
1267
1268 ifp->if_collisions +=
1269 (cur_tx->sis_txstat & SIS_TXSTAT_COLLCNT) >> 16;
1270
1271 ifp->if_opackets++;
1272 if (cur_tx->sis_mbuf != NULL) {
1273 m_freem(cur_tx->sis_mbuf);
1274 cur_tx->sis_mbuf = NULL;
1275 }
1276
1277 sc->sis_cdata.sis_tx_cnt--;
1278 SIS_INC(idx, SIS_TX_LIST_CNT);
1279 ifp->if_timer = 0;
1280 }
1281
1282 sc->sis_cdata.sis_tx_cons = idx;
1283
1284 if (cur_tx != NULL)
1285 ifp->if_flags &= ~IFF_OACTIVE;
1286
1287 return;
1288 }
1289
1290 static void sis_intr(arg)
1291 void *arg;
1292 {
1293 struct sis_softc *sc;
1294 struct ifnet *ifp;
1295 u_int32_t status;
1296
1297 sc = arg;
1298 ifp = &sc->arpcom.ac_if;
1299
1300 /* Supress unwanted interrupts */
1301 if (!(ifp->if_flags & IFF_UP)) {
1302 sis_stop(sc);
1303 return;
1304 }
1305
1306 /* Disable interrupts. */
1307 CSR_WRITE_4(sc, SIS_IER, 0);
1308
1309 for (;;) {
1310 /* Reading the ISR register clears all interrupts. */
1311 status = CSR_READ_4(sc, SIS_ISR);
1312
1313 if ((status & SIS_INTRS) == 0)
1314 break;
1315
1316 if ((status & SIS_ISR_TX_OK) ||
1317 (status & SIS_ISR_TX_ERR) ||
1318 (status & SIS_ISR_TX_IDLE))
1319 sis_txeof(sc);
1320
1321 if (status & SIS_ISR_RX_OK)
1322 sis_rxeof(sc);
1323
1324 if ((status & SIS_ISR_RX_ERR) ||
1325 (status & SIS_ISR_RX_OFLOW)) {
1326 sis_rxeoc(sc);
1327 }
1328
1329 if (status & SIS_ISR_SYSERR) {
1330 sis_reset(sc);
1331 sis_init(sc);
1332 }
1333 }
1334
1335 /* Re-enable interrupts. */
1336 CSR_WRITE_4(sc, SIS_IER, 1);
1337
1338 if (ifp->if_snd.ifq_head != NULL)
1339 sis_start(ifp);
1340
1341 return;
1342 }
1343
1344 /*
1345 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
1346 * pointers to the fragment pointers.
1347 */
1348 static int sis_encap(sc, m_head, txidx)
1349 struct sis_softc *sc;
1350 struct mbuf *m_head;
1351 u_int32_t *txidx;
1352 {
1353 struct sis_desc *f = NULL;
1354 struct mbuf *m;
1355 int frag, cur, cnt = 0;
1356
1357 /*
1358 * Start packing the mbufs in this chain into
1359 * the fragment pointers. Stop when we run out
1360 * of fragments or hit the end of the mbuf chain.
1361 */
1362 m = m_head;
1363 cur = frag = *txidx;
1364
1365 for (m = m_head; m != NULL; m = m->m_next) {
1366 if (m->m_len != 0) {
1367 if ((SIS_TX_LIST_CNT -
1368 (sc->sis_cdata.sis_tx_cnt + cnt)) < 2)
1369 return(ENOBUFS);
1370 f = &sc->sis_ldata->sis_tx_list[frag];
1371 f->sis_ctl = SIS_CMDSTS_MORE | m->m_len;
1372 f->sis_ptr = vtophys(mtod(m, vm_offset_t));
1373 if (cnt != 0)
1374 f->sis_ctl |= SIS_CMDSTS_OWN;
1375 cur = frag;
1376 SIS_INC(frag, SIS_TX_LIST_CNT);
1377 cnt++;
1378 }
1379 }
1380
1381 if (m != NULL)
1382 return(ENOBUFS);
1383
1384 sc->sis_ldata->sis_tx_list[cur].sis_mbuf = m_head;
1385 sc->sis_ldata->sis_tx_list[cur].sis_ctl &= ~SIS_CMDSTS_MORE;
1386 sc->sis_ldata->sis_tx_list[*txidx].sis_ctl |= SIS_CMDSTS_OWN;
1387 sc->sis_cdata.sis_tx_cnt += cnt;
1388 *txidx = frag;
1389
1390 return(0);
1391 }
1392
1393 /*
1394 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
1395 * to the mbuf data regions directly in the transmit lists. We also save a
1396 * copy of the pointers since the transmit list fragment pointers are
1397 * physical addresses.
1398 */
1399
1400 static void sis_start(ifp)
1401 struct ifnet *ifp;
1402 {
1403 struct sis_softc *sc;
1404 struct mbuf *m_head = NULL;
1405 u_int32_t idx;
1406
1407 sc = ifp->if_softc;
1408
1409 if (sc->sis_autoneg)
1410 return;
1411
1412 idx = sc->sis_cdata.sis_tx_prod;
1413
1414 if (ifp->if_flags & IFF_OACTIVE)
1415 return;
1416
1417 while(sc->sis_ldata->sis_tx_list[idx].sis_mbuf == NULL) {
1418 IF_DEQUEUE(&ifp->if_snd, m_head);
1419 if (m_head == NULL)
1420 break;
1421
1422 if (sis_encap(sc, m_head, &idx)) {
1423 IF_PREPEND(&ifp->if_snd, m_head);
1424 ifp->if_flags |= IFF_OACTIVE;
1425 break;
1426 }
1427
1428 #if NBPFILTER > 0
1429 /*
1430 * If there's a BPF listener, bounce a copy of this frame
1431 * to him.
1432 */
1433 if (ifp->if_bpf)
1434 bpf_mtap(ifp, m_head);
1435 #endif
1436 }
1437
1438 /* Transmit */
1439 sc->sis_cdata.sis_tx_prod = idx;
1440 SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_ENABLE);
1441
1442 /*
1443 * Set a timeout in case the chip goes out to lunch.
1444 */
1445 ifp->if_timer = 5;
1446
1447 return;
1448 }
1449
1450 static void sis_init(xsc)
1451 void *xsc;
1452 {
1453 struct sis_softc *sc = xsc;
1454 struct ifnet *ifp = &sc->arpcom.ac_if;
1455 int s;
1456 u_int16_t phy_bmcr;
1457
1458 if (sc->sis_autoneg)
1459 return;
1460
1461 s = splimp();
1462
1463 /*
1464 * Cancel pending I/O and free all RX/TX buffers.
1465 */
1466 sis_stop(sc);
1467
1468 phy_bmcr = sis_phy_readreg(sc, PHY_BMCR);
1469
1470 /* Set MAC address */
1471 CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0);
1472 CSR_WRITE_4(sc, SIS_RXFILT_DATA,
1473 ((u_int16_t *)sc->arpcom.ac_enaddr)[0]);
1474 CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR1);
1475 CSR_WRITE_4(sc, SIS_RXFILT_DATA,
1476 ((u_int16_t *)sc->arpcom.ac_enaddr)[1]);
1477 CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2);
1478 CSR_WRITE_4(sc, SIS_RXFILT_DATA,
1479 ((u_int16_t *)sc->arpcom.ac_enaddr)[2]);
1480
1481 /* Init circular RX list. */
1482 if (sis_list_rx_init(sc) == ENOBUFS) {
1483 printf("sis%d: initialization failed: no "
1484 "memory for rx buffers\n", sc->sis_unit);
1485 sis_stop(sc);
1486 (void)splx(s);
1487 return;
1488 }
1489
1490 /*
1491 * Init tx descriptors.
1492 */
1493 sis_list_tx_init(sc);
1494
1495 /* If we want promiscuous mode, set the allframes bit. */
1496 if (ifp->if_flags & IFF_PROMISC) {
1497 SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
1498 } else {
1499 SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
1500 }
1501
1502 /*
1503 * Set the capture broadcast bit to capture broadcast frames.
1504 */
1505 if (ifp->if_flags & IFF_BROADCAST) {
1506 SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
1507 } else {
1508 SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
1509 }
1510
1511 /*
1512 * Load the multicast filter.
1513 */
1514 sis_setmulti(sc);
1515
1516 /* Turn the receive filter on */
1517 SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ENABLE);
1518
1519 /*
1520 * Load the address of the RX and TX lists.
1521 */
1522 CSR_WRITE_4(sc, SIS_RX_LISTPTR,
1523 vtophys(&sc->sis_ldata->sis_rx_list[0]));
1524 CSR_WRITE_4(sc, SIS_TX_LISTPTR,
1525 vtophys(&sc->sis_ldata->sis_tx_list[0]));
1526
1527 /* Set RX configuration */
1528 CSR_WRITE_4(sc, SIS_RX_CFG, SIS_RXCFG);
1529 /* Set TX configuration */
1530 CSR_WRITE_4(sc, SIS_TX_CFG, SIS_TXCFG);
1531
1532 /*
1533 * Enable interrupts.
1534 */
1535 CSR_WRITE_4(sc, SIS_IMR, SIS_INTRS);
1536 CSR_WRITE_4(sc, SIS_IER, 1);
1537
1538 /* Enable receiver and transmitter. */
1539 SIS_CLRBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
1540 SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
1541
1542 sis_phy_writereg(sc, PHY_BMCR, phy_bmcr);
1543
1544 ifp->if_flags |= IFF_RUNNING;
1545 ifp->if_flags &= ~IFF_OACTIVE;
1546
1547 (void)splx(s);
1548
1549 return;
1550 }
1551
1552 /*
1553 * Set media options.
1554 */
1555 static int sis_ifmedia_upd(ifp)
1556 struct ifnet *ifp;
1557 {
1558 struct sis_softc *sc;
1559 struct ifmedia *ifm;
1560
1561 sc = ifp->if_softc;
1562 ifm = &sc->ifmedia;
1563
1564 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1565 return(EINVAL);
1566
1567 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
1568 sis_autoneg_mii(sc, SIS_FLAG_SCHEDDELAY, 1);
1569 else {
1570 sis_setmode_mii(sc, ifm->ifm_media);
1571 }
1572
1573 return(0);
1574 }
1575
1576 /*
1577 * Report current media status.
1578 */
1579 static void sis_ifmedia_sts(ifp, ifmr)
1580 struct ifnet *ifp;
1581 struct ifmediareq *ifmr;
1582 {
1583 struct sis_softc *sc;
1584 u_int16_t advert = 0, ability = 0;
1585
1586 sc = ifp->if_softc;
1587
1588 ifmr->ifm_active = IFM_ETHER;
1589
1590 if (!(sis_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_AUTONEGENBL)) {
1591 if (sis_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_SPEEDSEL)
1592 ifmr->ifm_active = IFM_ETHER|IFM_100_TX;
1593 else
1594 ifmr->ifm_active = IFM_ETHER|IFM_10_T;
1595 if (sis_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_DUPLEX)
1596 ifmr->ifm_active |= IFM_FDX;
1597 else
1598 ifmr->ifm_active |= IFM_HDX;
1599 return;
1600 }
1601
1602 ability = sis_phy_readreg(sc, PHY_LPAR);
1603 advert = sis_phy_readreg(sc, PHY_ANAR);
1604 if (advert & PHY_ANAR_100BT4 &&
1605 ability & PHY_ANAR_100BT4) {
1606 ifmr->ifm_active = IFM_ETHER|IFM_100_T4;
1607 } else if (advert & PHY_ANAR_100BTXFULL &&
1608 ability & PHY_ANAR_100BTXFULL) {
1609 ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_FDX;
1610 } else if (advert & PHY_ANAR_100BTXHALF &&
1611 ability & PHY_ANAR_100BTXHALF) {
1612 ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_HDX;
1613 } else if (advert & PHY_ANAR_10BTFULL &&
1614 ability & PHY_ANAR_10BTFULL) {
1615 ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_FDX;
1616 } else if (advert & PHY_ANAR_10BTHALF &&
1617 ability & PHY_ANAR_10BTHALF) {
1618 ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_HDX;
1619 }
1620
1621 return;
1622 }
1623
1624 static int sis_ioctl(ifp, command, data)
1625 struct ifnet *ifp;
1626 u_long command;
1627 caddr_t data;
1628 {
1629 struct sis_softc *sc = ifp->if_softc;
1630 struct ifreq *ifr = (struct ifreq *) data;
1631 int s, error = 0;
1632
1633 s = splimp();
1634
1635 switch(command) {
1636 case SIOCSIFADDR:
1637 case SIOCGIFADDR:
1638 case SIOCSIFMTU:
1639 error = ether_ioctl(ifp, command, data);
1640 break;
1641 case SIOCSIFFLAGS:
1642 if (ifp->if_flags & IFF_UP) {
1643 sis_init(sc);
1644 } else {
1645 if (ifp->if_flags & IFF_RUNNING)
1646 sis_stop(sc);
1647 }
1648 error = 0;
1649 break;
1650 case SIOCADDMULTI:
1651 case SIOCDELMULTI:
1652 sis_setmulti(sc);
1653 error = 0;
1654 break;
1655 case SIOCGIFMEDIA:
1656 case SIOCSIFMEDIA:
1657 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
1658 break;
1659 default:
1660 error = EINVAL;
1661 break;
1662 }
1663
1664 (void)splx(s);
1665
1666 return(error);
1667 }
1668
1669 static void sis_watchdog(ifp)
1670 struct ifnet *ifp;
1671 {
1672 struct sis_softc *sc;
1673
1674 sc = ifp->if_softc;
1675
1676 if (sc->sis_autoneg) {
1677 sis_autoneg_mii(sc, SIS_FLAG_DELAYTIMEO, 1);
1678 return;
1679 }
1680
1681 ifp->if_oerrors++;
1682 printf("sis%d: watchdog timeout\n", sc->sis_unit);
1683
1684 sis_stop(sc);
1685 sis_reset(sc);
1686 sis_init(sc);
1687
1688 if (ifp->if_snd.ifq_head != NULL)
1689 sis_start(ifp);
1690
1691 return;
1692 }
1693
1694 /*
1695 * Stop the adapter and free any mbufs allocated to the
1696 * RX and TX lists.
1697 */
1698 static void sis_stop(sc)
1699 struct sis_softc *sc;
1700 {
1701 register int i;
1702 struct ifnet *ifp;
1703
1704 ifp = &sc->arpcom.ac_if;
1705 ifp->if_timer = 0;
1706
1707 CSR_WRITE_4(sc, SIS_IER, 0);
1708 CSR_WRITE_4(sc, SIS_IMR, 0);
1709 SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
1710 DELAY(1000);
1711 CSR_WRITE_4(sc, SIS_TX_LISTPTR, 0);
1712 CSR_WRITE_4(sc, SIS_RX_LISTPTR, 0);
1713
1714 /*
1715 * Free data in the RX lists.
1716 */
1717 for (i = 0; i < SIS_RX_LIST_CNT; i++) {
1718 if (sc->sis_ldata->sis_rx_list[i].sis_mbuf != NULL) {
1719 m_freem(sc->sis_ldata->sis_rx_list[i].sis_mbuf);
1720 sc->sis_ldata->sis_rx_list[i].sis_mbuf = NULL;
1721 }
1722 }
1723 bzero((char *)&sc->sis_ldata->sis_rx_list,
1724 sizeof(sc->sis_ldata->sis_rx_list));
1725
1726 /*
1727 * Free the TX list buffers.
1728 */
1729 for (i = 0; i < SIS_TX_LIST_CNT; i++) {
1730 if (sc->sis_ldata->sis_tx_list[i].sis_mbuf != NULL) {
1731 m_freem(sc->sis_ldata->sis_tx_list[i].sis_mbuf);
1732 sc->sis_ldata->sis_tx_list[i].sis_mbuf = NULL;
1733 }
1734 }
1735
1736 bzero((char *)&sc->sis_ldata->sis_tx_list,
1737 sizeof(sc->sis_ldata->sis_tx_list));
1738
1739 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1740
1741 return;
1742 }
1743
1744 /*
1745 * Stop all chip I/O so that the kernel's probe routines don't
1746 * get confused by errant DMAs when rebooting.
1747 */
1748 static void sis_shutdown(howto, arg)
1749 int howto;
1750 void *arg;
1751 {
1752 struct sis_softc *sc;
1753
1754 sc = arg;
1755
1756 sis_reset(sc);
1757 sis_stop(sc);
1758
1759 return;
1760 }
1761
1762 static struct pci_device sis_device = {
1763 "sis",
1764 sis_probe,
1765 sis_attach,
1766 &sis_count,
1767 NULL
1768 };
1769 #ifdef COMPAT_PCI_DRIVER
1770 COMPAT_PCI_DRIVER(sis, sis_device);
1771 #else
1772 DATA_SET(pcidevice_set, sis_device);
1773 #endif
Cache object: 76e58de784c8476c1775ba43a72511b6
|