Lines Matching +full:xcvr +full:- +full:setup

1 /*-
2 * SPDX-License-Identifier: BSD-4-Clause
18 * 4. Neither the name of the author nor the names of any co-contributors
40 * bus-master chips (3c90x cards and embedded controllers) including
43 * 3Com 3c900-TPO 10Mbps/RJ-45
44 * 3Com 3c900-COMBO 10Mbps/RJ-45,AUI,BNC
45 * 3Com 3c905-TX 10/100Mbps/RJ-45
46 * 3Com 3c905-T4 10/100Mbps/RJ-45
47 * 3Com 3c900B-TPO 10Mbps/RJ-45
48 * 3Com 3c900B-COMBO 10Mbps/RJ-45,AUI,BNC
49 * 3Com 3c900B-TPC 10Mbps/RJ-45,BNC
50 * 3Com 3c900B-FL 10Mbps/Fiber-optic
51 * 3Com 3c905B-COMBO 10/100Mbps/RJ-45,AUI,BNC
52 * 3Com 3c905B-TX 10/100Mbps/RJ-45
53 * 3Com 3c905B-FL/FX 10/100Mbps/Fiber-optic
54 * 3Com 3c905C-TX 10/100Mbps/RJ-45 (Tornado ASIC)
55 * 3Com 3c980-TX 10/100Mbps server adapter (Hurricane ASIC)
56 * 3Com 3c980C-TX 10/100Mbps server adapter (Tornado ASIC)
57 * 3Com 3cSOHO100-TX 10/100Mbps/RJ-45 (Hurricane ASIC)
58 * 3Com 3c450-TX 10/100Mbps/RJ-45 (Tornado ASIC)
59 * 3Com 3c555 10/100Mbps/RJ-45 (MiniPCI, Laptop Hurricane)
60 * 3Com 3c556 10/100Mbps/RJ-45 (MiniPCI, Hurricane ASIC)
61 * 3Com 3c556B 10/100Mbps/RJ-45 (MiniPCI, Hurricane ASIC)
62 * 3Com 3c575TX 10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
63 * 3Com 3c575B 10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
64 * 3Com 3c575C 10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
65 * 3Com 3cxfem656 10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
66 * 3Com 3cxfem656b 10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
67 * 3Com 3cxfem656c 10/100Mbps/RJ-45 (Cardbus, Tornado ASIC)
68 * Dell Optiplex GX1 on-board 3c918 10/100Mbps/RJ-45
69 * Dell on-board 3c920 10/100Mbps/RJ-45
70 * Dell Precision on-board 3c905B 10/100Mbps/RJ-45
71 * Dell Latitude laptop docking station embedded 3c905-TX
78 * The 3c90x series chips use a bus-master DMA interface for transferring
87 * By contrast, the 3c90x cards support a fragment-based bus master
149 * - TX Checksumming will occasionally produce corrupt packets
150 * - TX Checksumming seems to reduce performance
168 "3Com 3c900-TPO Etherlink XL" },
170 "3Com 3c900-COMBO Etherlink XL" },
172 "3Com 3c905-TX Fast Etherlink XL" },
174 "3Com 3c905-T4 Fast Etherlink XL" },
176 "3Com 3c900B-TPO Etherlink XL" },
178 "3Com 3c900B-COMBO Etherlink XL" },
180 "3Com 3c900B-TPC Etherlink XL" },
182 "3Com 3c900B-FL Etherlink XL" },
184 "3Com 3c905B-TX Fast Etherlink XL" },
186 "3Com 3c905B-T4 Fast Etherlink XL" },
188 "3Com 3c905B-FX/SC Fast Etherlink XL" },
190 "3Com 3c905B-COMBO Fast Etherlink XL" },
192 "3Com 3c905C-TX Fast Etherlink XL" },
194 "3Com 3c920B-EMB Integrated Fast Etherlink XL" },
196 "3Com 3c920B-EMB-WNM Integrated Fast Etherlink XL" },
202 "3Com 3cSOHO100-TX OfficeConnect" },
204 "3Com 3c450-TX HomeConnect" },
289 * MII bit-bang glue
333 nitems(xl_devs) - 1);
341 *paddr = segs->ds_addr;
362 if (i == XL_TIMEOUT && bus_child_present(sc->xl_dev))
363 device_printf(sc->xl_dev, "command never completed!\n");
368 * PHYs (3c905-TX, 3c905-T4, 3c905B-T4) and those with built-in
369 * autoneg logic that's faked up to look like a PHY (3c905B-TX).
377 * Read the MII serial port for the MII bit-bang module.
396 * Write the MII serial port for the MII bit-bang module.
447 mii = device_get_softc(sc->xl_miibus);
454 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
456 if (sc->xl_type == XL_TYPE_905B) {
457 if ((IFM_OPTIONS(mii->mii_media_active) &
465 if (sc->xl_type == XL_TYPE_905B)
472 * Special support for the 3c905B-COMBO. This card has 10/100 support
474 * plus some non-MII media settings. In order to allow this, we have to
489 mii = device_get_softc(sc->xl_miibus);
490 ifm = &mii->mii_media;
492 if (sc->xl_media & (XL_MEDIAOPT_AUI | XL_MEDIAOPT_10FL)) {
496 if (sc->xl_type == XL_TYPE_905B &&
497 sc->xl_media == XL_MEDIAOPT_10FL) {
499 device_printf(sc->xl_dev, "found 10baseFL\n");
503 if (sc->xl_caps & XL_CAPS_FULL_DUPLEX)
508 device_printf(sc->xl_dev, "found AUI\n");
513 if (sc->xl_media & XL_MEDIAOPT_BNC) {
515 device_printf(sc->xl_dev, "found BNC\n");
537 device_printf(sc->xl_dev, "eeprom failed to come ready\n");
566 if (sc->xl_flags & XL_FLAG_EEPROM_OFFSET_30)
570 if (sc->xl_flags & XL_FLAG_8BITROM)
594 if (sc->xl_type == XL_TYPE_905B)
622 ifp = sc->xl_ifp;
642 if_foreach_llmaddr(sc->xl_ifp, xl_check_maddr_90x, &rxfilt);
650 * Note: the 3c905B currently only supports a 64-bit
653 * will have a 256-bit hash table, hence the routine
682 ifp = sc->xl_ifp;
708 if (if_foreach_llmaddr(sc->xl_ifp, xl_check_maddr_90xB, sc) > 0)
726 if (sc->xl_media & XL_MEDIAOPT_MII ||
727 sc->xl_media & XL_MEDIAOPT_BT4)
729 if (sc->xl_media & XL_MEDIAOPT_BTX)
750 if (sc->xl_media & XL_MEDIAOPT_BT) {
753 sc->xl_xcvr = XL_XCVR_10BT;
762 if (sc->xl_media & XL_MEDIAOPT_BFX) {
765 sc->xl_xcvr = XL_XCVR_100BFX;
773 if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {
776 sc->xl_xcvr = XL_XCVR_AUI;
785 sc->xl_xcvr = XL_XCVR_AUI;
794 if (sc->xl_media & XL_MEDIAOPT_BNC) {
797 sc->xl_xcvr = XL_XCVR_COAX;
829 device_printf(sc->xl_dev, "selecting %s, %s duplex\n", pmsg, dmsg);
841 ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?
851 if (sc->xl_flags & XL_FLAG_USE_MMIO)
861 device_printf(sc->xl_dev, "reset didn't complete\n");
876 if (sc->xl_flags & XL_FLAG_INVERT_LED_PWR ||
877 sc->xl_flags & XL_FLAG_INVERT_MII_PWR) {
881 ((sc->xl_flags & XL_FLAG_INVERT_LED_PWR) ?
883 ((sc->xl_flags & XL_FLAG_INVERT_MII_PWR) ?
902 while (t->xl_name != NULL) {
903 if ((pci_get_vendor(dev) == t->xl_vid) &&
904 (pci_get_device(dev) == t->xl_did)) {
905 device_set_desc(dev, t->xl_name);
919 * one Dell Latitude laptop docking station with an integrated 3c905-TX
936 if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO)) {
938 * Check the XCVR value. If it's not in the normal range
941 if (sc->xl_xcvr <= XL_XCVR_AUTO)
944 device_printf(sc->xl_dev,
945 "bogus xcvr value in EEPROM (%x)\n", sc->xl_xcvr);
946 device_printf(sc->xl_dev,
950 if (sc->xl_type == XL_TYPE_905B &&
951 sc->xl_media & XL_MEDIAOPT_10FL)
953 device_printf(sc->xl_dev,
955 device_printf(sc->xl_dev,
957 device_printf(sc->xl_dev,
977 case TC_DEVICEID_BOOMERANG_10BT: /* 3c900-TPO */
978 case TC_DEVICEID_KRAKATOA_10BT: /* 3c900B-TPO */
979 sc->xl_media = XL_MEDIAOPT_BT;
980 sc->xl_xcvr = XL_XCVR_10BT;
982 device_printf(sc->xl_dev,
985 case TC_DEVICEID_BOOMERANG_10BT_COMBO: /* 3c900-COMBO */
986 case TC_DEVICEID_KRAKATOA_10BT_COMBO: /* 3c900B-COMBO */
987 sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
988 sc->xl_xcvr = XL_XCVR_10BT;
990 device_printf(sc->xl_dev,
993 case TC_DEVICEID_KRAKATOA_10BT_TPC: /* 3c900B-TPC */
994 sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;
995 sc->xl_xcvr = XL_XCVR_10BT;
997 device_printf(sc->xl_dev, "guessing TPC (BNC/TP)\n");
999 case TC_DEVICEID_CYCLONE_10FL: /* 3c900B-FL */
1000 sc->xl_media = XL_MEDIAOPT_10FL;
1001 sc->xl_xcvr = XL_XCVR_AUI;
1003 device_printf(sc->xl_dev, "guessing 10baseFL\n");
1005 case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
1015 case TC_DEVICEID_TORNADO_10_100BT_920B: /* 3c920B-EMB */
1016 case TC_DEVICEID_TORNADO_10_100BT_920B_WNM: /* 3c920B-EMB-WNM */
1017 sc->xl_media = XL_MEDIAOPT_MII;
1018 sc->xl_xcvr = XL_XCVR_MII;
1020 device_printf(sc->xl_dev, "guessing MII\n");
1022 case TC_DEVICEID_BOOMERANG_100BT4: /* 3c905-T4 */
1023 case TC_DEVICEID_CYCLONE_10_100BT4: /* 3c905B-T4 */
1024 sc->xl_media = XL_MEDIAOPT_BT4;
1025 sc->xl_xcvr = XL_XCVR_MII;
1027 device_printf(sc->xl_dev, "guessing 100baseT4/MII\n");
1029 case TC_DEVICEID_HURRICANE_10_100BT: /* 3c905B-TX */
1030 case TC_DEVICEID_HURRICANE_10_100BT_SERV:/*3c980-TX */
1031 case TC_DEVICEID_TORNADO_10_100BT_SERV: /* 3c980C-TX */
1032 case TC_DEVICEID_HURRICANE_SOHO100TX: /* 3cSOHO100-TX */
1033 case TC_DEVICEID_TORNADO_10_100BT: /* 3c905C-TX */
1034 case TC_DEVICEID_TORNADO_HOMECONNECT: /* 3c450-TX */
1035 sc->xl_media = XL_MEDIAOPT_BTX;
1036 sc->xl_xcvr = XL_XCVR_AUTO;
1038 device_printf(sc->xl_dev, "guessing 10/100 internal\n");
1040 case TC_DEVICEID_CYCLONE_10_100_COMBO: /* 3c905B-COMBO */
1041 sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
1042 sc->xl_xcvr = XL_XCVR_AUTO;
1044 device_printf(sc->xl_dev,
1048 device_printf(sc->xl_dev,
1049 "unknown device ID: %x -- defaulting to 10baseT\n", devid);
1050 sc->xl_media = XL_MEDIAOPT_BT;
1057 * setup and ethernet/BPF attach.
1063 u_int16_t sinfo2, xcvr[2];
1071 sc->xl_dev = dev;
1073 mtx_init(&sc->xl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
1075 ifmedia_init(&sc->ifmedia, 0, xl_ifmedia_upd, xl_ifmedia_sts);
1079 sc->xl_flags = 0;
1081 sc->xl_flags |= XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_PHYOK;
1084 sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
1089 sc->xl_flags |= XL_FLAG_8BITROM;
1091 sc->xl_flags |= XL_FLAG_NO_XCVR_PWR;
1097 sc->xl_flags |= XL_FLAG_FUNCREG;
1103 sc->xl_flags |= XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 |
1106 sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK;
1108 sc->xl_flags |= XL_FLAG_INVERT_LED_PWR;
1110 sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
1112 sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
1115 sc->xl_flags |= XL_FLAG_INVERT_MII_PWR |
1119 sc->xl_flags |= XL_FLAG_PHYOK;
1122 case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
1126 sc->xl_flags |= XL_FLAG_NO_MMIO;
1137 if ((sc->xl_flags & XL_FLAG_NO_MMIO) == 0) {
1141 sc->xl_res = bus_alloc_resource_any(dev, res, &rid, RF_ACTIVE);
1144 if (sc->xl_res != NULL) {
1145 sc->xl_flags |= XL_FLAG_USE_MMIO;
1151 sc->xl_res = bus_alloc_resource_any(dev, res, &rid, RF_ACTIVE);
1152 if (sc->xl_res == NULL) {
1161 sc->xl_btag = rman_get_bustag(sc->xl_res);
1162 sc->xl_bhandle = rman_get_bushandle(sc->xl_res);
1164 if (sc->xl_flags & XL_FLAG_FUNCREG) {
1166 sc->xl_fres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
1169 if (sc->xl_fres == NULL) {
1175 sc->xl_ftag = rman_get_bustag(sc->xl_fres);
1176 sc->xl_fhandle = rman_get_bushandle(sc->xl_fres);
1181 sc->xl_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
1183 if (sc->xl_irq == NULL) {
1190 ifp = sc->xl_ifp = if_alloc(IFT_ETHER);
1208 callout_init_mtx(&sc->xl_tick_callout, &sc->xl_mtx, 0);
1209 NET_TASK_INIT(&sc->xl_task, 0, xl_rxeof_task, sc);
1213 * of DMA-able memory based on the tag. Also obtain the DMA
1221 &sc->xl_ldata.xl_rx_tag);
1227 error = bus_dmamem_alloc(sc->xl_ldata.xl_rx_tag,
1228 (void **)&sc->xl_ldata.xl_rx_list, BUS_DMA_NOWAIT |
1229 BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->xl_ldata.xl_rx_dmamap);
1232 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1233 sc->xl_ldata.xl_rx_tag = NULL;
1237 error = bus_dmamap_load(sc->xl_ldata.xl_rx_tag,
1238 sc->xl_ldata.xl_rx_dmamap, sc->xl_ldata.xl_rx_list,
1240 &sc->xl_ldata.xl_rx_dmaaddr, BUS_DMA_NOWAIT);
1243 bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
1244 sc->xl_ldata.xl_rx_dmamap);
1245 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1246 sc->xl_ldata.xl_rx_tag = NULL;
1253 &sc->xl_ldata.xl_tx_tag);
1259 error = bus_dmamem_alloc(sc->xl_ldata.xl_tx_tag,
1260 (void **)&sc->xl_ldata.xl_tx_list, BUS_DMA_NOWAIT |
1261 BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->xl_ldata.xl_tx_dmamap);
1264 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1265 sc->xl_ldata.xl_tx_tag = NULL;
1269 error = bus_dmamap_load(sc->xl_ldata.xl_tx_tag,
1270 sc->xl_ldata.xl_tx_dmamap, sc->xl_ldata.xl_tx_list,
1272 &sc->xl_ldata.xl_tx_dmaaddr, BUS_DMA_NOWAIT);
1275 bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
1276 sc->xl_ldata.xl_tx_dmamap);
1277 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1278 sc->xl_ldata.xl_tx_tag = NULL;
1288 NULL, &sc->xl_mtag);
1295 error = bus_dmamap_create(sc->xl_mtag, 0, &sc->xl_tmpmap);
1309 xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
1310 if (sc->xl_caps & XL_CAPS_NO_TXLENGTH ||
1311 !(sc->xl_caps & XL_CAPS_LARGE_PKTS))
1312 sc->xl_type = XL_TYPE_905B;
1314 sc->xl_type = XL_TYPE_90X;
1317 if ((sc->xl_caps & XL_CAPS_PWRMGMT) != 0 &&
1319 sc->xl_pmcap = pmcap;
1320 sc->xl_flags |= XL_FLAG_WOL;
1329 sc->xl_tx_thresh = XL_MIN_FRAMELEN;
1334 if (sc->xl_type == XL_TYPE_905B) {
1342 if ((sc->xl_flags & XL_FLAG_WOL) != 0)
1350 if_setsendqlen(ifp, XL_TX_LIST_CNT - 1);
1359 sc->xl_media = CSR_READ_2(sc, XL_W3_MEDIA_OPT);
1361 device_printf(dev, "media options word: %x\n", sc->xl_media);
1363 xl_read_eeprom(sc, (char *)&xcvr, XL_EE_ICFG_0, 2, 0);
1364 sc->xl_xcvr = xcvr[0] | xcvr[1] << 16;
1365 sc->xl_xcvr &= XL_ICFG_CONNECTOR_MASK;
1366 sc->xl_xcvr >>= XL_ICFG_CONNECTOR_BITS;
1370 if (sc->xl_media & XL_MEDIAOPT_MII ||
1371 sc->xl_media & XL_MEDIAOPT_BTX ||
1372 sc->xl_media & XL_MEDIAOPT_BT4) {
1383 if ((sc->xl_flags & XL_FLAG_PHYOK) == 0)
1385 error = mii_attach(dev, &sc->xl_miibus, ifp, xl_ifmedia_upd,
1387 sc->xl_type == XL_TYPE_905B ? MIIF_DOPAUSE : 0);
1400 if (sc->xl_xcvr == XL_XCVR_AUTO)
1404 * Do ifmedia setup.
1406 if (sc->xl_media & XL_MEDIAOPT_BT) {
1409 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
1410 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
1411 if (sc->xl_caps & XL_CAPS_FULL_DUPLEX)
1412 ifmedia_add(&sc->ifmedia,
1416 if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {
1420 if (sc->xl_type == XL_TYPE_905B &&
1421 sc->xl_media == XL_MEDIAOPT_10FL) {
1424 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_FL, 0, NULL);
1425 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_FL|IFM_HDX,
1427 if (sc->xl_caps & XL_CAPS_FULL_DUPLEX)
1428 ifmedia_add(&sc->ifmedia,
1433 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL);
1437 if (sc->xl_media & XL_MEDIAOPT_BNC) {
1440 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL);
1443 if (sc->xl_media & XL_MEDIAOPT_BFX) {
1446 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_FX, 0, NULL);
1452 if (sc->xl_miibus == NULL)
1453 ifmedia_set(&sc->ifmedia, media);
1456 if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) {
1466 error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET | INTR_MPSAFE,
1467 NULL, xl_intr, sc, &sc->xl_intrhand);
1484 * acquires/releases the non-recursible driver mutex to
1493 switch (sc->xl_xcvr) {
1499 if (sc->xl_type == XL_TYPE_905B &&
1500 sc->xl_media == XL_MEDIAOPT_10FL) {
1521 device_printf(sc->xl_dev, "unknown XCVR type: %d\n",
1522 sc->xl_xcvr);
1549 ifp = sc->xl_ifp;
1551 KASSERT(mtx_initialized(&sc->xl_mtx), ("xl mutex not initialized"));
1558 if (sc->xl_flags & XL_FLAG_USE_MMIO) {
1571 taskqueue_drain(taskqueue_swi, &sc->xl_task);
1572 callout_drain(&sc->xl_tick_callout);
1576 ifmedia_removeall(&sc->ifmedia);
1578 if (sc->xl_intrhand)
1579 bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
1580 if (sc->xl_irq)
1581 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
1582 if (sc->xl_fres != NULL)
1584 XL_PCI_FUNCMEM, sc->xl_fres);
1585 if (sc->xl_res)
1586 bus_release_resource(dev, res, rid, sc->xl_res);
1591 if (sc->xl_mtag) {
1592 bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
1593 bus_dma_tag_destroy(sc->xl_mtag);
1595 if (sc->xl_ldata.xl_rx_tag) {
1596 bus_dmamap_unload(sc->xl_ldata.xl_rx_tag,
1597 sc->xl_ldata.xl_rx_dmamap);
1598 bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
1599 sc->xl_ldata.xl_rx_dmamap);
1600 bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
1602 if (sc->xl_ldata.xl_tx_tag) {
1603 bus_dmamap_unload(sc->xl_ldata.xl_tx_tag,
1604 sc->xl_ldata.xl_tx_dmamap);
1605 bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
1606 sc->xl_ldata.xl_tx_dmamap);
1607 bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
1610 mtx_destroy(&sc->xl_mtx);
1627 cd = &sc->xl_cdata;
1628 ld = &sc->xl_ldata;
1630 cd->xl_tx_chain[i].xl_ptr = &ld->xl_tx_list[i];
1631 error = bus_dmamap_create(sc->xl_mtag, 0,
1632 &cd->xl_tx_chain[i].xl_map);
1635 cd->xl_tx_chain[i].xl_phys = ld->xl_tx_dmaaddr +
1637 if (i == (XL_TX_LIST_CNT - 1))
1638 cd->xl_tx_chain[i].xl_next = NULL;
1640 cd->xl_tx_chain[i].xl_next = &cd->xl_tx_chain[i + 1];
1643 cd->xl_tx_free = &cd->xl_tx_chain[0];
1644 cd->xl_tx_tail = cd->xl_tx_head = NULL;
1646 bus_dmamap_sync(ld->xl_tx_tag, ld->xl_tx_dmamap, BUS_DMASYNC_PREWRITE);
1662 cd = &sc->xl_cdata;
1663 ld = &sc->xl_ldata;
1665 cd->xl_tx_chain[i].xl_ptr = &ld->xl_tx_list[i];
1666 error = bus_dmamap_create(sc->xl_mtag, 0,
1667 &cd->xl_tx_chain[i].xl_map);
1670 cd->xl_tx_chain[i].xl_phys = ld->xl_tx_dmaaddr +
1672 if (i == (XL_TX_LIST_CNT - 1))
1673 cd->xl_tx_chain[i].xl_next = &cd->xl_tx_chain[0];
1675 cd->xl_tx_chain[i].xl_next = &cd->xl_tx_chain[i + 1];
1677 cd->xl_tx_chain[i].xl_prev =
1678 &cd->xl_tx_chain[XL_TX_LIST_CNT - 1];
1680 cd->xl_tx_chain[i].xl_prev =
1681 &cd->xl_tx_chain[i - 1];
1684 bzero(ld->xl_tx_list, XL_TX_LIST_SZ);
1685 ld->xl_tx_list[0].xl_status = htole32(XL_TXSTAT_EMPTY);
1687 cd->xl_tx_prod = 1;
1688 cd->xl_tx_cons = 1;
1689 cd->xl_tx_cnt = 0;
1691 bus_dmamap_sync(ld->xl_tx_tag, ld->xl_tx_dmamap, BUS_DMASYNC_PREWRITE);
1710 cd = &sc->xl_cdata;
1711 ld = &sc->xl_ldata;
1714 cd->xl_rx_chain[i].xl_ptr = &ld->xl_rx_list[i];
1715 error = bus_dmamap_create(sc->xl_mtag, 0,
1716 &cd->xl_rx_chain[i].xl_map);
1719 error = xl_newbuf(sc, &cd->xl_rx_chain[i]);
1722 if (i == (XL_RX_LIST_CNT - 1))
1726 nextptr = ld->xl_rx_dmaaddr +
1728 cd->xl_rx_chain[i].xl_next = &cd->xl_rx_chain[next];
1729 ld->xl_rx_list[i].xl_next = htole32(nextptr);
1732 bus_dmamap_sync(ld->xl_rx_tag, ld->xl_rx_dmamap, BUS_DMASYNC_PREWRITE);
1733 cd->xl_rx_head = &cd->xl_rx_chain[0];
1757 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1762 error = bus_dmamap_load_mbuf_sg(sc->xl_mtag, sc->xl_tmpmap, m_new,
1766 device_printf(sc->xl_dev, "can't map mbuf (error %d)\n",
1773 bus_dmamap_unload(sc->xl_mtag, c->xl_map);
1774 map = c->xl_map;
1775 c->xl_map = sc->xl_tmpmap;
1776 sc->xl_tmpmap = map;
1777 c->xl_mbuf = m_new;
1778 c->xl_ptr->xl_frag.xl_len = htole32(m_new->m_len | XL_LAST_FRAG);
1779 c->xl_ptr->xl_frag.xl_addr = htole32(segs->ds_addr);
1780 c->xl_ptr->xl_status = 0;
1781 bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREREAD);
1793 pos = sc->xl_cdata.xl_rx_head;
1796 if (pos->xl_ptr->xl_status)
1798 pos = pos->xl_next;
1804 sc->xl_cdata.xl_rx_head = pos;
1817 if_t ifp = sc->xl_ifp;
1825 bus_dmamap_sync(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap,
1827 while ((rxstat = le32toh(sc->xl_cdata.xl_rx_head->xl_ptr->xl_status))) {
1830 if (sc->rxcycles <= 0)
1832 sc->rxcycles--;
1835 cur_rx = sc->xl_cdata.xl_rx_head;
1836 sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
1852 * it should simply get re-used next time this descriptor
1857 cur_rx->xl_ptr->xl_status = 0;
1858 bus_dmamap_sync(sc->xl_ldata.xl_rx_tag,
1859 sc->xl_ldata.xl_rx_dmamap, BUS_DMASYNC_PREWRITE);
1869 device_printf(sc->xl_dev,
1870 "bad receive status -- packet dropped\n");
1872 cur_rx->xl_ptr->xl_status = 0;
1873 bus_dmamap_sync(sc->xl_ldata.xl_rx_tag,
1874 sc->xl_ldata.xl_rx_dmamap, BUS_DMASYNC_PREWRITE);
1879 bus_dmamap_sync(sc->xl_mtag, cur_rx->xl_map,
1881 m = cur_rx->xl_mbuf;
1892 cur_rx->xl_ptr->xl_status = 0;
1893 bus_dmamap_sync(sc->xl_ldata.xl_rx_tag,
1894 sc->xl_ldata.xl_rx_dmamap, BUS_DMASYNC_PREWRITE);
1897 bus_dmamap_sync(sc->xl_ldata.xl_rx_tag,
1898 sc->xl_ldata.xl_rx_dmamap, BUS_DMASYNC_PREWRITE);
1901 m->m_pkthdr.rcvif = ifp;
1902 m->m_pkthdr.len = m->m_len = total_len;
1907 m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
1909 m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
1914 m->m_pkthdr.csum_flags |=
1916 m->m_pkthdr.csum_data = 0xffff;
1949 CSR_WRITE_4(sc, XL_UPLIST_PTR, sc->xl_ldata.xl_rx_dmaaddr);
1950 sc->xl_cdata.xl_rx_head = &sc->xl_cdata.xl_rx_chain[0];
1966 if (if_getdrvflags(sc->xl_ifp) & IFF_DRV_RUNNING)
1979 if_t ifp = sc->xl_ifp;
1992 while (sc->xl_cdata.xl_tx_head != NULL) {
1993 cur_tx = sc->xl_cdata.xl_tx_head;
1998 sc->xl_cdata.xl_tx_head = cur_tx->xl_next;
1999 bus_dmamap_sync(sc->xl_mtag, cur_tx->xl_map,
2001 bus_dmamap_unload(sc->xl_mtag, cur_tx->xl_map);
2002 m_freem(cur_tx->xl_mbuf);
2003 cur_tx->xl_mbuf = NULL;
2007 cur_tx->xl_next = sc->xl_cdata.xl_tx_free;
2008 sc->xl_cdata.xl_tx_free = cur_tx;
2011 if (sc->xl_cdata.xl_tx_head == NULL) {
2012 sc->xl_wdog_timer = 0;
2013 sc->xl_cdata.xl_tx_tail = NULL;
2018 sc->xl_cdata.xl_tx_head->xl_phys);
2028 if_t ifp = sc->xl_ifp;
2033 bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap,
2035 idx = sc->xl_cdata.xl_tx_cons;
2036 while (idx != sc->xl_cdata.xl_tx_prod) {
2037 cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
2039 if (!(le32toh(cur_tx->xl_ptr->xl_status) &
2043 if (cur_tx->xl_mbuf != NULL) {
2044 bus_dmamap_sync(sc->xl_mtag, cur_tx->xl_map,
2046 bus_dmamap_unload(sc->xl_mtag, cur_tx->xl_map);
2047 m_freem(cur_tx->xl_mbuf);
2048 cur_tx->xl_mbuf = NULL;
2053 sc->xl_cdata.xl_tx_cnt--;
2057 if (sc->xl_cdata.xl_tx_cnt == 0)
2058 sc->xl_wdog_timer = 0;
2059 sc->xl_cdata.xl_tx_cons = idx;
2081 device_printf(sc->xl_dev,
2085 if (sc->xl_type == XL_TYPE_905B) {
2086 if (sc->xl_cdata.xl_tx_cnt) {
2090 i = sc->xl_cdata.xl_tx_cons;
2091 c = &sc->xl_cdata.xl_tx_chain[i];
2093 c->xl_phys);
2095 sc->xl_wdog_timer = 5;
2098 if (sc->xl_cdata.xl_tx_head != NULL) {
2100 sc->xl_cdata.xl_tx_head->xl_phys);
2101 sc->xl_wdog_timer = 5;
2110 sc->xl_tx_thresh < XL_PACKET_SIZE) {
2111 sc->xl_tx_thresh += XL_MIN_FRAMELEN;
2112 device_printf(sc->xl_dev,
2113 "tx underrun, increasing tx start threshold to %d bytes\n", sc->xl_tx_thresh);
2116 XL_CMD_TX_SET_START|sc->xl_tx_thresh);
2117 if (sc->xl_type == XL_TYPE_905B) {
2139 if_t ifp = sc->xl_ifp;
2168 if (sc->xl_type == XL_TYPE_905B)
2191 if (sc->xl_type == XL_TYPE_905B)
2222 sc->rxcycles = count;
2224 if (sc->xl_type == XL_TYPE_905B)
2230 if (sc->xl_type == XL_TYPE_905B)
2270 if (sc->xl_miibus != NULL) {
2271 mii = device_get_softc(sc->xl_miibus);
2279 callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc);
2285 if_t ifp = sc->xl_ifp;
2328 if_t ifp = sc->xl_ifp;
2334 error = bus_dmamap_load_mbuf_sg(sc->xl_mtag, c->xl_map, *m_head,
2335 sc->xl_cdata.xl_tx_segs, &nseg, BUS_DMA_NOWAIT);
2359 error = bus_dmamap_load_mbuf_sg(sc->xl_mtag, c->xl_map,
2360 *m_head, sc->xl_cdata.xl_tx_segs, &nseg, BUS_DMA_NOWAIT);
2376 bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREWRITE);
2380 KASSERT(sc->xl_cdata.xl_tx_segs[i].ds_len <= MCLBYTES,
2382 c->xl_ptr->xl_frag[i].xl_addr =
2383 htole32(sc->xl_cdata.xl_tx_segs[i].ds_addr);
2384 c->xl_ptr->xl_frag[i].xl_len =
2385 htole32(sc->xl_cdata.xl_tx_segs[i].ds_len);
2386 total_len += sc->xl_cdata.xl_tx_segs[i].ds_len;
2388 c->xl_ptr->xl_frag[nseg - 1].xl_len |= htole32(XL_LAST_FRAG);
2390 if (sc->xl_type == XL_TYPE_905B) {
2394 if ((*m_head)->m_pkthdr.csum_flags) {
2395 if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP)
2397 if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP)
2399 if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP)
2405 c->xl_ptr->xl_status = htole32(status);
2406 c->xl_ptr->xl_next = 0;
2408 c->xl_mbuf = *m_head;
2426 if (sc->xl_type == XL_TYPE_905B)
2452 if (sc->xl_cdata.xl_tx_free == NULL) {
2455 if (sc->xl_cdata.xl_tx_free == NULL) {
2461 start_tx = sc->xl_cdata.xl_tx_free;
2464 sc->xl_cdata.xl_tx_free != NULL;) {
2471 cur_tx = sc->xl_cdata.xl_tx_free;
2484 sc->xl_cdata.xl_tx_free = cur_tx->xl_next;
2485 cur_tx->xl_next = NULL;
2489 prev->xl_next = cur_tx;
2490 prev->xl_ptr->xl_next = htole32(cur_tx->xl_phys);
2498 BPF_MTAP(ifp, cur_tx->xl_mbuf);
2514 cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR);
2523 if (sc->xl_cdata.xl_tx_head != NULL) {
2524 sc->xl_cdata.xl_tx_tail->xl_next = start_tx;
2525 sc->xl_cdata.xl_tx_tail->xl_ptr->xl_next =
2526 htole32(start_tx->xl_phys);
2527 sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status &=
2529 sc->xl_cdata.xl_tx_tail = cur_tx;
2531 sc->xl_cdata.xl_tx_head = start_tx;
2532 sc->xl_cdata.xl_tx_tail = cur_tx;
2534 bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap,
2537 CSR_WRITE_4(sc, XL_DOWNLIST_PTR, start_tx->xl_phys);
2546 sc->xl_wdog_timer = 5;
2563 taskqueue_enqueue(taskqueue_swi, &sc->xl_task);
2581 idx = sc->xl_cdata.xl_tx_prod;
2582 start_tx = &sc->xl_cdata.xl_tx_chain[idx];
2585 sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL;) {
2586 if ((XL_TX_LIST_CNT - sc->xl_cdata.xl_tx_cnt) < 3) {
2596 cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
2611 prev->xl_ptr->xl_next = htole32(cur_tx->xl_phys);
2618 BPF_MTAP(ifp, cur_tx->xl_mbuf);
2621 sc->xl_cdata.xl_tx_cnt++;
2637 cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR);
2640 sc->xl_cdata.xl_tx_prod = idx;
2641 start_tx->xl_prev->xl_ptr->xl_next = htole32(start_tx->xl_phys);
2642 bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap,
2648 sc->xl_wdog_timer = 5;
2664 if_t ifp = sc->xl_ifp;
2680 if (sc->xl_miibus == NULL) {
2688 if (sc->xl_miibus != NULL)
2689 mii = device_get_softc(sc->xl_miibus);
2695 if ((sc->xl_flags & XL_FLAG_WOL) != 0) {
2704 if_getlladdr(sc->xl_ifp)[i]);
2720 device_printf(sc->xl_dev, "initialization of the rx ring failed (%d)\n",
2727 if (sc->xl_type == XL_TYPE_905B)
2732 device_printf(sc->xl_dev, "initialization of the tx ring failed (%d)\n",
2747 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_SET_START|sc->xl_tx_thresh);
2758 if (sc->xl_type == XL_TYPE_905B) {
2778 CSR_WRITE_4(sc, XL_UPLIST_PTR, sc->xl_ldata.xl_rx_dmaaddr);
2782 if (sc->xl_type == XL_TYPE_905B) {
2789 sc->xl_cdata.xl_tx_chain[0].xl_phys);
2796 * the DC-DC converter.
2799 if (sc->xl_xcvr == XL_XCVR_COAX)
2811 if (sc->xl_type == XL_TYPE_905B)
2839 if (sc->xl_flags & XL_FLAG_FUNCREG)
2840 bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000);
2862 sc->xl_wdog_timer = 0;
2863 callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc);
2878 if (sc->xl_miibus != NULL)
2879 mii = device_get_softc(sc->xl_miibus);
2881 ifm = &sc->ifmedia;
2883 ifm = &mii->mii_media;
2885 switch (IFM_SUBTYPE(ifm->ifm_media)) {
2890 xl_setmode(sc, ifm->ifm_media);
2895 if (sc->xl_media & XL_MEDIAOPT_MII ||
2896 sc->xl_media & XL_MEDIAOPT_BTX ||
2897 sc->xl_media & XL_MEDIAOPT_BT4) {
2901 xl_setmode(sc, ifm->ifm_media);
2922 if (sc->xl_miibus != NULL)
2923 mii = device_get_softc(sc->xl_miibus);
2932 ifmr->ifm_active = IFM_ETHER;
2933 ifmr->ifm_status = IFM_AVALID;
2936 ifmr->ifm_status |= IFM_ACTIVE;
2940 ifmr->ifm_active = IFM_ETHER|IFM_10_T;
2942 ifmr->ifm_active |= IFM_FDX;
2944 ifmr->ifm_active |= IFM_HDX;
2947 if (sc->xl_type == XL_TYPE_905B &&
2948 sc->xl_media == XL_MEDIAOPT_10FL) {
2949 ifmr->ifm_active = IFM_ETHER|IFM_10_FL;
2951 ifmr->ifm_active |= IFM_FDX;
2953 ifmr->ifm_active |= IFM_HDX;
2955 ifmr->ifm_active = IFM_ETHER|IFM_10_5;
2958 ifmr->ifm_active = IFM_ETHER|IFM_10_2;
2969 ifmr->ifm_active = mii->mii_media_active;
2970 ifmr->ifm_status = mii->mii_media_status;
2974 ifmr->ifm_active = IFM_ETHER|IFM_100_FX;
2977 if_printf(ifp, "unknown XCVR type: %d\n", icfg);
2997 (if_getflags(ifp) ^ sc->xl_if_flags) &
3006 sc->xl_if_flags = if_getflags(ifp);
3019 if (sc->xl_miibus != NULL)
3020 mii = device_get_softc(sc->xl_miibus);
3023 &sc->ifmedia, command);
3026 &mii->mii_media, command);
3029 mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
3051 if (sc->xl_flags & XL_FLAG_FUNCREG)
3052 bus_space_write_4(sc->xl_ftag,
3053 sc->xl_fhandle, 4, 0x8000);
3086 if_t ifp = sc->xl_ifp;
3092 if (sc->xl_wdog_timer == 0 || --sc->xl_wdog_timer != 0)
3098 if (sc->xl_type == XL_TYPE_905B) {
3100 if (sc->xl_cdata.xl_tx_cnt == 0)
3104 if (sc->xl_cdata.xl_tx_head == NULL)
3108 device_printf(sc->xl_dev,
3109 "watchdog timeout (missed Tx interrupts) -- recovering\n");
3116 device_printf(sc->xl_dev, "watchdog timeout\n");
3119 device_printf(sc->xl_dev,
3120 "no carrier - transceiver cable problem?\n");
3126 if (sc->xl_type == XL_TYPE_905B)
3143 if_t ifp = sc->xl_ifp;
3147 sc->xl_wdog_timer = 0;
3168 if (sc->xl_flags & XL_FLAG_FUNCREG)
3169 bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000);
3172 callout_stop(&sc->xl_tick_callout);
3178 if (sc->xl_cdata.xl_rx_chain[i].xl_mbuf != NULL) {
3179 bus_dmamap_unload(sc->xl_mtag,
3180 sc->xl_cdata.xl_rx_chain[i].xl_map);
3181 bus_dmamap_destroy(sc->xl_mtag,
3182 sc->xl_cdata.xl_rx_chain[i].xl_map);
3183 m_freem(sc->xl_cdata.xl_rx_chain[i].xl_mbuf);
3184 sc->xl_cdata.xl_rx_chain[i].xl_mbuf = NULL;
3187 if (sc->xl_ldata.xl_rx_list != NULL)
3188 bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
3193 if (sc->xl_cdata.xl_tx_chain[i].xl_mbuf != NULL) {
3194 bus_dmamap_unload(sc->xl_mtag,
3195 sc->xl_cdata.xl_tx_chain[i].xl_map);
3196 bus_dmamap_destroy(sc->xl_mtag,
3197 sc->xl_cdata.xl_tx_chain[i].xl_map);
3198 m_freem(sc->xl_cdata.xl_tx_chain[i].xl_mbuf);
3199 sc->xl_cdata.xl_tx_chain[i].xl_mbuf = NULL;
3202 if (sc->xl_ldata.xl_tx_list != NULL)
3203 bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
3241 ifp = sc->xl_ifp;
3261 if ((sc->xl_flags & XL_FLAG_WOL) == 0)
3264 ifp = sc->xl_ifp;
3276 pmstat = pci_read_config(sc->xl_dev,
3277 sc->xl_pmcap + PCIR_POWER_STATUS, 2);
3282 pci_write_config(sc->xl_dev,
3283 sc->xl_pmcap + PCIR_POWER_STATUS, pmstat, 2);