Deleted Added
full compact
if_xl.c (93818) if_xl.c (102336)
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

--- 15 unchanged lines hidden (view full) ---

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 *
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

--- 15 unchanged lines hidden (view full) ---

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: head/sys/pci/if_xl.c 93818 2002-04-04 21:03:38Z jhb $
32 * $FreeBSD: head/sys/pci/if_xl.c 102336 2002-08-24 00:02:03Z alfred $
33 */
34
35/*
36 * 3Com 3c90x Etherlink XL PCI NIC driver
37 *
38 * Supports the 3Com "boomerang", "cyclone" and "hurricane" PCI
39 * bus-master chips (3c90x cards and embedded controllers) including
40 * the following:

--- 106 unchanged lines hidden (view full) ---

147 * might not work on some devices.
148 */
149#define XL_USEIOSPACE
150
151#include <pci/if_xlreg.h>
152
153#if !defined(lint)
154static const char rcsid[] =
33 */
34
35/*
36 * 3Com 3c90x Etherlink XL PCI NIC driver
37 *
38 * Supports the 3Com "boomerang", "cyclone" and "hurricane" PCI
39 * bus-master chips (3c90x cards and embedded controllers) including
40 * the following:

--- 106 unchanged lines hidden (view full) ---

147 * might not work on some devices.
148 */
149#define XL_USEIOSPACE
150
151#include <pci/if_xlreg.h>
152
153#if !defined(lint)
154static const char rcsid[] =
155 "$FreeBSD: head/sys/pci/if_xl.c 93818 2002-04-04 21:03:38Z jhb $";
155 "$FreeBSD: head/sys/pci/if_xl.c 102336 2002-08-24 00:02:03Z alfred $";
156#endif
157
158#define XL905B_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
159
160/*
161 * Various supported device vendors/types and their names.
162 */
163static struct xl_type xl_devs[] = {

--- 153 unchanged lines hidden (view full) ---

317/*
318 * Murphy's law says that it's possible the chip can wedge and
319 * the 'command in progress' bit may never clear. Hence, we wait
320 * only a finite amount of time to avoid getting caught in an
321 * infinite loop. Normally this delay routine would be a macro,
322 * but it isn't called during normal operation so we can afford
323 * to make it a function.
324 */
156#endif
157
158#define XL905B_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
159
160/*
161 * Various supported device vendors/types and their names.
162 */
163static struct xl_type xl_devs[] = {

--- 153 unchanged lines hidden (view full) ---

317/*
318 * Murphy's law says that it's possible the chip can wedge and
319 * the 'command in progress' bit may never clear. Hence, we wait
320 * only a finite amount of time to avoid getting caught in an
321 * infinite loop. Normally this delay routine would be a macro,
322 * but it isn't called during normal operation so we can afford
323 * to make it a function.
324 */
325static void xl_wait(sc)
325static void
326xl_wait(sc)
326 struct xl_softc *sc;
327{
328 register int i;
329
330 for (i = 0; i < XL_TIMEOUT; i++) {
331 if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
332 break;
333 }

--- 19 unchanged lines hidden (view full) ---

353
354#define MII_CLR(x) \
355 CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \
356 CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~x)
357
358/*
359 * Sync the PHYs by setting data bit and strobing the clock 32 times.
360 */
327 struct xl_softc *sc;
328{
329 register int i;
330
331 for (i = 0; i < XL_TIMEOUT; i++) {
332 if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
333 break;
334 }

--- 19 unchanged lines hidden (view full) ---

354
355#define MII_CLR(x) \
356 CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \
357 CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~x)
358
359/*
360 * Sync the PHYs by setting data bit and strobing the clock 32 times.
361 */
361static void xl_mii_sync(sc)
362static void
363xl_mii_sync(sc)
362 struct xl_softc *sc;
363{
364 register int i;
365
366 XL_SEL_WIN(4);
367 MII_SET(XL_MII_DIR|XL_MII_DATA);
368
369 for (i = 0; i < 32; i++) {

--- 4 unchanged lines hidden (view full) ---

374 }
375
376 return;
377}
378
379/*
380 * Clock a series of bits through the MII.
381 */
364 struct xl_softc *sc;
365{
366 register int i;
367
368 XL_SEL_WIN(4);
369 MII_SET(XL_MII_DIR|XL_MII_DATA);
370
371 for (i = 0; i < 32; i++) {

--- 4 unchanged lines hidden (view full) ---

376 }
377
378 return;
379}
380
381/*
382 * Clock a series of bits through the MII.
383 */
382static void xl_mii_send(sc, bits, cnt)
384static void
385xl_mii_send(sc, bits, cnt)
383 struct xl_softc *sc;
384 u_int32_t bits;
385 int cnt;
386{
387 int i;
388
389 XL_SEL_WIN(4);
390 MII_CLR(XL_MII_CLK);

--- 9 unchanged lines hidden (view full) ---

400 DELAY(1);
401 MII_SET(XL_MII_CLK);
402 }
403}
404
405/*
406 * Read an PHY register through the MII.
407 */
386 struct xl_softc *sc;
387 u_int32_t bits;
388 int cnt;
389{
390 int i;
391
392 XL_SEL_WIN(4);
393 MII_CLR(XL_MII_CLK);

--- 9 unchanged lines hidden (view full) ---

403 DELAY(1);
404 MII_SET(XL_MII_CLK);
405 }
406}
407
408/*
409 * Read an PHY register through the MII.
410 */
408static int xl_mii_readreg(sc, frame)
411static int
412xl_mii_readreg(sc, frame)
409 struct xl_softc *sc;
410 struct xl_mii_frame *frame;
411
412{
413 int i, ack;
414
415 XL_LOCK(sc);
416

--- 81 unchanged lines hidden (view full) ---

498 if (ack)
499 return(1);
500 return(0);
501}
502
503/*
504 * Write to a PHY register through the MII.
505 */
413 struct xl_softc *sc;
414 struct xl_mii_frame *frame;
415
416{
417 int i, ack;
418
419 XL_LOCK(sc);
420

--- 81 unchanged lines hidden (view full) ---

502 if (ack)
503 return(1);
504 return(0);
505}
506
507/*
508 * Write to a PHY register through the MII.
509 */
506static int xl_mii_writereg(sc, frame)
510static int
511xl_mii_writereg(sc, frame)
507 struct xl_softc *sc;
508 struct xl_mii_frame *frame;
509
510{
511 XL_LOCK(sc);
512
513 /*
514 * Set up frame for TX.

--- 33 unchanged lines hidden (view full) ---

548 */
549 MII_CLR(XL_MII_DIR);
550
551 XL_UNLOCK(sc);
552
553 return(0);
554}
555
512 struct xl_softc *sc;
513 struct xl_mii_frame *frame;
514
515{
516 XL_LOCK(sc);
517
518 /*
519 * Set up frame for TX.

--- 33 unchanged lines hidden (view full) ---

553 */
554 MII_CLR(XL_MII_DIR);
555
556 XL_UNLOCK(sc);
557
558 return(0);
559}
560
556static int xl_miibus_readreg(dev, phy, reg)
561static int
562xl_miibus_readreg(dev, phy, reg)
557 device_t dev;
558 int phy, reg;
559{
560 struct xl_softc *sc;
561 struct xl_mii_frame frame;
562
563 sc = device_get_softc(dev);
564

--- 11 unchanged lines hidden (view full) ---

576
577 frame.mii_phyaddr = phy;
578 frame.mii_regaddr = reg;
579 xl_mii_readreg(sc, &frame);
580
581 return(frame.mii_data);
582}
583
563 device_t dev;
564 int phy, reg;
565{
566 struct xl_softc *sc;
567 struct xl_mii_frame frame;
568
569 sc = device_get_softc(dev);
570

--- 11 unchanged lines hidden (view full) ---

582
583 frame.mii_phyaddr = phy;
584 frame.mii_regaddr = reg;
585 xl_mii_readreg(sc, &frame);
586
587 return(frame.mii_data);
588}
589
584static int xl_miibus_writereg(dev, phy, reg, data)
590static int
591xl_miibus_writereg(dev, phy, reg, data)
585 device_t dev;
586 int phy, reg, data;
587{
588 struct xl_softc *sc;
589 struct xl_mii_frame frame;
590
591 sc = device_get_softc(dev);
592

--- 6 unchanged lines hidden (view full) ---

599 frame.mii_regaddr = reg;
600 frame.mii_data = data;
601
602 xl_mii_writereg(sc, &frame);
603
604 return(0);
605}
606
592 device_t dev;
593 int phy, reg, data;
594{
595 struct xl_softc *sc;
596 struct xl_mii_frame frame;
597
598 sc = device_get_softc(dev);
599

--- 6 unchanged lines hidden (view full) ---

606 frame.mii_regaddr = reg;
607 frame.mii_data = data;
608
609 xl_mii_writereg(sc, &frame);
610
611 return(0);
612}
613
607static void xl_miibus_statchg(dev)
614static void
615xl_miibus_statchg(dev)
608 device_t dev;
609{
610 struct xl_softc *sc;
611 struct mii_data *mii;
612
613
614 sc = device_get_softc(dev);
615 mii = device_get_softc(sc->xl_miibus);

--- 20 unchanged lines hidden (view full) ---

636 * plus BNC and AUI ports. This means we will have both an miibus attached
637 * plus some non-MII media settings. In order to allow this, we have to
638 * add the extra media to the miibus's ifmedia struct, but we can't do
639 * that during xl_attach() because the miibus hasn't been attached yet.
640 * So instead, we wait until the miibus probe/attach is done, at which
641 * point we will get a callback telling is that it's safe to add our
642 * extra media.
643 */
616 device_t dev;
617{
618 struct xl_softc *sc;
619 struct mii_data *mii;
620
621
622 sc = device_get_softc(dev);
623 mii = device_get_softc(sc->xl_miibus);

--- 20 unchanged lines hidden (view full) ---

644 * plus BNC and AUI ports. This means we will have both an miibus attached
645 * plus some non-MII media settings. In order to allow this, we have to
646 * add the extra media to the miibus's ifmedia struct, but we can't do
647 * that during xl_attach() because the miibus hasn't been attached yet.
648 * So instead, we wait until the miibus probe/attach is done, at which
649 * point we will get a callback telling is that it's safe to add our
650 * extra media.
651 */
644static void xl_miibus_mediainit(dev)
652static void
653xl_miibus_mediainit(dev)
645 device_t dev;
646{
647 struct xl_softc *sc;
648 struct mii_data *mii;
649 struct ifmedia *ifm;
650
651 sc = device_get_softc(dev);
652 mii = device_get_softc(sc->xl_miibus);

--- 31 unchanged lines hidden (view full) ---

684
685 return;
686}
687
688/*
689 * The EEPROM is slow: give it time to come ready after issuing
690 * it a command.
691 */
654 device_t dev;
655{
656 struct xl_softc *sc;
657 struct mii_data *mii;
658 struct ifmedia *ifm;
659
660 sc = device_get_softc(dev);
661 mii = device_get_softc(sc->xl_miibus);

--- 31 unchanged lines hidden (view full) ---

693
694 return;
695}
696
697/*
698 * The EEPROM is slow: give it time to come ready after issuing
699 * it a command.
700 */
692static int xl_eeprom_wait(sc)
701static int
702xl_eeprom_wait(sc)
693 struct xl_softc *sc;
694{
695 int i;
696
697 for (i = 0; i < 100; i++) {
698 if (CSR_READ_2(sc, XL_W0_EE_CMD) & XL_EE_BUSY)
699 DELAY(162);
700 else

--- 7 unchanged lines hidden (view full) ---

708
709 return(0);
710}
711
712/*
713 * Read a sequence of words from the EEPROM. Note that ethernet address
714 * data is stored in the EEPROM in network byte order.
715 */
703 struct xl_softc *sc;
704{
705 int i;
706
707 for (i = 0; i < 100; i++) {
708 if (CSR_READ_2(sc, XL_W0_EE_CMD) & XL_EE_BUSY)
709 DELAY(162);
710 else

--- 7 unchanged lines hidden (view full) ---

718
719 return(0);
720}
721
722/*
723 * Read a sequence of words from the EEPROM. Note that ethernet address
724 * data is stored in the EEPROM in network byte order.
725 */
716static int xl_read_eeprom(sc, dest, off, cnt, swap)
726static int
727xl_read_eeprom(sc, dest, off, cnt, swap)
717 struct xl_softc *sc;
718 caddr_t dest;
719 int off;
720 int cnt;
721 int swap;
722{
723 int err = 0, i;
724 u_int16_t word = 0, *ptr;

--- 70 unchanged lines hidden (view full) ---

795 /* return the filter bit position */
796 return(crc & 0x000000FF);
797}
798
799/*
800 * NICs older than the 3c905B have only one multicast option, which
801 * is to enable reception of all multicast frames.
802 */
728 struct xl_softc *sc;
729 caddr_t dest;
730 int off;
731 int cnt;
732 int swap;
733{
734 int err = 0, i;
735 u_int16_t word = 0, *ptr;

--- 70 unchanged lines hidden (view full) ---

806 /* return the filter bit position */
807 return(crc & 0x000000FF);
808}
809
810/*
811 * NICs older than the 3c905B have only one multicast option, which
812 * is to enable reception of all multicast frames.
813 */
803static void xl_setmulti(sc)
814static void
815xl_setmulti(sc)
804 struct xl_softc *sc;
805{
806 struct ifnet *ifp;
807 struct ifmultiaddr *ifma;
808 u_int8_t rxfilt;
809 int mcnt = 0;
810
811 ifp = &sc->arpcom.ac_if;

--- 18 unchanged lines hidden (view full) ---

830 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
831
832 return;
833}
834
835/*
836 * 3c905B adapters have a hash filter that we can program.
837 */
816 struct xl_softc *sc;
817{
818 struct ifnet *ifp;
819 struct ifmultiaddr *ifma;
820 u_int8_t rxfilt;
821 int mcnt = 0;
822
823 ifp = &sc->arpcom.ac_if;

--- 18 unchanged lines hidden (view full) ---

842 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
843
844 return;
845}
846
847/*
848 * 3c905B adapters have a hash filter that we can program.
849 */
838static void xl_setmulti_hash(sc)
850static void
851xl_setmulti_hash(sc)
839 struct xl_softc *sc;
840{
841 struct ifnet *ifp;
842 int h = 0, i;
843 struct ifmultiaddr *ifma;
844 u_int8_t rxfilt;
845 int mcnt = 0;
846

--- 29 unchanged lines hidden (view full) ---

876 rxfilt &= ~XL_RXFILTER_MULTIHASH;
877
878 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
879
880 return;
881}
882
883#ifdef notdef
852 struct xl_softc *sc;
853{
854 struct ifnet *ifp;
855 int h = 0, i;
856 struct ifmultiaddr *ifma;
857 u_int8_t rxfilt;
858 int mcnt = 0;
859

--- 29 unchanged lines hidden (view full) ---

889 rxfilt &= ~XL_RXFILTER_MULTIHASH;
890
891 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
892
893 return;
894}
895
896#ifdef notdef
884static void xl_testpacket(sc)
897static void
898xl_testpacket(sc)
885 struct xl_softc *sc;
886{
887 struct mbuf *m;
888 struct ifnet *ifp;
889
890 ifp = &sc->arpcom.ac_if;
891
892 MGETHDR(m, M_DONTWAIT, MT_DATA);

--- 12 unchanged lines hidden (view full) ---

905 m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
906 IF_ENQUEUE(&ifp->if_snd, m);
907 xl_start(ifp);
908
909 return;
910}
911#endif
912
899 struct xl_softc *sc;
900{
901 struct mbuf *m;
902 struct ifnet *ifp;
903
904 ifp = &sc->arpcom.ac_if;
905
906 MGETHDR(m, M_DONTWAIT, MT_DATA);

--- 12 unchanged lines hidden (view full) ---

919 m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
920 IF_ENQUEUE(&ifp->if_snd, m);
921 xl_start(ifp);
922
923 return;
924}
925#endif
926
913static void xl_setcfg(sc)
927static void
928xl_setcfg(sc)
914 struct xl_softc *sc;
915{
916 u_int32_t icfg;
917
918 XL_SEL_WIN(3);
919 icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
920 icfg &= ~XL_ICFG_CONNECTOR_MASK;
921 if (sc->xl_media & XL_MEDIAOPT_MII ||
922 sc->xl_media & XL_MEDIAOPT_BT4)
923 icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);
924 if (sc->xl_media & XL_MEDIAOPT_BTX)
925 icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);
926
927 CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
928 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
929
930 return;
931}
932
929 struct xl_softc *sc;
930{
931 u_int32_t icfg;
932
933 XL_SEL_WIN(3);
934 icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
935 icfg &= ~XL_ICFG_CONNECTOR_MASK;
936 if (sc->xl_media & XL_MEDIAOPT_MII ||
937 sc->xl_media & XL_MEDIAOPT_BT4)
938 icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);
939 if (sc->xl_media & XL_MEDIAOPT_BTX)
940 icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);
941
942 CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
943 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
944
945 return;
946}
947
933static void xl_setmode(sc, media)
948static void
949xl_setmode(sc, media)
934 struct xl_softc *sc;
935 int media;
936{
937 u_int32_t icfg;
938 u_int16_t mediastat;
939
940 printf("xl%d: selecting ", sc->xl_unit);
941

--- 78 unchanged lines hidden (view full) ---

1020 XL_SEL_WIN(4);
1021 CSR_WRITE_2(sc, XL_W4_MEDIA_STATUS, mediastat);
1022 DELAY(800);
1023 XL_SEL_WIN(7);
1024
1025 return;
1026}
1027
950 struct xl_softc *sc;
951 int media;
952{
953 u_int32_t icfg;
954 u_int16_t mediastat;
955
956 printf("xl%d: selecting ", sc->xl_unit);
957

--- 78 unchanged lines hidden (view full) ---

1036 XL_SEL_WIN(4);
1037 CSR_WRITE_2(sc, XL_W4_MEDIA_STATUS, mediastat);
1038 DELAY(800);
1039 XL_SEL_WIN(7);
1040
1041 return;
1042}
1043
1028static void xl_reset(sc)
1044static void
1045xl_reset(sc)
1029 struct xl_softc *sc;
1030{
1031 register int i;
1032
1033 XL_SEL_WIN(0);
1034 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |
1035 ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?
1036 XL_RESETOPT_DISADVFD:0));

--- 34 unchanged lines hidden (view full) ---

1071 DELAY(100000);
1072 return;
1073}
1074
1075/*
1076 * Probe for a 3Com Etherlink XL chip. Check the PCI vendor and device
1077 * IDs against our list and return a device name if we find a match.
1078 */
1046 struct xl_softc *sc;
1047{
1048 register int i;
1049
1050 XL_SEL_WIN(0);
1051 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |
1052 ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?
1053 XL_RESETOPT_DISADVFD:0));

--- 34 unchanged lines hidden (view full) ---

1088 DELAY(100000);
1089 return;
1090}
1091
1092/*
1093 * Probe for a 3Com Etherlink XL chip. Check the PCI vendor and device
1094 * IDs against our list and return a device name if we find a match.
1095 */
1079static int xl_probe(dev)
1096static int
1097xl_probe(dev)
1080 device_t dev;
1081{
1082 struct xl_type *t;
1083
1084 t = xl_devs;
1085
1086 while(t->xl_name != NULL) {
1087 if ((pci_get_vendor(dev) == t->xl_vid) &&

--- 14 unchanged lines hidden (view full) ---

1102 * 3c90x adapters) to return an incorrect result. I have encountered
1103 * one Dell Latitude laptop docking station with an integrated 3c905-TX
1104 * which doesn't have any of the 'mediaopt' bits set. This screws up
1105 * the attach routine pretty badly because it doesn't know what media
1106 * to look for. If we find ourselves in this predicament, this routine
1107 * will try to guess the media options values and warn the user of a
1108 * possible manufacturing defect with his adapter/system/whatever.
1109 */
1098 device_t dev;
1099{
1100 struct xl_type *t;
1101
1102 t = xl_devs;
1103
1104 while(t->xl_name != NULL) {
1105 if ((pci_get_vendor(dev) == t->xl_vid) &&

--- 14 unchanged lines hidden (view full) ---

1120 * 3c90x adapters) to return an incorrect result. I have encountered
1121 * one Dell Latitude laptop docking station with an integrated 3c905-TX
1122 * which doesn't have any of the 'mediaopt' bits set. This screws up
1123 * the attach routine pretty badly because it doesn't know what media
1124 * to look for. If we find ourselves in this predicament, this routine
1125 * will try to guess the media options values and warn the user of a
1126 * possible manufacturing defect with his adapter/system/whatever.
1127 */
1110static void xl_mediacheck(sc)
1128static void
1129xl_mediacheck(sc)
1111 struct xl_softc *sc;
1112{
1113
1114 /*
1115 * If some of the media options bits are set, assume they are
1116 * correct. If not, try to figure it out down below.
1117 * XXX I should check for 10baseFL, but I don't have an adapter
1118 * to test with.

--- 23 unchanged lines hidden (view full) ---

1142 "should probably consult your vendor\n", sc->xl_unit);
1143 }
1144
1145 xl_choose_xcvr(sc, 1);
1146
1147 return;
1148}
1149
1130 struct xl_softc *sc;
1131{
1132
1133 /*
1134 * If some of the media options bits are set, assume they are
1135 * correct. If not, try to figure it out down below.
1136 * XXX I should check for 10baseFL, but I don't have an adapter
1137 * to test with.

--- 23 unchanged lines hidden (view full) ---

1161 "should probably consult your vendor\n", sc->xl_unit);
1162 }
1163
1164 xl_choose_xcvr(sc, 1);
1165
1166 return;
1167}
1168
1150static void xl_choose_xcvr(sc, verbose)
1169static void
1170xl_choose_xcvr(sc, verbose)
1151 struct xl_softc *sc;
1152 int verbose;
1153{
1154 u_int16_t devid;
1155
1156 /*
1157 * Read the device ID from the EEPROM.
1158 * This is what's loaded into the PCI device ID register, so it has

--- 78 unchanged lines hidden (view full) ---

1237
1238 return;
1239}
1240
1241/*
1242 * Attach the interface. Allocate softc structures, do ifmedia
1243 * setup and ethernet/BPF attach.
1244 */
1171 struct xl_softc *sc;
1172 int verbose;
1173{
1174 u_int16_t devid;
1175
1176 /*
1177 * Read the device ID from the EEPROM.
1178 * This is what's loaded into the PCI device ID register, so it has

--- 78 unchanged lines hidden (view full) ---

1257
1258 return;
1259}
1260
1261/*
1262 * Attach the interface. Allocate softc structures, do ifmedia
1263 * setup and ethernet/BPF attach.
1264 */
1245static int xl_attach(dev)
1265static int
1266xl_attach(dev)
1246 device_t dev;
1247{
1248 u_char eaddr[ETHER_ADDR_LEN];
1249 u_int32_t command;
1250 struct xl_softc *sc;
1251 struct ifnet *ifp;
1252 int media = IFM_ETHER|IFM_100_TX|IFM_FDX;
1253 int unit, error = 0, rid;

--- 374 unchanged lines hidden (view full) ---

1628
1629fail:
1630 XL_UNLOCK(sc);
1631 mtx_destroy(&sc->xl_mtx);
1632
1633 return(error);
1634}
1635
1267 device_t dev;
1268{
1269 u_char eaddr[ETHER_ADDR_LEN];
1270 u_int32_t command;
1271 struct xl_softc *sc;
1272 struct ifnet *ifp;
1273 int media = IFM_ETHER|IFM_100_TX|IFM_FDX;
1274 int unit, error = 0, rid;

--- 374 unchanged lines hidden (view full) ---

1649
1650fail:
1651 XL_UNLOCK(sc);
1652 mtx_destroy(&sc->xl_mtx);
1653
1654 return(error);
1655}
1656
1636static int xl_detach(dev)
1657static int
1658xl_detach(dev)
1637 device_t dev;
1638{
1639 struct xl_softc *sc;
1640 struct ifnet *ifp;
1641
1642 sc = device_get_softc(dev);
1643 XL_LOCK(sc);
1644 ifp = &sc->arpcom.ac_if;

--- 22 unchanged lines hidden (view full) ---

1667 mtx_destroy(&sc->xl_mtx);
1668
1669 return(0);
1670}
1671
1672/*
1673 * Initialize the transmit descriptors.
1674 */
1659 device_t dev;
1660{
1661 struct xl_softc *sc;
1662 struct ifnet *ifp;
1663
1664 sc = device_get_softc(dev);
1665 XL_LOCK(sc);
1666 ifp = &sc->arpcom.ac_if;

--- 22 unchanged lines hidden (view full) ---

1689 mtx_destroy(&sc->xl_mtx);
1690
1691 return(0);
1692}
1693
1694/*
1695 * Initialize the transmit descriptors.
1696 */
1675static int xl_list_tx_init(sc)
1697static int
1698xl_list_tx_init(sc)
1676 struct xl_softc *sc;
1677{
1678 struct xl_chain_data *cd;
1679 struct xl_list_data *ld;
1680 int i;
1681
1682 cd = &sc->xl_cdata;
1683 ld = sc->xl_ldata;

--- 49 unchanged lines hidden (view full) ---

1733 return(0);
1734}
1735
1736/*
1737 * Initialize the RX descriptors and allocate mbufs for them. Note that
1738 * we arrange the descriptors in a closed ring, so that the last descriptor
1739 * points back to the first.
1740 */
1699 struct xl_softc *sc;
1700{
1701 struct xl_chain_data *cd;
1702 struct xl_list_data *ld;
1703 int i;
1704
1705 cd = &sc->xl_cdata;
1706 ld = sc->xl_ldata;

--- 49 unchanged lines hidden (view full) ---

1756 return(0);
1757}
1758
1759/*
1760 * Initialize the RX descriptors and allocate mbufs for them. Note that
1761 * we arrange the descriptors in a closed ring, so that the last descriptor
1762 * points back to the first.
1763 */
1741static int xl_list_rx_init(sc)
1764static int
1765xl_list_rx_init(sc)
1742 struct xl_softc *sc;
1743{
1744 struct xl_chain_data *cd;
1745 struct xl_list_data *ld;
1746 int i;
1747
1748 cd = &sc->xl_cdata;
1749 ld = sc->xl_ldata;

--- 17 unchanged lines hidden (view full) ---

1767 cd->xl_rx_head = &cd->xl_rx_chain[0];
1768
1769 return(0);
1770}
1771
1772/*
1773 * Initialize an RX descriptor and attach an MBUF cluster.
1774 */
1766 struct xl_softc *sc;
1767{
1768 struct xl_chain_data *cd;
1769 struct xl_list_data *ld;
1770 int i;
1771
1772 cd = &sc->xl_cdata;
1773 ld = sc->xl_ldata;

--- 17 unchanged lines hidden (view full) ---

1791 cd->xl_rx_head = &cd->xl_rx_chain[0];
1792
1793 return(0);
1794}
1795
1796/*
1797 * Initialize an RX descriptor and attach an MBUF cluster.
1798 */
1775static int xl_newbuf(sc, c)
1799static int
1800xl_newbuf(sc, c)
1776 struct xl_softc *sc;
1777 struct xl_chain_onefrag *c;
1778{
1779 struct mbuf *m_new = NULL;
1780
1781 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1782 if (m_new == NULL)
1783 return(ENOBUFS);

--- 12 unchanged lines hidden (view full) ---

1796 c->xl_mbuf = m_new;
1797 c->xl_ptr->xl_frag.xl_addr = vtophys(mtod(m_new, caddr_t));
1798 c->xl_ptr->xl_frag.xl_len = MCLBYTES | XL_LAST_FRAG;
1799 c->xl_ptr->xl_status = 0;
1800
1801 return(0);
1802}
1803
1801 struct xl_softc *sc;
1802 struct xl_chain_onefrag *c;
1803{
1804 struct mbuf *m_new = NULL;
1805
1806 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1807 if (m_new == NULL)
1808 return(ENOBUFS);

--- 12 unchanged lines hidden (view full) ---

1821 c->xl_mbuf = m_new;
1822 c->xl_ptr->xl_frag.xl_addr = vtophys(mtod(m_new, caddr_t));
1823 c->xl_ptr->xl_frag.xl_len = MCLBYTES | XL_LAST_FRAG;
1824 c->xl_ptr->xl_status = 0;
1825
1826 return(0);
1827}
1828
1804static int xl_rx_resync(sc)
1829static int
1830xl_rx_resync(sc)
1805 struct xl_softc *sc;
1806{
1807 struct xl_chain_onefrag *pos;
1808 int i;
1809
1810 pos = sc->xl_cdata.xl_rx_head;
1811
1812 for (i = 0; i < XL_RX_LIST_CNT; i++) {

--- 9 unchanged lines hidden (view full) ---

1822
1823 return(EAGAIN);
1824}
1825
1826/*
1827 * A frame has been uploaded: pass the resulting mbuf chain up to
1828 * the higher level protocols.
1829 */
1831 struct xl_softc *sc;
1832{
1833 struct xl_chain_onefrag *pos;
1834 int i;
1835
1836 pos = sc->xl_cdata.xl_rx_head;
1837
1838 for (i = 0; i < XL_RX_LIST_CNT; i++) {

--- 9 unchanged lines hidden (view full) ---

1848
1849 return(EAGAIN);
1850}
1851
1852/*
1853 * A frame has been uploaded: pass the resulting mbuf chain up to
1854 * the higher level protocols.
1855 */
1830static void xl_rxeof(sc)
1856static void
1857xl_rxeof(sc)
1831 struct xl_softc *sc;
1832{
1833 struct ether_header *eh;
1834 struct mbuf *m;
1835 struct ifnet *ifp;
1836 struct xl_chain_onefrag *cur_rx;
1837 int total_len = 0;
1838 u_int32_t rxstat;

--- 99 unchanged lines hidden (view full) ---

1938
1939 return;
1940}
1941
1942/*
1943 * A frame was downloaded to the chip. It's safe for us to clean up
1944 * the list buffers.
1945 */
1858 struct xl_softc *sc;
1859{
1860 struct ether_header *eh;
1861 struct mbuf *m;
1862 struct ifnet *ifp;
1863 struct xl_chain_onefrag *cur_rx;
1864 int total_len = 0;
1865 u_int32_t rxstat;

--- 99 unchanged lines hidden (view full) ---

1965
1966 return;
1967}
1968
1969/*
1970 * A frame was downloaded to the chip. It's safe for us to clean up
1971 * the list buffers.
1972 */
1946static void xl_txeof(sc)
1973static void
1974xl_txeof(sc)
1947 struct xl_softc *sc;
1948{
1949 struct xl_chain *cur_tx;
1950 struct ifnet *ifp;
1951
1952 ifp = &sc->arpcom.ac_if;
1953
1954 /* Clear the timeout timer. */

--- 75 unchanged lines hidden (view full) ---

2030 return;
2031}
2032
2033/*
2034 * TX 'end of channel' interrupt handler. Actually, we should
2035 * only get a 'TX complete' interrupt if there's a transmit error,
2036 * so this is really TX error handler.
2037 */
1975 struct xl_softc *sc;
1976{
1977 struct xl_chain *cur_tx;
1978 struct ifnet *ifp;
1979
1980 ifp = &sc->arpcom.ac_if;
1981
1982 /* Clear the timeout timer. */

--- 75 unchanged lines hidden (view full) ---

2058 return;
2059}
2060
2061/*
2062 * TX 'end of channel' interrupt handler. Actually, we should
2063 * only get a 'TX complete' interrupt if there's a transmit error,
2064 * so this is really TX error handler.
2065 */
2038static void xl_txeoc(sc)
2066static void
2067xl_txeoc(sc)
2039 struct xl_softc *sc;
2040{
2041 u_int8_t txstat;
2042
2043 while((txstat = CSR_READ_1(sc, XL_TX_STATUS))) {
2044 if (txstat & XL_TXSTATUS_UNDERRUN ||
2045 txstat & XL_TXSTATUS_JABBER ||
2046 txstat & XL_TXSTATUS_RECLAIM) {

--- 45 unchanged lines hidden (view full) ---

2092 * to clear this interrupt/error and advance to the next.
2093 */
2094 CSR_WRITE_1(sc, XL_TX_STATUS, 0x01);
2095 }
2096
2097 return;
2098}
2099
2068 struct xl_softc *sc;
2069{
2070 u_int8_t txstat;
2071
2072 while((txstat = CSR_READ_1(sc, XL_TX_STATUS))) {
2073 if (txstat & XL_TXSTATUS_UNDERRUN ||
2074 txstat & XL_TXSTATUS_JABBER ||
2075 txstat & XL_TXSTATUS_RECLAIM) {

--- 45 unchanged lines hidden (view full) ---

2121 * to clear this interrupt/error and advance to the next.
2122 */
2123 CSR_WRITE_1(sc, XL_TX_STATUS, 0x01);
2124 }
2125
2126 return;
2127}
2128
2100static void xl_intr(arg)
2129static void
2130xl_intr(arg)
2101 void *arg;
2102{
2103 struct xl_softc *sc;
2104 struct ifnet *ifp;
2105 u_int16_t status;
2106
2107 sc = arg;
2108 XL_LOCK(sc);

--- 42 unchanged lines hidden (view full) ---

2151 if (ifp->if_snd.ifq_head != NULL)
2152 (*ifp->if_start)(ifp);
2153
2154 XL_UNLOCK(sc);
2155
2156 return;
2157}
2158
2131 void *arg;
2132{
2133 struct xl_softc *sc;
2134 struct ifnet *ifp;
2135 u_int16_t status;
2136
2137 sc = arg;
2138 XL_LOCK(sc);

--- 42 unchanged lines hidden (view full) ---

2181 if (ifp->if_snd.ifq_head != NULL)
2182 (*ifp->if_start)(ifp);
2183
2184 XL_UNLOCK(sc);
2185
2186 return;
2187}
2188
2159static void xl_stats_update(xsc)
2189static void
2190xl_stats_update(xsc)
2160 void *xsc;
2161{
2162 struct xl_softc *sc;
2163 struct ifnet *ifp;
2164 struct xl_stats xl_stats;
2165 u_int8_t *p;
2166 int i;
2167 struct mii_data *mii = NULL;

--- 38 unchanged lines hidden (view full) ---

2206
2207 return;
2208}
2209
2210/*
2211 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
2212 * pointers to the fragment pointers.
2213 */
2191 void *xsc;
2192{
2193 struct xl_softc *sc;
2194 struct ifnet *ifp;
2195 struct xl_stats xl_stats;
2196 u_int8_t *p;
2197 int i;
2198 struct mii_data *mii = NULL;

--- 38 unchanged lines hidden (view full) ---

2237
2238 return;
2239}
2240
2241/*
2242 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
2243 * pointers to the fragment pointers.
2244 */
2214static int xl_encap(sc, c, m_head)
2245static int
2246xl_encap(sc, c, m_head)
2215 struct xl_softc *sc;
2216 struct xl_chain *c;
2217 struct mbuf *m_head;
2218{
2219 int frag = 0;
2220 struct xl_frag *f = NULL;
2221 int total_len;
2222 struct mbuf *m;

--- 63 unchanged lines hidden (view full) ---

2286}
2287
2288/*
2289 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
2290 * to the mbuf data regions directly in the transmit lists. We also save a
2291 * copy of the pointers since the transmit list fragment pointers are
2292 * physical addresses.
2293 */
2247 struct xl_softc *sc;
2248 struct xl_chain *c;
2249 struct mbuf *m_head;
2250{
2251 int frag = 0;
2252 struct xl_frag *f = NULL;
2253 int total_len;
2254 struct mbuf *m;

--- 63 unchanged lines hidden (view full) ---

2318}
2319
2320/*
2321 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
2322 * to the mbuf data regions directly in the transmit lists. We also save a
2323 * copy of the pointers since the transmit list fragment pointers are
2324 * physical addresses.
2325 */
2294static void xl_start(ifp)
2326static void
2327xl_start(ifp)
2295 struct ifnet *ifp;
2296{
2297 struct xl_softc *sc;
2298 struct mbuf *m_head = NULL;
2299 struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
2300
2301 sc = ifp->if_softc;
2302 XL_LOCK(sc);

--- 233 unchanged lines hidden (view full) ---

2536 */
2537 ifp->if_timer = 5;
2538
2539 XL_UNLOCK(sc);
2540
2541 return;
2542}
2543
2328 struct ifnet *ifp;
2329{
2330 struct xl_softc *sc;
2331 struct mbuf *m_head = NULL;
2332 struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
2333
2334 sc = ifp->if_softc;
2335 XL_LOCK(sc);

--- 233 unchanged lines hidden (view full) ---

2569 */
2570 ifp->if_timer = 5;
2571
2572 XL_UNLOCK(sc);
2573
2574 return;
2575}
2576
2544static void xl_init(xsc)
2577static void
2578xl_init(xsc)
2545 void *xsc;
2546{
2547 struct xl_softc *sc = xsc;
2548 struct ifnet *ifp = &sc->arpcom.ac_if;
2549 int i;
2550 u_int16_t rxfilt = 0;
2551 struct mii_data *mii = NULL;
2552

--- 192 unchanged lines hidden (view full) ---

2745 XL_UNLOCK(sc);
2746
2747 return;
2748}
2749
2750/*
2751 * Set media options.
2752 */
2579 void *xsc;
2580{
2581 struct xl_softc *sc = xsc;
2582 struct ifnet *ifp = &sc->arpcom.ac_if;
2583 int i;
2584 u_int16_t rxfilt = 0;
2585 struct mii_data *mii = NULL;
2586

--- 192 unchanged lines hidden (view full) ---

2779 XL_UNLOCK(sc);
2780
2781 return;
2782}
2783
2784/*
2785 * Set media options.
2786 */
2753static int xl_ifmedia_upd(ifp)
2787static int
2788xl_ifmedia_upd(ifp)
2754 struct ifnet *ifp;
2755{
2756 struct xl_softc *sc;
2757 struct ifmedia *ifm = NULL;
2758 struct mii_data *mii = NULL;
2759
2760 sc = ifp->if_softc;
2761 if (sc->xl_miibus != NULL)

--- 23 unchanged lines hidden (view full) ---

2785 }
2786
2787 return(0);
2788}
2789
2790/*
2791 * Report current media status.
2792 */
2789 struct ifnet *ifp;
2790{
2791 struct xl_softc *sc;
2792 struct ifmedia *ifm = NULL;
2793 struct mii_data *mii = NULL;
2794
2795 sc = ifp->if_softc;
2796 if (sc->xl_miibus != NULL)

--- 23 unchanged lines hidden (view full) ---

2820 }
2821
2822 return(0);
2823}
2824
2825/*
2826 * Report current media status.
2827 */
2793static void xl_ifmedia_sts(ifp, ifmr)
2828static void
2829xl_ifmedia_sts(ifp, ifmr)
2794 struct ifnet *ifp;
2795 struct ifmediareq *ifmr;
2796{
2797 struct xl_softc *sc;
2798 u_int32_t icfg;
2799 struct mii_data *mii = NULL;
2800
2801 sc = ifp->if_softc;

--- 47 unchanged lines hidden (view full) ---

2849 default:
2850 printf("xl%d: unknown XCVR type: %d\n", sc->xl_unit, icfg);
2851 break;
2852 }
2853
2854 return;
2855}
2856
2830 struct ifnet *ifp;
2831 struct ifmediareq *ifmr;
2832{
2833 struct xl_softc *sc;
2834 u_int32_t icfg;
2835 struct mii_data *mii = NULL;
2836
2837 sc = ifp->if_softc;

--- 47 unchanged lines hidden (view full) ---

2885 default:
2886 printf("xl%d: unknown XCVR type: %d\n", sc->xl_unit, icfg);
2887 break;
2888 }
2889
2890 return;
2891}
2892
2857static int xl_ioctl(ifp, command, data)
2893static int
2894xl_ioctl(ifp, command, data)
2858 struct ifnet *ifp;
2859 u_long command;
2860 caddr_t data;
2861{
2862 struct xl_softc *sc = ifp->if_softc;
2863 struct ifreq *ifr = (struct ifreq *) data;
2864 int error = 0;
2865 struct mii_data *mii = NULL;

--- 58 unchanged lines hidden (view full) ---

2924 break;
2925 }
2926
2927 XL_UNLOCK(sc);
2928
2929 return(error);
2930}
2931
2895 struct ifnet *ifp;
2896 u_long command;
2897 caddr_t data;
2898{
2899 struct xl_softc *sc = ifp->if_softc;
2900 struct ifreq *ifr = (struct ifreq *) data;
2901 int error = 0;
2902 struct mii_data *mii = NULL;

--- 58 unchanged lines hidden (view full) ---

2961 break;
2962 }
2963
2964 XL_UNLOCK(sc);
2965
2966 return(error);
2967}
2968
2932static void xl_watchdog(ifp)
2969static void
2970xl_watchdog(ifp)
2933 struct ifnet *ifp;
2934{
2935 struct xl_softc *sc;
2936 u_int16_t status = 0;
2937
2938 sc = ifp->if_softc;
2939
2940 XL_LOCK(sc);

--- 19 unchanged lines hidden (view full) ---

2960
2961 return;
2962}
2963
2964/*
2965 * Stop the adapter and free any mbufs allocated to the
2966 * RX and TX lists.
2967 */
2971 struct ifnet *ifp;
2972{
2973 struct xl_softc *sc;
2974 u_int16_t status = 0;
2975
2976 sc = ifp->if_softc;
2977
2978 XL_LOCK(sc);

--- 19 unchanged lines hidden (view full) ---

2998
2999 return;
3000}
3001
3002/*
3003 * Stop the adapter and free any mbufs allocated to the
3004 * RX and TX lists.
3005 */
2968static void xl_stop(sc)
3006static void
3007xl_stop(sc)
2969 struct xl_softc *sc;
2970{
2971 register int i;
2972 struct ifnet *ifp;
2973
2974 XL_LOCK(sc);
2975
2976 ifp = &sc->arpcom.ac_if;

--- 52 unchanged lines hidden (view full) ---

3029
3030 return;
3031}
3032
3033/*
3034 * Stop all chip I/O so that the kernel's probe routines don't
3035 * get confused by errant DMAs when rebooting.
3036 */
3008 struct xl_softc *sc;
3009{
3010 register int i;
3011 struct ifnet *ifp;
3012
3013 XL_LOCK(sc);
3014
3015 ifp = &sc->arpcom.ac_if;

--- 52 unchanged lines hidden (view full) ---

3068
3069 return;
3070}
3071
3072/*
3073 * Stop all chip I/O so that the kernel's probe routines don't
3074 * get confused by errant DMAs when rebooting.
3075 */
3037static void xl_shutdown(dev)
3076static void
3077xl_shutdown(dev)
3038 device_t dev;
3039{
3040 struct xl_softc *sc;
3041
3042 sc = device_get_softc(dev);
3043
3044 XL_LOCK(sc);
3045 xl_reset(sc);
3046 xl_stop(sc);
3047 XL_UNLOCK(sc);
3048
3049 return;
3050}
3051
3078 device_t dev;
3079{
3080 struct xl_softc *sc;
3081
3082 sc = device_get_softc(dev);
3083
3084 XL_LOCK(sc);
3085 xl_reset(sc);
3086 xl_stop(sc);
3087 XL_UNLOCK(sc);
3088
3089 return;
3090}
3091
3052static int xl_suspend(dev)
3092static int
3093xl_suspend(dev)
3053 device_t dev;
3054{
3055 struct xl_softc *sc;
3056
3057 sc = device_get_softc(dev);
3058
3059 XL_LOCK(sc);
3060 xl_stop(sc);
3061 XL_UNLOCK(sc);
3062
3063 return(0);
3064}
3065
3094 device_t dev;
3095{
3096 struct xl_softc *sc;
3097
3098 sc = device_get_softc(dev);
3099
3100 XL_LOCK(sc);
3101 xl_stop(sc);
3102 XL_UNLOCK(sc);
3103
3104 return(0);
3105}
3106
3066static int xl_resume(dev)
3107static int
3108xl_resume(dev)
3067 device_t dev;
3068{
3069 struct xl_softc *sc;
3070 struct ifnet *ifp;
3071
3072 sc = device_get_softc(dev);
3073 XL_LOCK(sc);
3074 ifp = &sc->arpcom.ac_if;
3075
3076 xl_reset(sc);
3077 if (ifp->if_flags & IFF_UP)
3078 xl_init(sc);
3079
3080 XL_UNLOCK(sc);
3081 return(0);
3082}
3109 device_t dev;
3110{
3111 struct xl_softc *sc;
3112 struct ifnet *ifp;
3113
3114 sc = device_get_softc(dev);
3115 XL_LOCK(sc);
3116 ifp = &sc->arpcom.ac_if;
3117
3118 xl_reset(sc);
3119 if (ifp->if_flags & IFF_UP)
3120 xl_init(sc);
3121
3122 XL_UNLOCK(sc);
3123 return(0);
3124}