diff options
author | Brooks Davis <brooks@FreeBSD.org> | 2019-05-17 15:24:44 +0000 |
---|---|---|
committer | Brooks Davis <brooks@FreeBSD.org> | 2019-05-17 15:24:44 +0000 |
commit | 7a582e5374c84af54912898bb139ed3384da7328 (patch) | |
tree | 7cefc28a520bb20cde6e685b95709db681aa11c4 | |
parent | 02fae06a11b4ff8fbc9293fd0760b597f21b3cf1 (diff) |
FCP-101: Remove xe(4)
Relnotes: yes
FCP: https://github.com/freebsd/fcp/blob/master/fcp-0101.md
Reviewed by: jhb, imp
Differential Revision: https://reviews.freebsd.org/D20230
Notes
Notes:
svn path=/head/; revision=347923
-rw-r--r-- | ObsoleteFiles.inc | 2 | ||||
-rw-r--r-- | share/man/man4/Makefile | 2 | ||||
-rw-r--r-- | share/man/man4/xe.4 | 176 | ||||
-rw-r--r-- | sys/conf/NOTES | 4 | ||||
-rw-r--r-- | sys/conf/files | 2 | ||||
-rw-r--r-- | sys/dev/xe/if_xe.c | 2078 | ||||
-rw-r--r-- | sys/dev/xe/if_xe_pccard.c | 391 | ||||
-rw-r--r-- | sys/dev/xe/if_xereg.h | 702 | ||||
-rw-r--r-- | sys/dev/xe/if_xevar.h | 92 | ||||
-rw-r--r-- | sys/i386/conf/GENERIC | 1 | ||||
-rw-r--r-- | sys/modules/Makefile | 2 | ||||
-rw-r--r-- | sys/modules/xe/Makefile | 9 |
12 files changed, 2 insertions, 3459 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 40b83cdcf642..6604c94cdcd9 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -62,6 +62,8 @@ OLD_FILES+=usr/share/man/man4/txp.4 OLD_FILES+=usr/share/man/man4/if_txp.4 OLD_FILES+=usr/share/man/man4/vx.4 OLD_FILES+=usr/share/man/man4/wb.4 +OLD_FILES+=usr/share/man/man4/xe.4 +OLD_FILES+=usr/share/man/man4/if_xe.4 # 20190513: libcap_sysctl interface change OLD_FILES+=lib/casper/libcap_sysctl.1 # 20190509: tests/sys/opencrypto requires the net/py-dpkt package. diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 0a2a6851c61f..8a8fb67a3aad 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -563,7 +563,6 @@ MAN= aac.4 \ wmt.4 \ ${_wpi.4} \ wsp.4 \ - xe.4 \ ${_xen.4} \ xhci.4 \ xl.4 \ @@ -726,7 +725,6 @@ MLINKS+=${_vtnet.4} ${_if_vtnet.4} MLINKS+=watchdog.4 SW_WATCHDOG.4 MLINKS+=wi.4 if_wi.4 MLINKS+=${_wpi.4} ${_if_wpi.4} -MLINKS+=xe.4 if_xe.4 MLINKS+=xl.4 if_xl.4 .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" diff --git a/share/man/man4/xe.4 b/share/man/man4/xe.4 deleted file mode 100644 index d4d8fd08b5eb..000000000000 --- a/share/man/man4/xe.4 +++ /dev/null @@ -1,176 +0,0 @@ -.\" -.\" Copyright (c) 2003 Tom Rhodes -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd October 24, 2018 -.Dt XE 4 -.Os -.Sh NAME -.Nm xe -.Nd "Xircom PCMCIA Ethernet device driver" -.Sh SYNOPSIS -To compile this driver into the kernel, -place the following line in your -kernel configuration file: -.Bd -ragged -offset indent -.Cd "device xe" -.Ed -.Pp -Alternatively, to load the driver as a -module at boot time, place the following line in -.Xr loader.conf 5 : -.Bd -literal -offset indent -if_xe_load="YES" -.Ed -.Sh DEPRECATION NOTICE -The -.Nm -driver is not present in -.Fx 13.0 -and later. -See https://github.com/freebsd/fcp/blob/master/fcp-0101.md for more -information. -.Sh DESCRIPTION -The -.Nm -driver supports -.Tn PCMCIA -Ethernet adapters based on Xircom CE2- and CE3-class hardware. -This includes devices made by Xircom along with -various -.Tn OEM -manufacturers. -.Pp -Please note that the -.Nm -driver only supports -.Tn PCMCIA -cards and their Ethernet functions. -.Nm -does not support the on-board modem device located on some -version of the Ethernet/modem combo cards. -In particular, Xircom RealPort2 cards are not supported by this driver. -.Pp -The -.Nm -driver supports the following media types: -.Bl -tag -width ".Cm autoselect" -.It Cm autoselect -Enable autoselection of media type and options. -.It Cm 10Base2/BNC -Select 10Mbps operation on a BNC coaxial connector. -.It Cm 10BaseT/UTP -Select 10Mbps operation on a RJ-45 connector. -.It Cm 100BaseTX -Select 100Mbps operation. -.El -.Pp -Note that 100BaseTX operation is not available on CE2-class cards, -while the 10Base2/BNC mode is only available on CE2-class cards. -Full-duplex -operation is currently not supported. -For more information on configuring network interface devices, -see -.Xr ifconfig 8 . -.Sh HARDWARE -The -.Nm -driver supports the following cards: -.Pp -.Bl -bullet -compact -.It -Xircom CreditCard Ethernet (PS-CE2-10) -.It -Xircom CreditCard Ethernet + Modem 28 (PS-CEM-28) -.It -Xircom CreditCard Ethernet + Modem 33 (CEM33) -.It -Xircom CreditCard 10/100 (CE3, CE3B) -.It -Xircom CreditCard Ethernet 10/100 + Modem 56 (CEM56) -.It -Xircom RealPort Ethernet 10 (RE10) -.It -Xircom RealPort Ethernet 10/100 (RE100) -.It -Xircom RealPort Ethernet 10/100 + Modem 56 (REM56, REM56G) -.It -Accton Fast EtherCard-16 (EN2226) -.It -Compaq Microcom CPQ550 Ethernet/Modem PC Card -.It -Compaq Netelligent 10/100 PC Card (CPQ-10/100) -.It -Intel EtherExpress Pro/100 PC Card Mobile Adapter 16 (Pro/100 M16A) -.It -Intel EtherExpress Pro/100 LAN/Modem PC Card Adapter (Pro/100 M16B) -.El -.Pp -Other similar devices using the same hardware may also be supported. -.Sh DIAGNOSTICS -.Bl -diag -.It "xe%d: Cannot allocate ioport" -.It "xe%d: Cannot allocate irq" -A fatal initialization error occurred while attempting to allocate -system resources for the card. -.It "xe%d: Unable to fix your %s combo card" -A fatal initialization error occurred while attempting to attach an -Ethernet/modem combo card. -.It "xe%d: watchdog timeout: resetting card" -The card failed to generate an interrupt acknowledging a -transmitted packet. -May indicate a -.Tn PCMCIA -configuration problem. -.It "xe%d: no carrier" -The card has lost all contact with the network; this -usually indicates a cable problem. -.El -.Sh SEE ALSO -.Xr pccard 4 , -.Xr ifconfig 8 -.Sh HISTORY -The -.Nm -driver first appeared in -.Fx 3.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm -device driver was written by -.An Scott Mitchell Aq Mt rsm@FreeBSD.org . -This manual page was written by -.An Scott Mitchell Aq Mt rsm@FreeBSD.org , -and -.An Tom Rhodes Aq Mt trhodes@FreeBSD.org . -.Sh BUGS -Supported devices will fail to attach on some machines using the -.Tn NEWCARD -.Tn PC -Card framework. -.Pp -Automatic media selection is usually unreliable. diff --git a/sys/conf/NOTES b/sys/conf/NOTES index d2e37ee1ff9f..30ae142ba29b 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2003,9 +2003,6 @@ device xmphy # XaQti XMAC II # wi: Lucent WaveLAN/IEEE 802.11 PCMCIA adapters. Note: this supports both # the PCMCIA and ISA cards: the ISA card is really a PCMCIA to ISA # bridge with a PCMCIA adapter plugged into it. -# xe: Xircom/Intel EtherExpress Pro100/16 PC Card ethernet controller, -# Accton Fast EtherCard-16, Compaq Netelligent 10/100 PC Card, -# Toshiba 10/100 Ethernet PC Card, Xircom 16-bit Ethernet + Modem 56 # xl: Support for the 3Com 3c900, 3c905, 3c905B and 3c905C (Fast) # Etherlink XL cards and integrated controllers. This includes the # integrated 3c905B-TX chips in certain Dell Optiplex and Dell @@ -2017,7 +2014,6 @@ device xmphy # XaQti XMAC II device an device wi -device xe # PCI Ethernet NICs that use the common MII bus controller code. device ae # Attansic/Atheros L2 FastEthernet diff --git a/sys/conf/files b/sys/conf/files index 77cc7ea46cbf..e6fd1398ac6a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3432,8 +3432,6 @@ dev/xdma/xdma_mbuf.c optional xdma dev/xdma/xdma_queue.c optional xdma dev/xdma/xdma_sg.c optional xdma dev/xdma/xdma_sglist.c optional xdma -dev/xe/if_xe.c optional xe -dev/xe/if_xe_pccard.c optional xe pccard dev/xen/balloon/balloon.c optional xenhvm dev/xen/blkfront/blkfront.c optional xenhvm dev/xen/blkback/blkback.c optional xenhvm diff --git a/sys/dev/xe/if_xe.c b/sys/dev/xe/if_xe.c deleted file mode 100644 index b421f36ff674..000000000000 --- a/sys/dev/xe/if_xe.c +++ /dev/null @@ -1,2078 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-3-Clause - * - * Copyright (c) 1998, 1999, 2003 Scott Mitchell - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/*- - * Portions of this software were derived from Werner Koch's xirc2ps driver - * for Linux under the terms of the following license (from v1.30 of the - * xirc2ps driver): - * - * Copyright (c) 1997 by Werner Koch (dd9jn) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * FreeBSD device driver for Xircom CreditCard PCMCIA Ethernet adapters. The - * following cards are currently known to work with the driver: - * Xircom CreditCard 10/100 (CE3) - * Xircom CreditCard Ethernet + Modem 28 (CEM28) - * Xircom CreditCard Ethernet 10/100 + Modem 56 (CEM56) - * Xircom RealPort Ethernet 10 - * Xircom RealPort Ethernet 10/100 - * Xircom RealPort Ethernet 10/100 + Modem 56 (REM56, REM56G) - * Intel EtherExpress Pro/100 PC Card Mobile Adapter 16 (Pro/100 M16A) - * Compaq Netelligent 10/100 PC Card (CPQ-10/100) - * - * Some other cards *should* work, but support for them is either broken or in - * an unknown state at the moment. I'm always interested in hearing from - * people who own any of these cards: - * Xircom CreditCard 10Base-T (PS-CE2-10) - * Xircom CreditCard Ethernet + ModemII (CEM2) - * Xircom CEM28 and CEM33 Ethernet/Modem cards (may be variants of CEM2?) - * - * Thanks to all who assisted with the development and testing of the driver, - * especially: Werner Koch, Duke Kamstra, Duncan Barclay, Jason George, Dru - * Nelson, Mike Kephart, Bill Rainey and Douglas Rand. Apologies if I've left - * out anyone who deserves a mention here. - * - * Special thanks to Ade Lovett for both hosting the mailing list and doing - * the CEM56/REM56 support code; and the FreeBSD UK Users' Group for hosting - * the web pages. - * - * Author email: <scott@uk.freebsd.org> - * Driver web page: http://ukug.uk.freebsd.org/~scott/xe_drv/ - */ - - -#include <sys/param.h> -#include <sys/cdefs.h> -#include <sys/errno.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/systm.h> -#include <sys/uio.h> -#include <sys/sysctl.h> - -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/ethernet.h> -#include <net/if.h> -#include <net/if_var.h> -#include <net/if_arp.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_mib.h> -#include <net/bpf.h> -#include <net/if_types.h> - -#include <dev/xe/if_xereg.h> -#include <dev/xe/if_xevar.h> - -/* - * MII command structure - */ -struct xe_mii_frame { - uint8_t mii_stdelim; - uint8_t mii_opcode; - uint8_t mii_phyaddr; - uint8_t mii_regaddr; - uint8_t mii_turnaround; - uint16_t mii_data; -}; - -/* - * Media autonegotiation progress constants - */ -#define XE_AUTONEG_NONE 0 /* No autonegotiation in progress */ -#define XE_AUTONEG_WAITING 1 /* Waiting for transmitter to go idle */ -#define XE_AUTONEG_STARTED 2 /* Waiting for autonegotiation to complete */ -#define XE_AUTONEG_100TX 3 /* Trying to force 100baseTX link */ -#define XE_AUTONEG_FAIL 4 /* Autonegotiation failed */ - -/* - * Prototypes start here - */ -static void xe_init(void *xscp); -static void xe_init_locked(struct xe_softc *scp); -static void xe_start(struct ifnet *ifp); -static void xe_start_locked(struct ifnet *ifp); -static int xe_ioctl(struct ifnet *ifp, u_long command, caddr_t data); -static void xe_watchdog(void *arg); -static void xe_intr(void *xscp); -static void xe_txintr(struct xe_softc *scp, uint8_t txst1); -static void xe_macintr(struct xe_softc *scp, uint8_t rst0, uint8_t txst0, - uint8_t txst1); -static void xe_rxintr(struct xe_softc *scp, uint8_t rst0); -static int xe_media_change(struct ifnet *ifp); -static void xe_media_status(struct ifnet *ifp, struct ifmediareq *mrp); -static void xe_setmedia(void *arg); -static void xe_reset(struct xe_softc *scp); -static void xe_enable_intr(struct xe_softc *scp); -static void xe_disable_intr(struct xe_softc *scp); -static void xe_set_multicast(struct xe_softc *scp); -static void xe_set_addr(struct xe_softc *scp, uint8_t* addr, unsigned idx); -static void xe_mchash(struct xe_softc *scp, const uint8_t *addr); -static int xe_pio_write_packet(struct xe_softc *scp, struct mbuf *mbp); - -/* - * MII functions - */ -static void xe_mii_sync(struct xe_softc *scp); -static int xe_mii_init(struct xe_softc *scp); -static void xe_mii_send(struct xe_softc *scp, uint32_t bits, int cnt); -static int xe_mii_readreg(struct xe_softc *scp, - struct xe_mii_frame *frame); -static int xe_mii_writereg(struct xe_softc *scp, - struct xe_mii_frame *frame); -static uint16_t xe_phy_readreg(struct xe_softc *scp, uint16_t reg); -static void xe_phy_writereg(struct xe_softc *scp, uint16_t reg, - uint16_t data); - -/* - * Debugging functions - */ -static void xe_mii_dump(struct xe_softc *scp); -#if 0 -static void xe_reg_dump(struct xe_softc *scp); -#endif - -/* - * Debug logging levels - set with hw.xe.debug sysctl - * 0 = None - * 1 = More hardware details, probe/attach progress - * 2 = Most function calls, ioctls and media selection progress - * 3 = Everything - interrupts, packets in/out and multicast address setup - */ -#define XE_DEBUG -#ifdef XE_DEBUG - -/* sysctl vars */ -static SYSCTL_NODE(_hw, OID_AUTO, xe, CTLFLAG_RD, 0, "if_xe parameters"); - -int xe_debug = 0; -SYSCTL_INT(_hw_xe, OID_AUTO, debug, CTLFLAG_RW, &xe_debug, 0, - "if_xe debug level"); - -#define DEVPRINTF(level, arg) if (xe_debug >= (level)) device_printf arg -#define DPRINTF(level, arg) if (xe_debug >= (level)) printf arg -#define XE_MII_DUMP(scp) if (xe_debug >= 3) xe_mii_dump(scp) -#if 0 -#define XE_REG_DUMP(scp) if (xe_debug >= 3) xe_reg_dump(scp) -#endif -#else -#define DEVPRINTF(level, arg) -#define DPRINTF(level, arg) -#define XE_MII_DUMP(scp) -#if 0 -#define XE_REG_DUMP(scp) -#endif -#endif - -/* - * Attach a device. - */ -int -xe_attach(device_t dev) -{ - struct xe_softc *scp = device_get_softc(dev); - int err; - - DEVPRINTF(2, (dev, "attach\n")); - - /* Initialise stuff... */ - scp->dev = dev; - scp->ifp = if_alloc(IFT_ETHER); - if (scp->ifp == NULL) - return (ENOSPC); - scp->ifm = &scp->ifmedia; - scp->autoneg_status = XE_AUTONEG_NONE; - mtx_init(&scp->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); - callout_init_mtx(&scp->wdog_timer, &scp->lock, 0); - - /* Initialise the ifnet structure */ - scp->ifp->if_softc = scp; - if_initname(scp->ifp, device_get_name(dev), device_get_unit(dev)); - scp->ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); - scp->ifp->if_linkmib = &scp->mibdata; - scp->ifp->if_linkmiblen = sizeof(scp->mibdata); - scp->ifp->if_start = xe_start; - scp->ifp->if_ioctl = xe_ioctl; - scp->ifp->if_init = xe_init; - scp->ifp->if_baudrate = 100000000; - IFQ_SET_MAXLEN(&scp->ifp->if_snd, ifqmaxlen); - - /* Initialise the ifmedia structure */ - ifmedia_init(scp->ifm, 0, xe_media_change, xe_media_status); - callout_init_mtx(&scp->media_timer, &scp->lock, 0); - - /* Add supported media types */ - if (scp->mohawk) { - ifmedia_add(scp->ifm, IFM_ETHER|IFM_100_TX, 0, NULL); - ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); - ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); - } - ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL); - if (scp->ce2) - ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_2, 0, NULL); - ifmedia_add(scp->ifm, IFM_ETHER|IFM_AUTO, 0, NULL); - - /* Default is to autoselect best supported media type */ - ifmedia_set(scp->ifm, IFM_ETHER|IFM_AUTO); - - /* Get the hardware into a known state */ - XE_LOCK(scp); - xe_reset(scp); - XE_UNLOCK(scp); - - /* Get hardware version numbers */ - XE_SELECT_PAGE(4); - scp->version = XE_INB(XE_BOV); - if (scp->mohawk) - scp->srev = (XE_INB(XE_BOV) & 0x70) >> 4; - else - scp->srev = (XE_INB(XE_BOV) & 0x30) >> 4; - - /* Print some useful information */ - device_printf(dev, "version 0x%02x/0x%02x%s%s\n", scp->version, - scp->srev, scp->mohawk ? ", 100Mbps capable" : "", - scp->modem ? ", with modem" : ""); - if (scp->mohawk) { - XE_SELECT_PAGE(0x10); - DEVPRINTF(1, (dev, - "DingoID=0x%04x, RevisionID=0x%04x, VendorID=0x%04x\n", - XE_INW(XE_DINGOID), XE_INW(XE_RevID), XE_INW(XE_VendorID))); - } - if (scp->ce2) { - XE_SELECT_PAGE(0x45); - DEVPRINTF(1, (dev, "CE2 version = 0x%02x\n", XE_INB(XE_REV))); - } - - /* Attach the interface */ - ether_ifattach(scp->ifp, scp->enaddr); - - err = bus_setup_intr(dev, scp->irq_res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, xe_intr, scp, &scp->intrhand); - if (err) { - ether_ifdetach(scp->ifp); - mtx_destroy(&scp->lock); - return (err); - } - - gone_by_fcp101_dev(dev); - - /* Done */ - return (0); -} - -/* - * Complete hardware intitialisation and enable output. Exits without doing - * anything if there's no address assigned to the card, or if media selection - * is in progress (the latter implies we've already run this function). - */ -static void -xe_init(void *xscp) -{ - struct xe_softc *scp = xscp; - - XE_LOCK(scp); - xe_init_locked(scp); - XE_UNLOCK(scp); -} - -static void -xe_init_locked(struct xe_softc *scp) -{ - unsigned i; - - if (scp->autoneg_status != XE_AUTONEG_NONE) - return; - - DEVPRINTF(2, (scp->dev, "init\n")); - - /* Reset transmitter flags */ - scp->tx_queued = 0; - scp->tx_tpr = 0; - scp->tx_timeouts = 0; - scp->tx_thres = 64; - scp->tx_min = ETHER_MIN_LEN - ETHER_CRC_LEN; - scp->tx_timeout = 0; - - /* Soft reset the card */ - XE_SELECT_PAGE(0); - XE_OUTB(XE_CR, XE_CR_SOFT_RESET); - DELAY(40000); - XE_OUTB(XE_CR, 0); - DELAY(40000); - - if (scp->mohawk) { - /* - * set GP1 and GP2 as outputs (bits 2 & 3) - * set GP1 low to power on the ML6692 (bit 0) - * set GP2 high to power on the 10Mhz chip (bit 1) - */ - XE_SELECT_PAGE(4); - XE_OUTB(XE_GPR0, XE_GPR0_GP2_SELECT | XE_GPR0_GP1_SELECT | - XE_GPR0_GP2_OUT); - } - - /* Shut off interrupts */ - xe_disable_intr(scp); - - /* Wait for everything to wake up */ - DELAY(500000); - - /* Check for PHY */ - if (scp->mohawk) - scp->phy_ok = xe_mii_init(scp); - - /* Disable 'source insertion' (not sure what that means) */ - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC0, XE_SWC0_NO_SRC_INSERT); - - /* Set 8K/24K Tx/Rx buffer split */ - if (scp->srev != 1) { - XE_SELECT_PAGE(2); - XE_OUTW(XE_RBS, 0x2000); - } - - /* Enable early transmit mode on Mohawk/Dingo */ - if (scp->mohawk) { - XE_SELECT_PAGE(0x03); - XE_OUTW(XE_TPT, scp->tx_thres); - XE_SELECT_PAGE(0x01); - XE_OUTB(XE_ECR, XE_INB(XE_ECR) | XE_ECR_EARLY_TX); - } - - /* Put MAC address in first 'individual address' register */ - XE_SELECT_PAGE(0x50); - for (i = 0; i < ETHER_ADDR_LEN; i++) - XE_OUTB(0x08 + i, IF_LLADDR(scp->ifp)[scp->mohawk ? 5 - i : i]); - - /* Set up multicast addresses */ - xe_set_multicast(scp); - - /* Fix the receive data offset -- reset can leave it off-by-one */ - XE_SELECT_PAGE(0); - XE_OUTW(XE_DO, 0x2000); - - /* Set interrupt masks */ - XE_SELECT_PAGE(1); - XE_OUTB(XE_IMR0, XE_IMR0_TX_PACKET | XE_IMR0_MAC_INTR | - XE_IMR0_RX_PACKET); - - /* Set MAC interrupt masks */ - XE_SELECT_PAGE(0x40); - XE_OUTB(XE_RX0Msk, - ~(XE_RX0M_RX_OVERRUN | XE_RX0M_CRC_ERROR | XE_RX0M_ALIGN_ERROR | - XE_RX0M_LONG_PACKET)); - XE_OUTB(XE_TX0Msk, - ~(XE_TX0M_SQE_FAIL | XE_TX0M_LATE_COLLISION | XE_TX0M_TX_UNDERRUN | - XE_TX0M_16_COLLISIONS | XE_TX0M_NO_CARRIER)); - - /* Clear MAC status registers */ - XE_SELECT_PAGE(0x40); - XE_OUTB(XE_RST0, 0x00); - XE_OUTB(XE_TXST0, 0x00); - - /* Enable receiver and put MAC online */ - XE_SELECT_PAGE(0x40); - XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE); - - /* Set up IMR, enable interrupts */ - xe_enable_intr(scp); - - /* Start media selection */ - xe_setmedia(scp); - - /* Enable output */ - scp->ifp->if_drv_flags |= IFF_DRV_RUNNING; - scp->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - callout_reset(&scp->wdog_timer, hz, xe_watchdog, scp); -} - -/* - * Start output on interface. Should be called at splimp() priority. Check - * that the output is idle (ie, IFF_DRV_OACTIVE is not set) before calling this - * function. If media selection is in progress we set IFF_DRV_OACTIVE ourselves - * and return immediately. - */ -static void -xe_start(struct ifnet *ifp) -{ - struct xe_softc *scp = ifp->if_softc; - - XE_LOCK(scp); - xe_start_locked(ifp); - XE_UNLOCK(scp); -} - -static void -xe_start_locked(struct ifnet *ifp) -{ - struct xe_softc *scp = ifp->if_softc; - struct mbuf *mbp; - - if (scp->autoneg_status != XE_AUTONEG_NONE) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; - } - - DEVPRINTF(3, (scp->dev, "start\n")); - - /* - * Loop while there are packets to be sent, and space to send - * them. - */ - for (;;) { - /* Suck a packet off the send queue */ - IF_DEQUEUE(&ifp->if_snd, mbp); - - if (mbp == NULL) { - /* - * We are using the !OACTIVE flag to indicate - * to the outside world that we can accept an - * additional packet rather than that the - * transmitter is _actually_ active. Indeed, - * the transmitter may be active, but if we - * haven't filled all the buffers with data - * then we still want to accept more. - */ - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - return; - } - - if (xe_pio_write_packet(scp, mbp) != 0) { - /* Push the packet back onto the queue */ - IF_PREPEND(&ifp->if_snd, mbp); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; - } - - /* Tap off here if there is a bpf listener */ - BPF_MTAP(ifp, mbp); - - /* In case we don't hear from the card again... */ - scp->tx_timeout = 5; - scp->tx_queued++; - - m_freem(mbp); - } -} - -/* - * Process an ioctl request. Adapted from the ed driver. - */ -static int -xe_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct xe_softc *scp; - int error; - - scp = ifp->if_softc; - error = 0; - - switch (command) { - case SIOCSIFFLAGS: - DEVPRINTF(2, (scp->dev, "ioctl: SIOCSIFFLAGS: 0x%04x\n", - ifp->if_flags)); - /* - * If the interface is marked up and stopped, then - * start it. If it is marked down and running, then - * stop it. - */ - XE_LOCK(scp); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - xe_reset(scp); - xe_init_locked(scp); - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - xe_stop(scp); - } - - /* handle changes to PROMISC/ALLMULTI flags */ - xe_set_multicast(scp); - XE_UNLOCK(scp); - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - DEVPRINTF(2, (scp->dev, "ioctl: SIOC{ADD,DEL}MULTI\n")); - /* - * Multicast list has (maybe) changed; set the - * hardware filters accordingly. - */ - XE_LOCK(scp); - xe_set_multicast(scp); - XE_UNLOCK(scp); - error = 0; - break; - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - DEVPRINTF(3, (scp->dev, "ioctl: bounce to ifmedia_ioctl\n")); - /* - * Someone wants to get/set media options. - */ - error = ifmedia_ioctl(ifp, (struct ifreq *)data, &scp->ifmedia, - command); - break; - default: - DEVPRINTF(3, (scp->dev, "ioctl: bounce to ether_ioctl\n")); - error = ether_ioctl(ifp, command, data); - } - - return (error); -} - -/* - * Card interrupt handler. - * - * This function is probably more complicated than it needs to be, as it - * attempts to deal with the case where multiple packets get sent between - * interrupts. This is especially annoying when working out the collision - * stats. Not sure whether this case ever really happens or not (maybe on a - * slow/heavily loaded machine?) so it's probably best to leave this like it - * is. - * - * Note that the crappy PIO used to get packets on and off the card means that - * you will spend a lot of time in this routine -- I can get my P150 to spend - * 90% of its time servicing interrupts if I really hammer the network. Could - * fix this, but then you'd start dropping/losing packets. The moral of this - * story? If you want good network performance _and_ some cycles left over to - * get your work done, don't buy a Xircom card. Or convince them to tell me - * how to do memory-mapped I/O :) - */ -static void -xe_txintr(struct xe_softc *scp, uint8_t txst1) -{ - struct ifnet *ifp; - uint8_t tpr, sent, coll; - - ifp = scp->ifp; - - /* Update packet count, accounting for rollover */ - tpr = XE_INB(XE_TPR); - sent = -scp->tx_tpr + tpr; - - /* Update statistics if we actually sent anything */ - if (sent > 0) { - coll = txst1 & XE_TXST1_RETRY_COUNT; - scp->tx_tpr = tpr; - scp->tx_queued -= sent; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, sent); - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, coll); - - /* - * According to the Xircom manual, Dingo will - * sometimes manage to transmit a packet with - * triggering an interrupt. If this happens, we have - * sent > 1 and the collision count only reflects - * collisions on the last packet sent (the one that - * triggered the interrupt). Collision stats might - * therefore be a bit low, but there doesn't seem to - * be anything we can do about that. - */ - switch (coll) { - case 0: - break; - case 1: - scp->mibdata.dot3StatsSingleCollisionFrames++; - scp->mibdata.dot3StatsCollFrequencies[0]++; - break; - default: - scp->mibdata.dot3StatsMultipleCollisionFrames++; - scp->mibdata.dot3StatsCollFrequencies[coll-1]++; - } - } - scp->tx_timeout = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -} - -/* Handle most MAC interrupts */ -static void -xe_macintr(struct xe_softc *scp, uint8_t rst0, uint8_t txst0, uint8_t txst1) -{ - struct ifnet *ifp; - - ifp = scp->ifp; - -#if 0 - /* Carrier sense lost -- only in 10Mbit HDX mode */ - if (txst0 & XE_TXST0_NO_CARRIER || !(txst1 & XE_TXST1_LINK_STATUS)) { - /* XXX - Need to update media status here */ - device_printf(scp->dev, "no carrier\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - scp->mibdata.dot3StatsCarrierSenseErrors++; - } -#endif - /* Excessive collisions -- try sending again */ - if (txst0 & XE_TXST0_16_COLLISIONS) { - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 16); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - scp->mibdata.dot3StatsExcessiveCollisions++; - scp->mibdata.dot3StatsMultipleCollisionFrames++; - scp->mibdata.dot3StatsCollFrequencies[15]++; - XE_OUTB(XE_CR, XE_CR_RESTART_TX); - } - - /* Transmit underrun -- increase early transmit threshold */ - if (txst0 & XE_TXST0_TX_UNDERRUN && scp->mohawk) { - DEVPRINTF(1, (scp->dev, "transmit underrun")); - if (scp->tx_thres < ETHER_MAX_LEN) { - if ((scp->tx_thres += 64) > ETHER_MAX_LEN) - scp->tx_thres = ETHER_MAX_LEN; - DPRINTF(1, (": increasing transmit threshold to %u", - scp->tx_thres)); - XE_SELECT_PAGE(0x3); - XE_OUTW(XE_TPT, scp->tx_thres); - XE_SELECT_PAGE(0x0); - } - DPRINTF(1, ("\n")); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - scp->mibdata.dot3StatsInternalMacTransmitErrors++; - } - - /* Late collision -- just complain about it */ - if (txst0 & XE_TXST0_LATE_COLLISION) { - device_printf(scp->dev, "late collision\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - scp->mibdata.dot3StatsLateCollisions++; - } - - /* SQE test failure -- just complain about it */ - if (txst0 & XE_TXST0_SQE_FAIL) { - device_printf(scp->dev, "SQE test failure\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - scp->mibdata.dot3StatsSQETestErrors++; - } - - /* Packet too long -- what happens to these */ - if (rst0 & XE_RST0_LONG_PACKET) { - device_printf(scp->dev, "received giant packet\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - scp->mibdata.dot3StatsFrameTooLongs++; - } - - /* CRC error -- packet dropped */ - if (rst0 & XE_RST0_CRC_ERROR) { - device_printf(scp->dev, "CRC error\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - scp->mibdata.dot3StatsFCSErrors++; - } -} - -static void -xe_rxintr(struct xe_softc *scp, uint8_t rst0) -{ - struct ifnet *ifp; - uint8_t esr, rsr; - - ifp = scp->ifp; - - /* Handle received packet(s) */ - while ((esr = XE_INB(XE_ESR)) & XE_ESR_FULL_PACKET_RX) { - rsr = XE_INB(XE_RSR); - - DEVPRINTF(3, (scp->dev, "intr: ESR=0x%02x, RSR=0x%02x\n", esr, - rsr)); - - /* Make sure packet is a good one */ - if (rsr & XE_RSR_RX_OK) { - struct ether_header *ehp; - struct mbuf *mbp; - uint16_t len; - - len = XE_INW(XE_RBC) - ETHER_CRC_LEN; - - DEVPRINTF(3, (scp->dev, "intr: receive length = %d\n", - len)); - - if (len == 0) { - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - continue; - } - - /* - * Allocate mbuf to hold received packet. If - * the mbuf header isn't big enough, we attach - * an mbuf cluster to hold the packet. Note - * the +=2 to align the packet data on a - * 32-bit boundary, and the +3 to allow for - * the possibility of reading one more byte - * than the actual packet length (we always - * read 16-bit words). XXX - Surely there's a - * better way to do this alignment? - */ - MGETHDR(mbp, M_NOWAIT, MT_DATA); - if (mbp == NULL) { - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - continue; - } - - if (len + 3 > MHLEN) { - if (!(MCLGET(mbp, M_NOWAIT))) { - m_freem(mbp); - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - continue; - } - } - - mbp->m_data += 2; - ehp = mtod(mbp, struct ether_header *); - - /* - * Now get the packet in PIO mode, including - * the Ethernet header but omitting the - * trailing CRC. - */ - - /* - * Work around a bug in CE2 cards. There - * seems to be a problem with duplicated and - * extraneous bytes in the receive buffer, but - * without any real documentation for the CE2 - * it's hard to tell for sure. XXX - Needs - * testing on CE2 hardware - */ - if (scp->srev == 0) { - u_short rhs; - - XE_SELECT_PAGE(5); - rhs = XE_INW(XE_RHSA); - XE_SELECT_PAGE(0); - - rhs += 3; /* Skip control info */ - - if (rhs >= 0x8000) - rhs = 0; - - if (rhs + len > 0x8000) { - int i; - - for (i = 0; i < len; i++, rhs++) { - ((char *)ehp)[i] = - XE_INB(XE_EDP); - if (rhs == 0x8000) { - rhs = 0; - i--; - } - } - } else - bus_read_multi_2(scp->port_res, XE_EDP, - (uint16_t *)ehp, (len + 1) >> 1); - } else - bus_read_multi_2(scp->port_res, XE_EDP, - (uint16_t *)ehp, (len + 1) >> 1); - - /* Deliver packet to upper layers */ - mbp->m_pkthdr.rcvif = ifp; - mbp->m_pkthdr.len = mbp->m_len = len; - XE_UNLOCK(scp); - (*ifp->if_input)(ifp, mbp); - XE_LOCK(scp); - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - - } else if (rsr & XE_RSR_ALIGN_ERROR) { - /* Packet alignment error -- drop packet */ - device_printf(scp->dev, "alignment error\n"); - scp->mibdata.dot3StatsAlignmentErrors++; - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - - /* Skip to next packet, if there is one */ - XE_OUTW(XE_DO, 0x8000); - } - - /* Clear receiver overruns now we have some free buffer space */ - if (rst0 & XE_RST0_RX_OVERRUN) { - DEVPRINTF(1, (scp->dev, "receive overrun\n")); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - scp->mibdata.dot3StatsInternalMacReceiveErrors++; - XE_OUTB(XE_CR, XE_CR_CLEAR_OVERRUN); - } -} - -static void -xe_intr(void *xscp) -{ - struct xe_softc *scp = (struct xe_softc *) xscp; - struct ifnet *ifp; - uint8_t psr, isr, rst0, txst0, txst1; - - ifp = scp->ifp; - XE_LOCK(scp); - - /* Disable interrupts */ - if (scp->mohawk) - XE_OUTB(XE_CR, 0); - - /* Cache current register page */ - psr = XE_INB(XE_PR); - - /* Read ISR to see what caused this interrupt */ - while ((isr = XE_INB(XE_ISR)) != 0) { - - /* 0xff might mean the card is no longer around */ - if (isr == 0xff) { - DEVPRINTF(3, (scp->dev, - "intr: interrupt received for missing card?\n")); - break; - } - - /* Read other status registers */ - XE_SELECT_PAGE(0x40); - rst0 = XE_INB(XE_RST0); - XE_OUTB(XE_RST0, 0); - txst0 = XE_INB(XE_TXST0); - txst1 = XE_INB(XE_TXST1); - XE_OUTB(XE_TXST0, 0); - XE_OUTB(XE_TXST1, 0); - XE_SELECT_PAGE(0); - - DEVPRINTF(3, (scp->dev, - "intr: ISR=0x%02x, RST=0x%02x, TXT=0x%02x%02x\n", isr, - rst0, txst1, txst0)); - - if (isr & XE_ISR_TX_PACKET) - xe_txintr(scp, txst1); - - if (isr & XE_ISR_MAC_INTR) - xe_macintr(scp, rst0, txst0, txst1); - - xe_rxintr(scp, rst0); - } - - /* Restore saved page */ - XE_SELECT_PAGE(psr); - - /* Re-enable interrupts */ - XE_OUTB(XE_CR, XE_CR_ENABLE_INTR); - - XE_UNLOCK(scp); -} - -/* - * Device timeout/watchdog routine. Called automatically if we queue a packet - * for transmission but don't get an interrupt within a specified timeout - * (usually 5 seconds). When this happens we assume the worst and reset the - * card. - */ -static void -xe_watchdog(void *arg) -{ - struct xe_softc *scp = arg; - - XE_ASSERT_LOCKED(scp); - - if (scp->tx_timeout && --scp->tx_timeout == 0) { - device_printf(scp->dev, "watchdog timeout: resetting card\n"); - scp->tx_timeouts++; - if_inc_counter(scp->ifp, IFCOUNTER_OERRORS, scp->tx_queued); - xe_stop(scp); - xe_reset(scp); - xe_init_locked(scp); - } - callout_reset(&scp->wdog_timer, hz, xe_watchdog, scp); -} - -/* - * Change media selection. - */ -static int -xe_media_change(struct ifnet *ifp) -{ - struct xe_softc *scp = ifp->if_softc; - - DEVPRINTF(2, (scp->dev, "media_change\n")); - - XE_LOCK(scp); - if (IFM_TYPE(scp->ifm->ifm_media) != IFM_ETHER) { - XE_UNLOCK(scp); - return(EINVAL); - } - - /* - * Some card/media combos aren't always possible -- filter - * those out here. - */ - if ((IFM_SUBTYPE(scp->ifm->ifm_media) == IFM_AUTO || - IFM_SUBTYPE(scp->ifm->ifm_media) == IFM_100_TX) && !scp->phy_ok) { - XE_UNLOCK(scp); - return (EINVAL); - } - - xe_setmedia(scp); - XE_UNLOCK(scp); - - return (0); -} - -/* - * Return current media selection. - */ -static void -xe_media_status(struct ifnet *ifp, struct ifmediareq *mrp) -{ - struct xe_softc *scp = ifp->if_softc; - - DEVPRINTF(3, (scp->dev, "media_status\n")); - - /* XXX - This is clearly wrong. Will fix once I have CE2 working */ - XE_LOCK(scp); - mrp->ifm_status = IFM_AVALID | IFM_ACTIVE; - mrp->ifm_active = ((struct xe_softc *)ifp->if_softc)->media; - XE_UNLOCK(scp); -} - -/* - * Select active media. - */ -static void -xe_setmedia(void *xscp) -{ - struct xe_softc *scp = xscp; - uint16_t bmcr, bmsr, anar, lpar; - - DEVPRINTF(2, (scp->dev, "setmedia\n")); - - XE_ASSERT_LOCKED(scp); - - /* Cancel any pending timeout */ - callout_stop(&scp->media_timer); - xe_disable_intr(scp); - - /* Select media */ - scp->media = IFM_ETHER; - switch (IFM_SUBTYPE(scp->ifm->ifm_media)) { - - case IFM_AUTO: /* Autoselect media */ - scp->media = IFM_ETHER|IFM_AUTO; - - /* - * Autoselection is really awful. It goes something like this: - * - * Wait until the transmitter goes idle (2sec timeout). - * Reset card - * IF a 100Mbit PHY exists - * Start NWAY autonegotiation (3.5sec timeout) - * IF that succeeds - * Select 100baseTX or 10baseT, whichever was detected - * ELSE - * Reset card - * IF a 100Mbit PHY exists - * Try to force a 100baseTX link (3sec timeout) - * IF that succeeds - * Select 100baseTX - * ELSE - * Disable the PHY - * ENDIF - * ENDIF - * ENDIF - * ENDIF - * IF nothing selected so far - * IF a 100Mbit PHY exists - * Select 10baseT - * ELSE - * Select 10baseT or 10base2, whichever is connected - * ENDIF - * ENDIF - */ - switch (scp->autoneg_status) { - case XE_AUTONEG_NONE: - DEVPRINTF(2, (scp->dev, - "Waiting for idle transmitter\n")); - scp->ifp->if_drv_flags |= IFF_DRV_OACTIVE; - scp->autoneg_status = XE_AUTONEG_WAITING; - /* FALL THROUGH */ - case XE_AUTONEG_WAITING: - if (scp->tx_queued != 0) { - callout_reset(&scp->media_timer, hz / 2, - xe_setmedia, scp); - return; - } - if (scp->phy_ok) { - DEVPRINTF(2, (scp->dev, - "Starting autonegotiation\n")); - bmcr = xe_phy_readreg(scp, PHY_BMCR); - bmcr &= ~(PHY_BMCR_AUTONEGENBL); - xe_phy_writereg(scp, PHY_BMCR, bmcr); - anar = xe_phy_readreg(scp, PHY_ANAR); - anar &= ~(PHY_ANAR_100BT4 | - PHY_ANAR_100BTXFULL | PHY_ANAR_10BTFULL); - anar |= PHY_ANAR_100BTXHALF | PHY_ANAR_10BTHALF; - xe_phy_writereg(scp, PHY_ANAR, anar); - bmcr |= PHY_BMCR_AUTONEGENBL | - PHY_BMCR_AUTONEGRSTR; - xe_phy_writereg(scp, PHY_BMCR, bmcr); - scp->autoneg_status = XE_AUTONEG_STARTED; - callout_reset(&scp->media_timer, hz * 7/2, - xe_setmedia, scp); - return; - } else { - scp->autoneg_status = XE_AUTONEG_FAIL; - } - break; - case XE_AUTONEG_STARTED: - bmsr = xe_phy_readreg(scp, PHY_BMSR); - lpar = xe_phy_readreg(scp, PHY_LPAR); - if (bmsr & (PHY_BMSR_AUTONEGCOMP | PHY_BMSR_LINKSTAT)) { - DEVPRINTF(2, (scp->dev, - "Autonegotiation complete!\n")); - - /* - * XXX - Shouldn't have to do this, - * but (on my hub at least) the - * transmitter won't work after a - * successful autoneg. So we see what - * the negotiation result was and - * force that mode. I'm sure there is - * an easy fix for this. - */ - if (lpar & PHY_LPAR_100BTXHALF) { - xe_phy_writereg(scp, PHY_BMCR, - PHY_BMCR_SPEEDSEL); - XE_MII_DUMP(scp); - XE_SELECT_PAGE(2); - XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08); - scp->media = IFM_ETHER | IFM_100_TX; - scp->autoneg_status = XE_AUTONEG_NONE; - } else { - /* - * XXX - Bit of a hack going - * on in here. This is - * derived from Ken Hughes - * patch to the Linux driver - * to make it work with 10Mbit - * _autonegotiated_ links on - * CE3B cards. What's a CE3B - * and how's it differ from a - * plain CE3? these are the - * things we need to find out. - */ - xe_phy_writereg(scp, PHY_BMCR, 0x0000); - XE_SELECT_PAGE(2); - /* BEGIN HACK */ - XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08); - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, 0x80); - scp->media = IFM_ETHER | IFM_10_T; - scp->autoneg_status = XE_AUTONEG_NONE; - /* END HACK */ -#if 0 - /* Display PHY? */ - XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08); - scp->autoneg_status = XE_AUTONEG_FAIL; -#endif - } - } else { - DEVPRINTF(2, (scp->dev, - "Autonegotiation failed; trying 100baseTX\n")); - XE_MII_DUMP(scp); - if (scp->phy_ok) { - xe_phy_writereg(scp, PHY_BMCR, - PHY_BMCR_SPEEDSEL); - scp->autoneg_status = XE_AUTONEG_100TX; - callout_reset(&scp->media_timer, hz * 3, - xe_setmedia, scp); - return; - } else { - scp->autoneg_status = XE_AUTONEG_FAIL; - } - } - break; - case XE_AUTONEG_100TX: - (void)xe_phy_readreg(scp, PHY_BMSR); - bmsr = xe_phy_readreg(scp, PHY_BMSR); - if (bmsr & PHY_BMSR_LINKSTAT) { - DEVPRINTF(2, (scp->dev, - "Got 100baseTX link!\n")); - XE_MII_DUMP(scp); - XE_SELECT_PAGE(2); - XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08); - scp->media = IFM_ETHER | IFM_100_TX; - scp->autoneg_status = XE_AUTONEG_NONE; - } else { - DEVPRINTF(2, (scp->dev, - "Autonegotiation failed; disabling PHY\n")); - XE_MII_DUMP(scp); - xe_phy_writereg(scp, PHY_BMCR, 0x0000); - XE_SELECT_PAGE(2); - - /* Disable PHY? */ - XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08); - scp->autoneg_status = XE_AUTONEG_FAIL; - } - break; - } - - /* - * If we got down here _and_ autoneg_status is - * XE_AUTONEG_FAIL, then either autonegotiation - * failed, or never got started to begin with. In - * either case, select a suitable 10Mbit media and - * hope it works. We don't need to reset the card - * again, since it will have been done already by the - * big switch above. - */ - if (scp->autoneg_status == XE_AUTONEG_FAIL) { - DEVPRINTF(2, (scp->dev, "Selecting 10baseX\n")); - if (scp->mohawk) { - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, 0x80); - scp->media = IFM_ETHER | IFM_10_T; - scp->autoneg_status = XE_AUTONEG_NONE; - } else { - XE_SELECT_PAGE(4); - XE_OUTB(XE_GPR0, 4); - DELAY(50000); - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, - (XE_INB(XE_ESR) & XE_ESR_MEDIA_SELECT) ? - 0x80 : 0xc0); - scp->media = IFM_ETHER | ((XE_INB(XE_ESR) & - XE_ESR_MEDIA_SELECT) ? IFM_10_T : IFM_10_2); - scp->autoneg_status = XE_AUTONEG_NONE; - } - } - break; - - /* - * If a specific media has been requested, we just reset the - * card and select it (one small exception -- if 100baseTX is - * requested but there is no PHY, we fall back to 10baseT - * operation). - */ - case IFM_100_TX: /* Force 100baseTX */ - if (scp->phy_ok) { - DEVPRINTF(2, (scp->dev, "Selecting 100baseTX\n")); - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, 0); - xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_SPEEDSEL); - XE_SELECT_PAGE(2); - XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08); - scp->media |= IFM_100_TX; - break; - } - /* FALLTHROUGH */ - case IFM_10_T: /* Force 10baseT */ - DEVPRINTF(2, (scp->dev, "Selecting 10baseT\n")); - if (scp->phy_ok) { - xe_phy_writereg(scp, PHY_BMCR, 0x0000); - XE_SELECT_PAGE(2); - - /* Disable PHY */ - XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08); - } - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, 0x80); - scp->media |= IFM_10_T; - break; - case IFM_10_2: - DEVPRINTF(2, (scp->dev, "Selecting 10base2\n")); - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, 0xc0); - scp->media |= IFM_10_2; - break; - } - - /* - * Finally, the LEDs are set to match whatever media was - * chosen and the transmitter is unblocked. - */ - DEVPRINTF(2, (scp->dev, "Setting LEDs\n")); - XE_SELECT_PAGE(2); - switch (IFM_SUBTYPE(scp->media)) { - case IFM_100_TX: - case IFM_10_T: - XE_OUTB(XE_LED, 0x3b); - if (scp->dingo) - XE_OUTB(0x0b, 0x04); /* 100Mbit LED */ - break; - case IFM_10_2: - XE_OUTB(XE_LED, 0x3a); - break; - } - - /* Restart output? */ - xe_enable_intr(scp); - scp->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - xe_start_locked(scp->ifp); -} - -/* - * Hard reset (power cycle) the card. - */ -static void -xe_reset(struct xe_softc *scp) -{ - - DEVPRINTF(2, (scp->dev, "reset\n")); - - XE_ASSERT_LOCKED(scp); - - /* Power down */ - XE_SELECT_PAGE(4); - XE_OUTB(XE_GPR1, 0); - DELAY(40000); - - /* Power up again */ - if (scp->mohawk) - XE_OUTB(XE_GPR1, XE_GPR1_POWER_DOWN); - else - XE_OUTB(XE_GPR1, XE_GPR1_POWER_DOWN | XE_GPR1_AIC); - - DELAY(40000); - XE_SELECT_PAGE(0); -} - -/* - * Take interface offline. This is done by powering down the device, which I - * assume means just shutting down the transceiver and Ethernet logic. This - * requires a _hard_ reset to recover from, as we need to power up again. - */ -void -xe_stop(struct xe_softc *scp) -{ - - DEVPRINTF(2, (scp->dev, "stop\n")); - - XE_ASSERT_LOCKED(scp); - - /* - * Shut off interrupts. - */ - xe_disable_intr(scp); - - /* - * Power down. - */ - XE_SELECT_PAGE(4); - XE_OUTB(XE_GPR1, 0); - XE_SELECT_PAGE(0); - if (scp->mohawk) { - /* - * set GP1 and GP2 as outputs (bits 2 & 3) - * set GP1 high to power on the ML6692 (bit 0) - * set GP2 low to power on the 10Mhz chip (bit 1) - */ - XE_SELECT_PAGE(4); - XE_OUTB(XE_GPR0, XE_GPR0_GP2_SELECT | XE_GPR0_GP1_SELECT | - XE_GPR0_GP1_OUT); - } - - /* - * ~IFF_DRV_RUNNING == interface down. - */ - scp->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - scp->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - scp->tx_timeout = 0; - callout_stop(&scp->wdog_timer); - callout_stop(&scp->media_timer); -} - -/* - * Enable interrupts from the card. - */ -static void -xe_enable_intr(struct xe_softc *scp) -{ - - DEVPRINTF(2, (scp->dev, "enable_intr\n")); - - XE_SELECT_PAGE(0); - XE_OUTB(XE_CR, XE_CR_ENABLE_INTR); /* Enable interrupts */ - if (scp->modem && !scp->dingo) { /* This bit is just magic */ - if (!(XE_INB(0x10) & 0x01)) { - XE_OUTB(0x10, 0x11); /* Unmask master int enable */ - } - } -} - -/* - * Disable interrupts from the card. - */ -static void -xe_disable_intr(struct xe_softc *scp) -{ - - DEVPRINTF(2, (scp->dev, "disable_intr\n")); - - XE_SELECT_PAGE(0); - XE_OUTB(XE_CR, 0); /* Disable interrupts */ - if (scp->modem && !scp->dingo) { /* More magic */ - XE_OUTB(0x10, 0x10); /* Mask the master int enable */ - } -} - -/* - * Set up multicast filter and promiscuous modes. - */ -static void -xe_set_multicast(struct xe_softc *scp) -{ - struct ifnet *ifp; - struct ifmultiaddr *maddr; - unsigned count, i; - - DEVPRINTF(2, (scp->dev, "set_multicast\n")); - - ifp = scp->ifp; - XE_SELECT_PAGE(0x42); - - /* Handle PROMISC flag */ - if (ifp->if_flags & IFF_PROMISC) { - XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) | XE_SWC1_PROMISCUOUS); - return; - } else - XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) & ~XE_SWC1_PROMISCUOUS); - - /* Handle ALLMULTI flag */ - if (ifp->if_flags & IFF_ALLMULTI) { - XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) | XE_SWC1_ALLMULTI); - return; - } else - XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) & ~XE_SWC1_ALLMULTI); - - /* Iterate over multicast address list */ - count = 0; - if_maddr_rlock(ifp); - CK_STAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) { - if (maddr->ifma_addr->sa_family != AF_LINK) - continue; - - count++; - - if (count < 10) - /* - * First 9 use Individual Addresses for exact - * matching. - */ - xe_set_addr(scp, - LLADDR((struct sockaddr_dl *)maddr->ifma_addr), - count); - else if (scp->mohawk) - /* Use hash filter on Mohawk and Dingo */ - xe_mchash(scp, - LLADDR((struct sockaddr_dl *)maddr->ifma_addr)); - else - /* Nowhere else to put them on CE2 */ - break; - } - if_maddr_runlock(ifp); - - DEVPRINTF(2, (scp->dev, "set_multicast: count = %u\n", count)); - - /* Now do some cleanup and enable multicast handling as needed */ - if (count == 0) { - /* Disable all multicast handling */ - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) & - ~(XE_SWC1_IA_ENABLE | XE_SWC1_ALLMULTI)); - if (scp->mohawk) { - XE_SELECT_PAGE(0x02); - XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~XE_MSR_HASH_TABLE); - } - } else if (count < 10) { - /* - * Full in any unused Individual Addresses with our - * MAC address. - */ - for (i = count + 1; i < 10; i++) - xe_set_addr(scp, IF_LLADDR(scp->ifp), i); - - /* Enable Individual Address matching only */ - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & ~XE_SWC1_ALLMULTI) | - XE_SWC1_IA_ENABLE); - if (scp->mohawk) { - XE_SELECT_PAGE(0x02); - XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~XE_MSR_HASH_TABLE); - } - } else if (scp->mohawk) { - /* Check whether hash table is full */ - XE_SELECT_PAGE(0x58); - for (i = 0x08; i < 0x10; i++) - if (XE_INB(i) != 0xff) - break; - if (i == 0x10) { - /* - * Hash table full - enable - * promiscuous multicast matching - */ - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & - ~XE_SWC1_IA_ENABLE) | XE_SWC1_ALLMULTI); - XE_SELECT_PAGE(0x02); - XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~XE_MSR_HASH_TABLE); - } else { - /* Enable hash table and Individual Address matching */ - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & ~XE_SWC1_ALLMULTI) | - XE_SWC1_IA_ENABLE); - XE_SELECT_PAGE(0x02); - XE_OUTB(XE_MSR, XE_INB(XE_MSR) | XE_MSR_HASH_TABLE); - } - } else { - /* Enable promiscuous multicast matching */ - XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & ~XE_SWC1_IA_ENABLE) | - XE_SWC1_ALLMULTI); - } - - XE_SELECT_PAGE(0); -} - -/* - * Copy the Ethernet multicast address in addr to the on-chip registers for - * Individual Address idx. Assumes that addr is really a multicast address - * and that idx > 0 (slot 0 is always used for the card MAC address). - */ -static void -xe_set_addr(struct xe_softc *scp, uint8_t* addr, unsigned idx) -{ - uint8_t page, reg; - unsigned i; - - /* - * Individual Addresses are stored in registers 8-F of pages - * 0x50-0x57. IA1 therefore starts at register 0xE on page - * 0x50. The expressions below compute the starting page and - * register for any IA index > 0. - */ - --idx; - page = 0x50 + idx % 4 + idx / 4 * 3; - reg = 0x0e - 2 * (idx % 4); - - DEVPRINTF(3, (scp->dev, - "set_addr: idx = %u, page = 0x%02x, reg = 0x%02x\n", idx + 1, page, - reg)); - - /* - * Copy the IA bytes. Note that the byte order is reversed - * for Mohawk and Dingo wrt. CE2 hardware. - */ - XE_SELECT_PAGE(page); - for (i = 0; i < ETHER_ADDR_LEN; i++) { - if (i > 0) { - DPRINTF(3, (":%02x", addr[i])); - } else { - DEVPRINTF(3, (scp->dev, "set_addr: %02x", addr[0])); - } - XE_OUTB(reg, addr[scp->mohawk ? 5 - i : i]); - if (++reg == 0x10) { - reg = 0x08; - XE_SELECT_PAGE(++page); - } - } - DPRINTF(3, ("\n")); -} - -/* - * Set the appropriate bit in the multicast hash table for the supplied - * Ethernet multicast address addr. Assumes that addr is really a multicast - * address. - */ -static void -xe_mchash(struct xe_softc* scp, const uint8_t *addr) -{ - int bit; - uint8_t byte, hash; - - hash = ether_crc32_le(addr, ETHER_ADDR_LEN) & 0x3F; - - /* - * Top 3 bits of hash give register - 8, bottom 3 give bit - * within register. - */ - byte = hash >> 3 | 0x08; - bit = 0x01 << (hash & 0x07); - - DEVPRINTF(3, (scp->dev, - "set_hash: hash = 0x%02x, byte = 0x%02x, bit = 0x%02x\n", hash, - byte, bit)); - - XE_SELECT_PAGE(0x58); - XE_OUTB(byte, XE_INB(byte) | bit); -} - -/* - * Write an outgoing packet to the card using programmed I/O. - */ -static int -xe_pio_write_packet(struct xe_softc *scp, struct mbuf *mbp) -{ - unsigned len, pad; - unsigned char wantbyte; - uint8_t *data; - uint8_t savebyte[2]; - - /* Get total packet length */ - if (mbp->m_flags & M_PKTHDR) - len = mbp->m_pkthdr.len; - else { - struct mbuf* mbp2 = mbp; - for (len = 0; mbp2 != NULL; - len += mbp2->m_len, mbp2 = mbp2->m_next); - } - - DEVPRINTF(3, (scp->dev, "pio_write_packet: len = %u\n", len)); - - /* Packets < minimum length may need to be padded out */ - pad = 0; - if (len < scp->tx_min) { - pad = scp->tx_min - len; - len = scp->tx_min; - } - - /* Check transmit buffer space */ - XE_SELECT_PAGE(0); - XE_OUTW(XE_TRS, len + 2); /* Only effective on rev. 1 CE2 cards */ - if ((XE_INW(XE_TSO) & 0x7fff) <= len + 2) - return (1); - - /* Send packet length to card */ - XE_OUTW(XE_EDP, len); - - /* - * Write packet to card using PIO (code stolen from the ed driver) - */ - wantbyte = 0; - while (mbp != NULL) { - len = mbp->m_len; - if (len > 0) { - data = mtod(mbp, caddr_t); - if (wantbyte) { /* Finish the last word */ - savebyte[1] = *data; - XE_OUTW(XE_EDP, *(u_short *)savebyte); - data++; - len--; - wantbyte = 0; - } - if (len > 1) { /* Output contiguous words */ - bus_write_multi_2(scp->port_res, XE_EDP, - (uint16_t *)data, len >> 1); - data += len & ~1; - len &= 1; - } - if (len == 1) { /* Save last byte, if needed */ - savebyte[0] = *data; - wantbyte = 1; - } - } - mbp = mbp->m_next; - } - - /* - * Send last byte of odd-length packets - */ - if (wantbyte) - XE_OUTB(XE_EDP, savebyte[0]); - - /* - * Can just tell CE3 cards to send; short packets will be - * padded out with random cruft automatically. For CE2, - * manually pad the packet with garbage; it will be sent when - * the required number of bytes have been delivered to the - * card. - */ - if (scp->mohawk) - XE_OUTB(XE_CR, XE_CR_TX_PACKET | XE_CR_RESTART_TX | - XE_CR_ENABLE_INTR); - else if (pad > 0) { - if (pad & 0x01) - XE_OUTB(XE_EDP, 0xaa); - pad >>= 1; - while (pad > 0) { - XE_OUTW(XE_EDP, 0xdead); - pad--; - } - } - - return (0); -} - -/************************************************************** - * * - * M I I F U N C T I O N S * - * * - **************************************************************/ - -/* - * Alternative MII/PHY handling code adapted from the xl driver. It doesn't - * seem to work any better than the xirc2_ps stuff, but it's cleaner code. - * XXX - this stuff shouldn't be here. It should all be abstracted off to - * XXX - some kind of common MII-handling code, shared by all drivers. But - * XXX - that's a whole other mission. - */ -#define XE_MII_SET(x) XE_OUTB(XE_GPR2, (XE_INB(XE_GPR2) | 0x04) | (x)) -#define XE_MII_CLR(x) XE_OUTB(XE_GPR2, (XE_INB(XE_GPR2) | 0x04) & ~(x)) - -/* - * Sync the PHYs by setting data bit and strobing the clock 32 times. - */ -static void -xe_mii_sync(struct xe_softc *scp) -{ - int i; - - XE_SELECT_PAGE(2); - XE_MII_SET(XE_MII_DIR|XE_MII_WRD); - - for (i = 0; i < 32; i++) { - XE_MII_SET(XE_MII_CLK); - DELAY(1); - XE_MII_CLR(XE_MII_CLK); - DELAY(1); - } -} - -/* - * Look for a MII-compliant PHY. If we find one, reset it. - */ -static int -xe_mii_init(struct xe_softc *scp) -{ - uint16_t status; - - status = xe_phy_readreg(scp, PHY_BMSR); - if ((status & 0xff00) != 0x7800) { - DEVPRINTF(2, (scp->dev, "no PHY found, %0x\n", status)); - return (0); - } else { - DEVPRINTF(2, (scp->dev, "PHY OK!\n")); - - /* Reset the PHY */ - xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_RESET); - DELAY(500); - while(xe_phy_readreg(scp, PHY_BMCR) & PHY_BMCR_RESET) - ; /* nothing */ - XE_MII_DUMP(scp); - return (1); - } -} - -/* - * Clock a series of bits through the MII. - */ -static void -xe_mii_send(struct xe_softc *scp, uint32_t bits, int cnt) -{ - int i; - - XE_SELECT_PAGE(2); - XE_MII_CLR(XE_MII_CLK); - - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { - XE_MII_SET(XE_MII_WRD); - } else { - XE_MII_CLR(XE_MII_WRD); - } - DELAY(1); - XE_MII_CLR(XE_MII_CLK); - DELAY(1); - XE_MII_SET(XE_MII_CLK); - } -} - -/* - * Read an PHY register through the MII. - */ -static int -xe_mii_readreg(struct xe_softc *scp, struct xe_mii_frame *frame) -{ - int i, ack; - - XE_ASSERT_LOCKED(scp); - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = XE_MII_STARTDELIM; - frame->mii_opcode = XE_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - XE_SELECT_PAGE(2); - XE_OUTB(XE_GPR2, 0); - - /* - * Turn on data xmit. - */ - XE_MII_SET(XE_MII_DIR); - - xe_mii_sync(scp); - - /* - * Send command/address info. - */ - xe_mii_send(scp, frame->mii_stdelim, 2); - xe_mii_send(scp, frame->mii_opcode, 2); - xe_mii_send(scp, frame->mii_phyaddr, 5); - xe_mii_send(scp, frame->mii_regaddr, 5); - - /* Idle bit */ - XE_MII_CLR((XE_MII_CLK|XE_MII_WRD)); - DELAY(1); - XE_MII_SET(XE_MII_CLK); - DELAY(1); - - /* Turn off xmit. */ - XE_MII_CLR(XE_MII_DIR); - - /* Check for ack */ - XE_MII_CLR(XE_MII_CLK); - DELAY(1); - ack = XE_INB(XE_GPR2) & XE_MII_RDD; - XE_MII_SET(XE_MII_CLK); - DELAY(1); - - /* - * Now try reading data bits. If the ack failed, we still - * need to clock through 16 cycles to keep the PHY(s) in sync. - */ - if (ack) { - for(i = 0; i < 16; i++) { - XE_MII_CLR(XE_MII_CLK); - DELAY(1); - XE_MII_SET(XE_MII_CLK); - DELAY(1); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - XE_MII_CLR(XE_MII_CLK); - DELAY(1); - if (!ack) { - if (XE_INB(XE_GPR2) & XE_MII_RDD) - frame->mii_data |= i; - DELAY(1); - } - XE_MII_SET(XE_MII_CLK); - DELAY(1); - } - -fail: - XE_MII_CLR(XE_MII_CLK); - DELAY(1); - XE_MII_SET(XE_MII_CLK); - DELAY(1); - - if (ack) - return(1); - return(0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -xe_mii_writereg(struct xe_softc *scp, struct xe_mii_frame *frame) -{ - - XE_ASSERT_LOCKED(scp); - - /* - * Set up frame for TX. - */ - frame->mii_stdelim = XE_MII_STARTDELIM; - frame->mii_opcode = XE_MII_WRITEOP; - frame->mii_turnaround = XE_MII_TURNAROUND; - - XE_SELECT_PAGE(2); - - /* - * Turn on data output. - */ - XE_MII_SET(XE_MII_DIR); - - xe_mii_sync(scp); - - xe_mii_send(scp, frame->mii_stdelim, 2); - xe_mii_send(scp, frame->mii_opcode, 2); - xe_mii_send(scp, frame->mii_phyaddr, 5); - xe_mii_send(scp, frame->mii_regaddr, 5); - xe_mii_send(scp, frame->mii_turnaround, 2); - xe_mii_send(scp, frame->mii_data, 16); - - /* Idle bit. */ - XE_MII_SET(XE_MII_CLK); - DELAY(1); - XE_MII_CLR(XE_MII_CLK); - DELAY(1); - - /* - * Turn off xmit. - */ - XE_MII_CLR(XE_MII_DIR); - - return(0); -} - -/* - * Read a register from the PHY. - */ -static uint16_t -xe_phy_readreg(struct xe_softc *scp, uint16_t reg) -{ - struct xe_mii_frame frame; - - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = 0; - frame.mii_regaddr = reg; - xe_mii_readreg(scp, &frame); - - return (frame.mii_data); -} - -/* - * Write to a PHY register. - */ -static void -xe_phy_writereg(struct xe_softc *scp, uint16_t reg, uint16_t data) -{ - struct xe_mii_frame frame; - - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = 0; - frame.mii_regaddr = reg; - frame.mii_data = data; - xe_mii_writereg(scp, &frame); -} - -/* - * A bit of debugging code. - */ -static void -xe_mii_dump(struct xe_softc *scp) -{ - int i; - - device_printf(scp->dev, "MII registers: "); - for (i = 0; i < 2; i++) { - printf(" %d:%04x", i, xe_phy_readreg(scp, i)); - } - for (i = 4; i < 7; i++) { - printf(" %d:%04x", i, xe_phy_readreg(scp, i)); - } - printf("\n"); -} - -#if 0 -void -xe_reg_dump(struct xe_softc *scp) -{ - int page, i; - - device_printf(scp->dev, "Common registers: "); - for (i = 0; i < 8; i++) { - printf(" %2.2x", XE_INB(i)); - } - printf("\n"); - - for (page = 0; page <= 8; page++) { - device_printf(scp->dev, "Register page %2.2x: ", page); - XE_SELECT_PAGE(page); - for (i = 8; i < 16; i++) { - printf(" %2.2x", XE_INB(i)); - } - printf("\n"); - } - - for (page = 0x10; page < 0x5f; page++) { - if ((page >= 0x11 && page <= 0x3f) || - (page == 0x41) || - (page >= 0x43 && page <= 0x4f) || - (page >= 0x59)) - continue; - device_printf(scp->dev, "Register page %2.2x: ", page); - XE_SELECT_PAGE(page); - for (i = 8; i < 16; i++) { - printf(" %2.2x", XE_INB(i)); - } - printf("\n"); - } -} -#endif - -int -xe_activate(device_t dev) -{ - struct xe_softc *sc = device_get_softc(dev); - int start, i; - - DEVPRINTF(2, (dev, "activate\n")); - - if (!sc->modem) { - sc->port_rid = 0; /* 0 is managed by pccard */ - sc->port_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, - &sc->port_rid, 16, RF_ACTIVE); - } else if (sc->dingo) { - /* - * Find a 16 byte aligned ioport for the card. - */ - DEVPRINTF(1, (dev, "Finding an aligned port for RealPort\n")); - sc->port_rid = 1; /* 0 is managed by pccard */ - start = 0x100; - do { - sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->port_rid, start, 0x3ff, 16, RF_ACTIVE); - if (sc->port_res == NULL) - break; - if ((rman_get_start(sc->port_res) & 0xf) == 0) - break; - bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, - sc->port_res); - start = (rman_get_start(sc->port_res) + 15) & ~0xf; - } while (1); - DEVPRINTF(1, (dev, "RealPort port 0x%0jx, size 0x%0jx\n", - bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid), - bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid))); - } else if (sc->ce2) { - /* - * Find contiguous I/O port for the Ethernet function - * on CEM2 and CEM3 cards. We allocate window 0 - * wherever pccard has decided it should be, then find - * an available window adjacent to it for the second - * function. Not sure that both windows are actually - * needed. - */ - DEVPRINTF(1, (dev, "Finding I/O port for CEM2/CEM3\n")); - sc->ce2_port_rid = 0; /* 0 is managed by pccard */ - sc->ce2_port_res = bus_alloc_resource_anywhere(dev, - SYS_RES_IOPORT, &sc->ce2_port_rid, 8, RF_ACTIVE); - if (sc->ce2_port_res == NULL) { - DEVPRINTF(1, (dev, - "Cannot allocate I/O port for modem\n")); - xe_deactivate(dev); - return (ENOMEM); - } - - sc->port_rid = 1; - start = bus_get_resource_start(dev, SYS_RES_IOPORT, - sc->ce2_port_rid); - for (i = 0; i < 2; i++) { - start += (i == 0 ? 8 : -24); - sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->port_rid, start, start + 15, 16, RF_ACTIVE); - if (sc->port_res == NULL) - continue; - if (bus_get_resource_start(dev, SYS_RES_IOPORT, - sc->port_rid) == start) - break; - - bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, - sc->port_res); - sc->port_res = NULL; - } - DEVPRINTF(1, (dev, "CEM2/CEM3 port 0x%0jx, size 0x%0jx\n", - bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid), - bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid))); - } - - if (!sc->port_res) { - DEVPRINTF(1, (dev, "Cannot allocate ioport\n")); - xe_deactivate(dev); - return (ENOMEM); - } - - sc->irq_rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, - RF_ACTIVE); - if (sc->irq_res == NULL) { - DEVPRINTF(1, (dev, "Cannot allocate irq\n")); - xe_deactivate(dev); - return (ENOMEM); - } - - return (0); -} - -void -xe_deactivate(device_t dev) -{ - struct xe_softc *sc = device_get_softc(dev); - - DEVPRINTF(2, (dev, "deactivate\n")); - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = NULL; - if (sc->port_res) - bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, - sc->port_res); - sc->port_res = NULL; - if (sc->ce2_port_res) - bus_release_resource(dev, SYS_RES_IOPORT, sc->ce2_port_rid, - sc->ce2_port_res); - sc->ce2_port_res = NULL; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, - sc->irq_res); - sc->irq_res = NULL; - if (sc->ifp) - if_free(sc->ifp); - sc->ifp = NULL; -} diff --git a/sys/dev/xe/if_xe_pccard.c b/sys/dev/xe/if_xe_pccard.c deleted file mode 100644 index ba6277d209c9..000000000000 --- a/sys/dev/xe/if_xe_pccard.c +++ /dev/null @@ -1,391 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2002 Takeshi Shibagaki - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* xe pccard interface driver */ - -#include <sys/param.h> -#include <sys/bus.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/module.h> -#include <sys/mutex.h> -#include <sys/socket.h> -#include <sys/systm.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/ethernet.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <net/if_media.h> -#include <net/if_mib.h> - -#include <dev/xe/if_xereg.h> -#include <dev/xe/if_xevar.h> - -#include <dev/pccard/pccardvar.h> -#include <dev/pccard/pccard_cis.h> - -#include "card_if.h" -#include "pccarddevs.h" - -/* - * Debug logging levels - set with hw.xe.debug sysctl - * 0 = None - * 1 = More hardware details, probe/attach progress - * 2 = Most function calls, ioctls and media selection progress - * 3 = Everything - interrupts, packets in/out and multicast address setup - */ -#define XE_DEBUG -#ifdef XE_DEBUG - -extern int xe_debug; - -#define DEVPRINTF(level, arg) if (xe_debug >= (level)) device_printf arg -#define DPRINTF(level, arg) if (xe_debug >= (level)) printf arg -#else -#define DEVPRINTF(level, arg) -#define DPRINTF(level, arg) -#endif - - -#define XE_CARD_TYPE_FLAGS_NO 0x0 -#define XE_CARD_TYPE_FLAGS_CE2 0x1 -#define XE_CARD_TYPE_FLAGS_MOHAWK 0x2 -#define XE_CARD_TYPE_FLAGS_DINGO 0x4 -#define XE_PROD_ETHER_MASK 0x0100 -#define XE_PROD_MODEM_MASK 0x1000 - -#define XE_BOGUS_MAC_OFFSET 0x90 - -/* MAC vendor prefix used by most Xircom cards is 00:80:c7 */ -#define XE_MAC_ADDR_0 0x00 -#define XE_MAC_ADDR_1 0x80 -#define XE_MAC_ADDR_2 0xc7 - -/* Some (all?) REM56 cards have vendor prefix 00:10:a4 */ -#define XE_REM56_MAC_ADDR_0 0x00 -#define XE_REM56_MAC_ADDR_1 0x10 -#define XE_REM56_MAC_ADDR_2 0xa4 - -struct xe_pccard_product { - struct pccard_product product; - uint16_t prodext; - uint16_t flags; -}; - -static const struct xe_pccard_product xe_pccard_products[] = { - { PCMCIA_CARD_D(COMPAQ, CPQ550), 0x43, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(COMPAQ2, CPQ_10_100), 0x43, XE_CARD_TYPE_FLAGS_MOHAWK }, - { PCMCIA_CARD_D(INTEL, EEPRO100), 0x43, XE_CARD_TYPE_FLAGS_MOHAWK }, - { PCMCIA_CARD_D(INTEL, PRO100LAN56), 0x46, XE_CARD_TYPE_FLAGS_DINGO }, - { PCMCIA_CARD_D(RACORE, ACCTON_EN2226),0x43, XE_CARD_TYPE_FLAGS_MOHAWK }, - { PCMCIA_CARD_D(XIRCOM, CE), 0x41, XE_CARD_TYPE_FLAGS_NO }, - { PCMCIA_CARD_D(XIRCOM, CE2), 0x41, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CE2), 0x42, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CE2_2), 0x41, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CE2_2), 0x42, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CE3), 0x43, XE_CARD_TYPE_FLAGS_MOHAWK }, - { PCMCIA_CARD_D(XIRCOM, CEM), 0x41, XE_CARD_TYPE_FLAGS_NO }, - { PCMCIA_CARD_D(XIRCOM, CEM2), 0x42, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CEM28), 0x43, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CEM33), 0x44, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CEM33_2), 0x44, XE_CARD_TYPE_FLAGS_CE2 }, - { PCMCIA_CARD_D(XIRCOM, CEM56), 0x45, XE_CARD_TYPE_FLAGS_DINGO }, - { PCMCIA_CARD_D(XIRCOM, CEM56_2), 0x46, XE_CARD_TYPE_FLAGS_DINGO }, - { PCMCIA_CARD_D(XIRCOM, REM56), 0x46, XE_CARD_TYPE_FLAGS_DINGO }, - { PCMCIA_CARD_D(XIRCOM, REM10), 0x47, XE_CARD_TYPE_FLAGS_DINGO }, - { PCMCIA_CARD_D(XIRCOM, XEM5600), 0x56, XE_CARD_TYPE_FLAGS_DINGO }, - { { NULL }, 0, 0 } -}; - -/* - * Fixing for CEM2, CEM3 and CEM56/REM56 cards. These need some magic to - * enable the Ethernet function, which isn't mentioned anywhere in the CIS. - * Despite the register names, most of this isn't Dingo-specific. - */ -static int -xe_cemfix(device_t dev) -{ - struct xe_softc *sc = device_get_softc(dev); - int ioport; - - DEVPRINTF(2, (dev, "cemfix\n")); - - DEVPRINTF(1, (dev, "CEM I/O port 0x%0jx, size 0x%0jx\n", - bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid), - bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid))); - - pccard_attr_write_1(dev, DINGO_ECOR, DINGO_ECOR_IRQ_LEVEL | - DINGO_ECOR_INT_ENABLE | DINGO_ECOR_IOB_ENABLE | - DINGO_ECOR_ETH_ENABLE); - ioport = bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid); - pccard_attr_write_1(dev, DINGO_EBAR0, ioport & 0xff); - pccard_attr_write_1(dev, DINGO_EBAR1, (ioport >> 8) & 0xff); - - if (sc->dingo) { - pccard_attr_write_1(dev, DINGO_DCOR0, DINGO_DCOR0_SF_INT); - pccard_attr_write_1(dev, DINGO_DCOR1, DINGO_DCOR1_INT_LEVEL | - DINGO_DCOR1_EEDIO); - pccard_attr_write_1(dev, DINGO_DCOR2, 0x00); - pccard_attr_write_1(dev, DINGO_DCOR3, 0x00); - pccard_attr_write_1(dev, DINGO_DCOR4, 0x00); - } - /* success! */ - return (0); -} - -static int -xe_pccard_product_match(device_t dev, const struct pccard_product* ent, - int vpfmatch) -{ - const struct xe_pccard_product* xpp; - uint16_t prodext; - - if (vpfmatch == 0) - return (0); - - xpp = (const struct xe_pccard_product*)ent; - pccard_get_prodext(dev, &prodext); - if (xpp->prodext != prodext) - vpfmatch = 0; - else - vpfmatch++; - return (vpfmatch); -} - -static const struct xe_pccard_product * -xe_pccard_get_product(device_t dev) -{ - return ((const struct xe_pccard_product *)pccard_product_lookup(dev, - (const struct pccard_product *)xe_pccard_products, - sizeof(xe_pccard_products[0]), xe_pccard_product_match)); -} - -/* - * Fixing for CE2-class cards with bogus CIS entry for MAC address. - */ -static int -xe_pccard_mac(const struct pccard_tuple *tuple, void *argp) -{ - uint8_t *enaddr = argp, test; - int i; - - /* Code 0x89 is Xircom special cis node contianing the MAC */ - if (tuple->code != 0x89) - return (0); - - /* Make sure this is a sane node */ - if (tuple->length != ETHER_ADDR_LEN + 2) - return (0); - test = pccard_tuple_read_1(tuple, 0); - if (test != PCCARD_TPLFE_TYPE_LAN_NID) - return (0); - test = pccard_tuple_read_1(tuple, 1); - if (test != ETHER_ADDR_LEN) - return (0); - - /* Copy the MAC ADDR and return success */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - enaddr[i] = pccard_tuple_read_1(tuple, i + 2); - return (1); -} - -static int -xe_bad_mac(uint8_t *enaddr) -{ - int i; - uint8_t sum; - - for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) - sum |= enaddr[i]; - return (sum == 0); -} - -/* - * PCMCIA attach routine. - * Identify the device. Called from the bus driver when the card is - * inserted or otherwise powers up. - */ -static int -xe_pccard_attach(device_t dev) -{ - struct xe_softc *scp = device_get_softc(dev); - uint32_t vendor,product; - uint16_t prodext; - const char* vendor_str = NULL; - const char* product_str = NULL; - const char* cis4_str = NULL; - const char *cis3_str=NULL; - const struct xe_pccard_product *xpp; - int err; - - DEVPRINTF(2, (dev, "pccard_attach\n")); - - pccard_get_vendor(dev, &vendor); - pccard_get_product(dev, &product); - pccard_get_prodext(dev, &prodext); - pccard_get_vendor_str(dev, &vendor_str); - pccard_get_product_str(dev, &product_str); - pccard_get_cis3_str(dev, &cis3_str); - pccard_get_cis4_str(dev, &cis4_str); - - DEVPRINTF(1, (dev, "vendor = 0x%04x\n", vendor)); - DEVPRINTF(1, (dev, "product = 0x%04x\n", product)); - DEVPRINTF(1, (dev, "prodext = 0x%02x\n", prodext)); - DEVPRINTF(1, (dev, "vendor_str = %s\n", vendor_str)); - DEVPRINTF(1, (dev, "product_str = %s\n", product_str)); - DEVPRINTF(1, (dev, "cis3_str = %s\n", cis3_str)); - DEVPRINTF(1, (dev, "cis4_str = %s\n", cis4_str)); - - xpp = xe_pccard_get_product(dev); - if (xpp == NULL) - return (ENXIO); - - /* Set various card ID fields in softc */ - scp->vendor = vendor_str; - scp->card_type = product_str; - if (xpp->flags & XE_CARD_TYPE_FLAGS_CE2) - scp->ce2 = 1; - if (xpp->flags & XE_CARD_TYPE_FLAGS_MOHAWK) - scp->mohawk = 1; - if (xpp->flags & XE_CARD_TYPE_FLAGS_DINGO) { - scp->dingo = 1; - scp->mohawk = 1; - } - if (xpp->product.pp_product & XE_PROD_MODEM_MASK) - scp->modem = 1; - - /* Get MAC address */ - pccard_get_ether(dev, scp->enaddr); - - /* Deal with bogus MAC address */ - if (xe_bad_mac(scp->enaddr) && - !pccard_cis_scan(dev, xe_pccard_mac, scp->enaddr)) { - device_printf(dev, - "Unable to find MAC address for your %s card\n", - device_get_desc(dev)); - return (ENXIO); - } - - if ((err = xe_activate(dev)) != 0) - return (err); - - /* Hack RealPorts into submission */ - if (scp->modem && xe_cemfix(dev) < 0) { - device_printf(dev, "Unable to fix your %s combo card\n", - device_get_desc(dev)); - xe_deactivate(dev); - return (ENXIO); - } - if ((err = xe_attach(dev))) { - device_printf(dev, "xe_attach() failed! (%d)\n", err); - xe_deactivate(dev); - return (err); - } - return (0); -} - -/* - * The device entry is being removed, probably because someone ejected the - * card. The interface should have been brought down manually before calling - * this function; if not you may well lose packets. In any case, I shut down - * the card and the interface, and hope for the best. - */ -static int -xe_pccard_detach(device_t dev) -{ - struct xe_softc *sc = device_get_softc(dev); - - DEVPRINTF(2, (dev, "pccard_detach\n")); - - XE_LOCK(sc); - xe_stop(sc); - XE_UNLOCK(sc); - callout_drain(&sc->media_timer); - callout_drain(&sc->wdog_timer); - ether_ifdetach(sc->ifp); - xe_deactivate(dev); - mtx_destroy(&sc->lock); - return (0); -} - -static int -xe_pccard_probe(device_t dev) -{ - const struct xe_pccard_product *xpp; - - DEVPRINTF(2, (dev, "pccard_probe\n")); - - /* - * Xircom cards aren't proper MFC cards, so we have to take all - * cards that match, not just ones that are network. - */ - - /* If we match something in the table, it is our device. */ - if ((xpp = xe_pccard_get_product(dev)) == NULL) - return (ENXIO); - - /* Set card name for logging later */ - if (xpp->product.pp_name != NULL) - device_set_desc(dev, xpp->product.pp_name); - - /* Reject known but unsupported cards */ - if (xpp->flags & XE_CARD_TYPE_FLAGS_NO) { - device_printf(dev, "Sorry, your %s card is not supported :(\n", - device_get_desc(dev)); - return (ENXIO); - } - - return (0); -} - -static device_method_t xe_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, xe_pccard_probe), - DEVMETHOD(device_attach, xe_pccard_attach), - DEVMETHOD(device_detach, xe_pccard_detach), - - { 0, 0 } -}; - -static driver_t xe_pccard_driver = { - "xe", - xe_pccard_methods, - sizeof(struct xe_softc), -}; - -devclass_t xe_devclass; - -DRIVER_MODULE(xe, pccard, xe_pccard_driver, xe_devclass, 0, 0); -PCCARD_PNP_INFO(xe_pccard_products); diff --git a/sys/dev/xe/if_xereg.h b/sys/dev/xe/if_xereg.h deleted file mode 100644 index 820d10603efb..000000000000 --- a/sys/dev/xe/if_xereg.h +++ /dev/null @@ -1,702 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998, 1999 Scott Mitchell - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: if_xereg.h,v 1.5 1999/05/20 21:53:58 scott Exp $ - * $FreeBSD$ - */ -#ifndef DEV_XE_IF_XEREG_H -#define DEV_XE_IF_XEREG_H - -/* - * Register definitions for Xircom PCMCIA Ethernet controllers, based on - * Rev. B of the "Dingo" 10/100 controller used in Xircom CEM56 and RealPort - * Ethernet/modem cards. The Dingo can be configured to be register - * compatible with the "Mohawk" 10/100 controller used in Xircom CE3 cards - * (also some Intel and Compaq OEM versions of the CE3). The older 10Mbps CE2 - * cards seem to use earlier revisions of the same device. Some registers and - * bits below are marked 'CE2 only'; these are used by Werner Koch's xirc2ps - * driver that was originally for the CE2 but, according to the spec, aren't - * present on the Dingo. They often seem to relate to operation on coax - * cables, which Mohawk can do in theory (it has the SSI interface) so they - * _might_ also work on Mohawk. I've also noted the few registers that are - * specific to Dingo. - * - * As far as I can tell, the Dingo is basically a Mohawk device with a few - * registers and support for a second PCMCIA function (the modem) added. In - * Dingo mode the SSI (non-MII) PHY interface of the Mohawk is not available. - * The CE2 chip is most likely a Mohawk without the MII and definitely with a - * slightly different register set. - * - * In all cases, the controller uses a paged model of register access. The - * first eight registers are always the same, the function of the second eight - * is selected by the value in the Page Register (reg 0x01). - * - * References: - * 1. Dingo External Reference Specification, Revision B. Xircom Inc., - * Thousand Oaks, California. August 1998. Available under licence from - * Xircom, http://www.xircom.com/ - * 2. ML6692 100BASE-TX Physical Layer with MII specification. MicroLinear - * Corp, San Jose, California. May 1997. Available for download from - * http://www.microlinear.com/ - * 3. DP83840 10/100 Mb/s Ethernet Physical Layer specification. National - * Semiconductor Corp., Arlington, Texas. March 1997. Available for - * download from http://www.ns.com/ - * 4. Werner Koch's xirc2ps driver for Linux, for all the CE2 and CE3 frobs - * that aren't documented in the Xircom spec. Available for download from - * http://www.d.shuttle.de/isil/xircom/xirc2ps.html - */ - -/******************* - * PCMCIA registers - *******************/ - -/* - * These are probably Dingo-specific, but you won't need them unless you have - * a CEM card that needs a bit of hackery to get the Ethernet function to - * operate. All addresses are in card attribute space. - */ -#define DINGO_CIS 0x0000 /* Start of CIS tuples */ -#define DINGO_ETH 0x0800 /* Ethernet configuration registers */ -#define DINGO_COR 0x0820 /* Dingo configuration option registers */ -#define DINGO_2ND 0x0840 /* 2nd function configuration registers */ - - -/* - * Ethernet configuration registers - */ -#define DINGO_ECOR (DINGO_ETH+0) /* Ethernet Configuration Option Register */ -#define DINGO_ECSR (DINGO_ETH+2) /* Ethernet Configuration Status Register */ -#define DINGO_EBAR0 (DINGO_ETH+10) /* Ethernet Base Address Register bits 7:4 (3:0 always 0) */ -#define DINGO_EBAR1 (DINGO_ETH+12) /* Ethernet Base Address Register bits 15:8 */ - -/* DINGO_ECOR bits */ -#define DINGO_ECOR_ETH_ENABLE 0x01 /* 1 = Enable Ethernet part of adapter */ -#define DINGO_ECOR_IOB_ENABLE 0x02 /* 1 = Enable EBAR, else use INDEX bits */ -#define DINGO_ECOR_INT_ENABLE 0x04 /* 1 = Enable Ethernet interrupts */ -#define DINGO_ECOR_IOB_INDEX 0x18 /* 00 = 0x300; 01 = 0x310; 10 = 0x320; 11 = no IO base */ -#define DINGO_ECOR_IOB_SHIFT 0x03 -#define DINGO_ECOR_IRQ_STSCHG 0x20 /* 1 = Route interrupts to -STSCHG pin, else use -INT pin */ -#define DINGO_ECOR_IRQ_LEVEL 0x40 /* 1 = Level-triggered interrupts, else edge-triggered */ -#define DINGO_ECOR_SRESET 0x80 /* 1 = Soft reset Ethernet adpater. Must write to 0 */ - -/* DINGO_ECSR bits */ -#define DINGO_ECSR_INT_ACK 0x01 /* 1 = Host must acknowledge interrupts (Clear ECSR_INT bit) */ -#define DINGO_ECSR_INT 0x02 /* 1 = Interrupt service requested */ -#define DINGO_ECSR_POWER_DOWN 0x04 /* 1 = Power down Ethernet adapter */ - -/* - * EBAR0/EBAR1 set the I/O base address of the Ethernet adapter when - * ECOR_IOB_ENABLE is set. 12 significant bits. - */ - - -/* - * Dingo configuration registers - */ -#define DINGO_DCOR0 (DINGO_COR+0) /* Dingo Configuration Options Register 0 */ -#define DINGO_DCOR1 (DINGO_COR+2) /* Dingo Configuration Options Register 1 */ -#define DINGO_DCOR2 (DINGO_COR+4) /* Dingo Configuration Options Register 2 */ -#define DINGO_DCOR3 (DINGO_COR+6) /* Dingo Configuration Options Register 3 */ -#define DINGO_DCOR4 (DINGO_COR+8) /* Dingo Configuration Options Register 4 */ - -/* DINGO_DCOR0 bits */ -#define DINGO_DCOR0_SF_INT 0x01 /* 1 = Enable 2ndF interrupts (alternate to SFCOR:2) */ -#define DINGO_DCOR0_DECODE 0x04 /* 1 = Decode 2ndF interrupts in Dingo, else in 2ndF */ -#define DINGO_DCOR0_BUS 0x08 /* 1 = 2ndF bus is ISA, else PCMCIA */ -#define DINGO_DCOR0_LED3_POWER 0x10 /* 1 = Drive LED3 line from SFCSR:2 */ -#define DINGO_DCOR0_LED3_RESET 0x20 /* 1 = Drive LED3 line from SFCOR:7 */ -#define DINGO_DCOR0_MR_POWER 0x40 /* 1 = Drive MRESET line from SFCSR:2 */ -#define DINGO_DCOR0_MR_RESET 0x80 /* 1 = Drive MRESET line from SFCOR:7 */ - -/* DINGO_DCOR1 bits */ -#define DINGO_DCOR1_INT_STSCHG 0x01 /* 1 = Route 2ndF interrupts to -STSCHG (alternate to SFCOR:5) */ -#define DINGO_DCOR1_MSTSCHG 0x02 /* 1 = Route 2ndF -MSTSCHG line to -STSCHG */ -#define DINGO_DCOR1_EEDIO 0x04 /* 1 = Use EEDIO pin as data line 6 to 2ndF */ -#define DINGO_DCOR1_INT_LEVEL 0x08 /* 1 = Force level-triggered interrupts from 2ndF */ -#define DINGO_DCOR1_SHADOW_CSR 0x10 /* Reserved, always write 0 */ -#define DINGO_DCOR1_SHADOW_IOB 0x20 /* Reserved, always write 0 */ -#define DINGO_DCOR1_CSR_WAIT 0xC0 /* Reserved, always write 0 */ -#define DINGO_DCOR1_CSR_SHIFT 0x06 - -/* DINGO_DCOR2 bits */ -#define DINGO_DCOR2_SHM_BASE 0x0f /* Bits 15-12 of Ethernet shared memory window */ -#define DINGO_DCOR2_SHM_SHIFT 0x00 -#define DINGO_DCOR2_SHADOW_COR 0x10 /* Reserved, always write 0 */ - -/* - * DCOR3/DCOR4 configure Dingo to assert -IOIS16 on any access to each pair of - * ports in the range SFIOB+0 .. SFIOB+31. Each pair can be set individually, - * eg. DCOR3:0 enables this function on ports SFIOB+0 and SFIOB+1. - */ - - -/* - * Second function configuration registers - */ -#define DINGO_SFCOR (DINGO_2ND+0) /* 2nd Function Configuration Option Register */ -#define DINGO_SFCSR (DINGO_2ND+2) /* 2nd Function Configuration Status Register */ -#define DINGO_SFBAR0 (DINGO_2ND+10) /* 2nd Function Base Address Register bits 7:0 */ -#define DINGO_SFBAR1 (DINGO_2ND+12) /* 2nd Function Base Address Register bits 15:8 */ -#define DINGO_SFILR (DINGO_2ND+18) /* 2nd Function I/O Limit Register */ - -/* DINGO_SFCOR bits */ -#define DINGO_SFCOR_SF_ENABLE 0x01 /* 1 = Enable second fuction */ -#define DINGO_SFCOR_IOB_ENABLE 0x02 /* 1 = Enable SFBAR, else use COM_SELECT bits */ -#define DINGO_SFCOR_INT_ENABLE 0x04 /* 1 = Enable second function interrupts */ -#define DINGO_SFCOR_COM_SELECT 0x18 /* 00 = 0x3f8; 01 = 0x2f8; 10 = 0x3e8; 11 = 0x2e8 */ -#define DINGO_SFCOR_COM_SHIFT 0x03 -#define DINGO_SFCOR_IRQ_STSCHG 0x20 /* 1 = Route interrupts to -STSCHG pin, else use -INT pin */ -#define DINGO_SFCOR_IRQ_LEVEL 0x40 /* 1 = Level-triggered interrupts, else edge-triggered */ -#define DINGO_SFCOR_SRESET 0x80 /* 1 = Soft reset second function. Must write to 0 */ - -/* DINGO_SFCSR bits */ -#define DINGO_SFCSR_INT_ACK 0x01 /* 1 = Host must acknowledge interrupts (Clear SFCSR_INT bit) */ -#define DINGO_SFCSR_INT 0x02 /* 1 = Interrupt service requested */ -#define DINGO_SFCSR_POWER_DOWN 0x04 /* 1 = Power down second function */ - -/* - * SFBAR0/SFBAR1 set the I/O base address of the second function when - * SFCOR_IOB_ENABLE is set. 16 significant bits. - */ - -/* - * SFILR is a bitmap of address lines 7:0 decoded by the second function - * device. Eg. a device with 16 ports should write 0x0f to this register. - */ - - - -/******************************** - * Ethernet controller registers - ********************************/ - -/* - * Common registers (available from any register page) - * - * Note: The EDP is actually 32 bits wide, occupying registers 2-5. In PCMCIA - * operation we can only access 16 bits at once, through registers 4 & 5. - */ -#define XE_CR 0x00 /* Command register (write) */ -#define XE_ESR 0x00 /* Ethernet status register (read) */ -#define XE_PR 0x01 /* Page select register */ -#define XE_EDP 0x04 /* Ethernet data port */ -#define XE_ISR 0x06 /* Ethernet interrupt status register (read) */ -#define XE_GIR 0x07 /* Global interrupt register (Dingo only) */ - -/* XE_CR bits */ -#define XE_CR_TX_PACKET 0x01 /* Transmit packet */ -#define XE_CR_SOFT_RESET 0x02 /* Software reset */ -#define XE_CR_ENABLE_INTR 0x04 /* Enable interrupts */ -#define XE_CR_FORCE_INTR 0x08 /* Force an interrupt */ -#define XE_CR_CLEAR_FIFO 0x10 /* Clear FIFO after transmit overrun */ -#define XE_CR_CLEAR_OVERRUN 0x20 /* Clear receive overrun condition */ -#define XE_CR_RESTART_TX 0x40 /* Restart TX after 16 collisions or TX underrun */ - -/* XE_ESR bits */ -#define XE_ESR_FULL_PACKET_RX 0x01 /* At least one full packet received */ -#define XE_ESR_PART_PACKET_RX 0x02 /* At least 64 bytes of packet received */ -#define XE_ESR_REJECT_PACKET 0x04 /* Partial packet rejected */ -#define XE_ESR_TX_PENDING 0x08 /* At least one packet waiting to transmit */ -#define XE_ESR_BAD_POLARITY 0x10 /* Bad cable polarity? (CE2 only) */ -#define XE_ESR_MEDIA_SELECT 0x20 /* SSI(?) media select: 1 = Twisted pair; 0 = AUI */ - -/* XE_ISR bits */ -#define XE_ISR_TX_OVERFLOW 0x01 /* No space in transmit buffer */ -#define XE_ISR_TX_PACKET 0x02 /* Packet sent successfully */ -#define XE_ISR_MAC_INTR 0x04 /* Some kind of MAC interrupt happened */ -#define XE_ISR_RX_EARLY 0x10 /* Incoming packet in early receive mode */ -#define XE_ISR_RX_PACKET 0x20 /* Complete packet received successfully */ -#define XE_ISR_RX_REJECT 0x40 /* Partial incoming packet rejected by MAC */ -#define XE_ISR_FORCE_INTR 0x80 /* Interrupt forced */ - -/* XE_GIR bits */ -#define XE_GIR_ETH_IRQ 0x01 /* Ethernet IRQ pending */ -#define XE_GIR_ETH_MASK 0x02 /* 1 = Mask Ethernet interrupts to host */ -#define XE_GIR_SF_IRQ 0x04 /* Second function IRQ pending */ -#define XE_GIR_SF_MASK 0x08 /* 1 = Mask second function interrupts to host */ - - -/* - * Page 0 registers - */ -#define XE_TSO 0x08 /* Transmit space open (17 bits) */ -#define XE_TRS 0x0a /* Transmit reservation size (CE2 only, removed in rev. 1) */ -#define XE_DO 0x0c /* Data offset register (13 bits/3 flags, write) */ -#define XE_RSR 0x0c /* Receive status register (read) */ -#define XE_TPR 0x0d /* Packets transmitted register (read) */ -#define XE_RBC 0x0e /* Received byte count (13 bits/3 flags, read) */ - -/* XE_DO bits */ -#define XE_DO_OFFSET 0x1fff /* First byte fetched when CHANGE_OFFSET issued */ -#define XE_DO_OFFSET_SHIFT 0x00 -#define XE_DO_CHANGE_OFFSET 0x2000 /* Flush RX FIFO, start fetching from OFFSET */ -#define XE_DO_SHARED_MEM 0x4000 /* Enable shared memory mode */ -#define XE_DO_SKIP_RX_PACKET 0x8000 /* Skip to next packet in buffer memory */ - -/* XE_RSR bits */ -#define XE_RSR_PHYS_PACKET 0x01 /* 1 = Physical packet, 0 = Multicast packet */ -#define XE_RSR_BCAST_PACKET 0x02 /* Broadcast packet */ -#define XE_RSR_LONG_PACKET 0x04 /* Packet >1518 bytes */ -#define XE_RSR_ADDR_MATCH 0x08 /* Packet matched one of our node addresses */ -#define XE_RSR_ALIGN_ERROR 0x10 /* Bad alignment? (CE2 only) */ -#define XE_RSR_CRC_ERROR 0x20 /* Incorrect CRC */ -#define XE_RSR_RX_OK 0x80 /* No errors on received packet */ - -/* XE_RBC bits */ -#define XE_RBC_BYTE_COUNT 0x1fff /* Bytes received for current packet */ -#define XE_RBC_COUNT_SHIFT 0x00 -#define XE_RBC_FULL_PACKET_RX 0x2000 /* These mirror bits 2:0 of ESR, if ECR:7 is set */ -#define XE_RBC_PART_PACKET_RX 0x4000 -#define XE_RBC_REJECT_PACKET 0x8000 - - -/* - * Page 1 registers - */ -#define XE_IMR0 0x0c /* Interrupt mask register 0 */ -#define XE_IMR1 0x0d /* Interrupt mask register 1 (CE2 only) */ -#define XE_ECR 0x0e /* Ethernet configuration register */ - -/* XE_IMR0 bits */ -#define XE_IMR0_TX_OVERFLOW 0x01 /* Masks for bits in ISR */ -#define XE_IMR0_TX_PACKET 0x02 -#define XE_IMR0_MAC_INTR 0x04 -#define XE_IMR0_TX_RESGRANT 0x08 /* Tx reservation granted (CE2) */ -#define XE_IMR0_RX_EARLY 0x10 -#define XE_IMR0_RX_PACKET 0x20 -#define XE_IMR0_RX_REJECT 0x40 -#define XE_IMR0_FORCE_INTR 0x80 - -/* XE_IMR1 bits */ -#define XE_IMR1_TX_UNDERRUN 0x01 - -/* XE_ECR bits */ -#define XE_ECR_EARLY_TX 0x01 /* Enable early transmit mode */ -#define XE_ECR_EARLY_RX 0x02 /* Enable early receive mode */ -#define XE_ECR_FULL_DUPLEX 0x04 /* Enable full-duplex (disable collision detection) */ -#define XE_ECR_LONG_TPCABLE 0x08 /* CE2 only */ -#define XE_ECR_NO_POL_COL 0x10 /* CE2 only */ -#define XE_ECR_NO_LINK_PULSE 0x20 /* Don't check/send link pulses (not 10BT compliant) */ -#define XE_ECR_NO_AUTO_TX 0x40 /* CE2 only */ -#define XE_ECR_SOFT_COMPAT 0x80 /* Map ESR bits 2:0 to RBC bits 15:13 */ - - -/* - * Page 2 registers - */ -#define XE_RBS 0x08 /* Receive buffer start (16 bits) */ -#define XE_LED 0x0a /* LED control register */ -#define XE_LED3 0x0b /* LED3 control register */ -#define XE_MSR 0x0c /* Misc. setup register (Mohawk specific register?) */ -#define XE_GPR2 0x0d /* General purpose register 2 */ - -/* - * LED function selection: - * 000 - Disabled - * 001 - Collision activity - * 010 - !Collision activity - * 011 - 10Mbit link detected - * 100 - 100Mbit link detected - * 101 - 10/100Mbit link detected - * 110 - Automatic assertion - * 111 - Transmit activity - */ - -/* XE_LED bits */ -#define XE_LED_LED0_MASK 0x07 /* LED0 function selection */ -#define XE_LED_LED0_SHIFT 0x00 -#define XE_LED_LED1_MASK 0x38 /* LED1 function selection */ -#define XE_LED_LED1_SHIFT 0x03 -#define XE_LED_LED0_RX 0x40 /* Add receive activity to LED0 */ -#define XE_LED_LED1_RX 0x80 /* Add receive activity to LED1 */ - -/* XE_LED3 bits */ -#define XE_LED3_MASK 0x07 /* LED3 function selection */ -#define XE_LED3_SHIFT 0x00 -#define XE_LED3_RX 0x40 /* Add receive activity to LED3 */ - -/* XE_MSR bits */ -#define XE_MSR_128K_SRAM 0x01 /* Select 128K SRAM */ -#define XE_MSR_RBS_BIT16 0x02 /* Bit 16 of RBS (only useful with big SRAM) */ -#define XE_MSR_MII_SELECT 0x08 /* Select MII instead of SSI interface */ -#define XE_MSR_HASH_TABLE 0x20 /* Enable hash table filtering */ - -/* XE_GPR2 bits */ -#define XE_GPR2_GP3_OUT 0x01 /* Value written to GP3 line */ -#define XE_GPR2_GP4_OUT 0x02 /* Value written to GP4 line */ -#define XE_GPR2_GP3_SELECT 0x04 /* 1 = GP3 is output, 0 = GP3 is input */ -#define XE_GPR2_GP4_SELECT 0x08 /* 1 = GP4 is output, 0 = GP3 is input */ -#define XE_GPR2_GP3_IN 0x10 /* Value read from GP3 line */ -#define XE_GPR2_GP4_IN 0x20 /* Value read from GP4 line */ - - -/* - * Page 3 registers - */ -#define XE_TPT 0x0a /* Transmit packet threshold (13 bits) */ - - -/* - * Page 4 registers - */ -#define XE_GPR0 0x08 /* General purpose register 0 */ -#define XE_GPR1 0x09 /* General purpose register 1 */ -#define XE_BOV 0x0a /* Bonding version register (read) */ -#define XE_EES 0x0b /* EEPROM control register */ -#define XE_LMA 0x0c /* Local memory address (CE2 only) */ -#define XE_LMD 0x0e /* Local memory data (CE2 only) */ - -/* XE_GPR0 bits */ -#define XE_GPR0_GP1_OUT 0x01 /* Value written to GP1 line */ -#define XE_GPR0_GP2_OUT 0x02 /* Value written to GP2 line */ -#define XE_GPR0_GP1_SELECT 0x04 /* 1 = GP1 is output, 0 = GP1 is input */ -#define XE_GPR0_GP2_SELECT 0x08 /* 1 = GP2 is output, 0 = GP2 is input */ -#define XE_GPR0_GP1_IN 0x10 /* Value read from GP1 line */ -#define XE_GPR0_GP2_IN 0x20 /* Value read from GP2 line */ - -/* XE_GPR1 bits */ -#define XE_GPR1_POWER_DOWN 0x01 /* 0 = Power down analog section */ -#define XE_GPR1_AIC 0x04 /* AIC bit (CE2 only) */ - -/* XE_BOV values */ -#define XE_BOV_DINGO 0x55 /* Dingo in Dingo mode */ -#define XE_BOV_MOHAWK 0x41 /* Original Mohawk */ -#define XE_BOV_MOHAWK_REV1 0x45 /* Rev. 1 Mohawk, or Dingo in Mohawk mode */ -#define XE_BOV_CEM28 0x11 /* CEM28 */ - -/* XE_EES bits */ -#define XE_EES_SCL_OUTPUT 0x01 /* Value written to SCL line, when MANUAL_ROM set */ -#define XE_EES_SDA_OUTPUT 0x02 /* Value written to SDA line, when MANUAL_ROM set */ -#define XE_EES_SDA_INPUT 0x04 /* Value read from SDA line */ -#define XE_EES_SDA_TRISTATE 0x08 /* 1 = SDA is output, 0 = SDA is input */ -#define XE_EES_MANUAL_ROM 0x20 /* Enable manual contro of serial EEPROM */ - - -/* - * Page 5 registers (all read only) - */ -#define XE_CRHA 0x08 /* Current Rx host address (16 bits) */ -#define XE_RHSA 0x0a /* Rx host start address (16 bits) */ -#define XE_RNSA 0x0c /* Rx network start address (16 bits) */ -#define XE_CRNA 0x0e /* Current Rx network address (16 bits) */ - - -/* - * Page 6 registers (all read only) - */ -#define XE_CTHA 0x08 /* Current Tx host address (16 bits) */ -#define XE_THSA 0x0a /* Tx host start address (16 bits) */ -#define XE_TNSA 0x0c /* Tx network statr address (16 bits) */ -#define XE_CTNA 0x0e /* Current Tx network address (16 bits) */ - - -/* - * Page 8 registers (all read only) - */ -#define XE_THBC 0x08 /* Tx host byte count (16 bits) */ -#define XE_THPS 0x0a /* Tx host packet size (16 bits) */ -#define XE_TNBC 0x0c /* Tx network byte count (16 bits) */ -#define XE_TNPS 0x0e /* Tx network packet size (16 bits) */ - - -/* - * Page 0x10 registers (all read only) - */ -#define XE_DINGOID 0x08 /* Dingo ID register (16 bits) (Dingo only) */ -#define XE_RevID 0x0a /* Dingo revision ID (16 bits) (Dingo only) */ -#define XE_VendorID 0x0c /* Dingo vendor ID (16 bits) (Dingo only) */ - -/* Values for the above registers */ -#define XE_DINGOID_DINGO3 0x444b /* In both Dingo and Mohawk modes */ -#define XE_RevID_DINGO3 0x0001 -#define XE_VendorID_DINGO3 0x0041 - - -/* - * Page 0x40 registers - */ -#define XE_CMD0 0x08 /* MAC Command register (write) */ -#define XE_RST0 0x09 /* Receive status register */ -#define XE_TXST0 0x0b /* Transmit status register 0 */ -#define XE_TXST1 0x0c /* Transmit status register 1 */ -#define XE_RX0Msk 0x0d /* Receive status mask register */ -#define XE_TX0Msk 0x0e /* Transmit status 0 mask register */ -#define XE_TX1Msk 0x0f /* Transmit status 1 mask register */ - -/* CMD0 bits */ -#define XE_CMD0_TX 0x01 /* CE2 only */ -#define XE_CMD0_RX_ENABLE 0x04 /* Enable receiver */ -#define XE_CMD0_RX_DISABLE 0x08 /* Disable receiver */ -#define XE_CMD0_ABORT 0x10 /* CE2 only */ -#define XE_CMD0_ONLINE 0x20 /* Take MAC online */ -#define XE_CMD0_ACK_INTR 0x40 /* CE2 only */ -#define XE_CMD0_OFFLINE 0x80 /* Take MAC offline */ - -/* RST0 bits */ -#define XE_RST0_LONG_PACKET 0x02 /* Packet received with >1518 and <8184 bytes */ -#define XE_RST0_CRC_ERROR 0x08 /* Packet received with incorrect CRC */ -#define XE_RST0_RX_OVERRUN 0x10 /* Receiver overrun, byte(s) dropped */ -#define XE_RST0_RX_ENABLE 0x20 /* Receiver enabled */ -#define XE_RST0_RX_ABORT 0x40 /* Receive aborted: CRC, FIFO overrun or addr mismatch */ -#define XE_RST0_RX_OK 0x80 /* Complete packet received OK */ - -/* TXST0 bits */ -#define XE_TXST0_NO_CARRIER 0x01 /* Lost carrier. Only valid in 10Mbit half-duplex */ -#define XE_TXST0_16_COLLISIONS 0x02 /* Packet aborted after 16 collisions */ -#define XE_TXST0_TX_UNDERRUN 0x08 /* MAC ran out of data to send */ -#define XE_TXST0_LATE_COLLISION 0x10 /* Collision later than 512 bits */ -#define XE_TXST0_SQE_FAIL 0x20 /* SQE test failed. */ -#define XE_TXST0_TX_ABORT 0x40 /* Transmit aborted: collisions, underrun or overrun */ -#define XE_TXST0_TX_OK 0x80 /* Complete packet sent OK */ - -/* TXST1 bits */ -#define XE_TXST1_RETRY_COUNT 0x0f /* Collision counter for current packet */ -#define XE_TXST1_LINK_STATUS 0x10 /* Valid link status */ - -/* RX0Msk bits */ -#define XE_RX0M_MP 0x01 /* Multicast packet? (CE2 only) */ -#define XE_RX0M_LONG_PACKET 0x02 /* Masks for bits in RXST0 */ -#define XE_RX0M_ALIGN_ERROR 0x04 /* Alignment error (CE2 only) */ -#define XE_RX0M_CRC_ERROR 0x08 -#define XE_RX0M_RX_OVERRUN 0x10 -#define XE_RX0M_RX_ABORT 0x40 -#define XE_RX0M_RX_OK 0x80 - -/* TX0Msk bits */ -#define XE_TX0M_NO_CARRIER 0x01 /* Masks for bits in TXST0 */ -#define XE_TX0M_16_COLLISIONS 0x02 -#define XE_TX0M_TX_UNDERRUN 0x08 -#define XE_TX0M_LATE_COLLISION 0x10 -#define XE_TX0M_SQE_FAIL 0x20 -#define XE_TX0M_TX_ABORT 0x40 -#define XE_TX0M_TX_OK 0x80 - -/* TX1Msk bits */ -#define XE_TX1M_PKTDEF 0x20 - - -/* - * Page 0x42 registers - */ -#define XE_SWC0 0x08 /* Software configuration 0 */ -#define XE_SWC1 0x09 /* Software configuration 1 */ -#define XE_BOC 0x0a /* Back-off configuration */ -#define XE_TCD 0x0b /* Transmit collision deferral */ - -/* SWC0 bits */ -#define XE_SWC0_LOOPBACK_ENABLE 0x01 /* Enable loopback operation */ -#define XE_SWC0_LOOPBACK_SOURCE 0x02 /* 1 = Transceiver, 0 = MAC */ -#define XE_SWC0_ACCEPT_ERROR 0x04 /* Accept otherwise OK packets with CRC errors */ -#define XE_SWC0_ACCEPT_SHORT 0x08 /* Accept otherwise OK packets that are too short */ -#define XE_SWC0_NO_SRC_INSERT 0x20 /* Disable source insertion (CE2) */ -#define XE_SWC0_NO_CRC_INSERT 0x40 /* Don't add CRC to outgoing packets */ - -/* SWC1 bits */ -#define XE_SWC1_IA_ENABLE 0x01 /* Enable individual address filters */ -#define XE_SWC1_ALLMULTI 0x02 /* Accept all multicast packets */ -#define XE_SWC1_PROMISCUOUS 0x04 /* Accept all non-multicast packets */ -#define XE_SWC1_BCAST_DISABLE 0x08 /* Reject broadcast packets */ -#define XE_SWC1_MEDIA_SELECT 0x40 /* AUI media select (Mohawk only) */ -#define XE_SWC1_AUTO_MEDIA 0x80 /* Auto media select (Mohawk only) */ - - -/* - * Page 0x44 registers (CE2 only) - */ -#define XE_TDR0 0x08 /* Time domain reflectometry register 0 */ -#define XE_TDR1 0x09 /* Time domain reflectometry register 1 */ -#define XE_RXC0 0x0a /* Receive byte count low */ -#define XE_RXC1 0x0b /* Receive byte count high */ - - -/* - * Page 0x45 registers (CE2 only) - */ -#define XE_REV 0x0f /* Revision (read) */ - - -/* - * Page 0x50-0x57: Individual address 0-9 - * - * Used to filter incoming packets by matching against individual node - * addresses. If IA matching is enabled (SWC1, bit0) any incoming packet with - * a destination matching one of these 10 addresses will be received. IA0 is - * always enabled and usually matches the card's unique address. - * - * Addresses are stored LSB first, ie. IA00 (reg. 8 on page 0x50) contains the - * LSB of IA0, and so on. The data is stored contiguously, in that addresses - * can be broken across page boundaries. That is: - * - * Reg: 50/8 50/9 50/a 50/b 50/c 50/d 50/e 50/f 51/8 51/9 ... 57/a 57/b - * IA00 IA01 IA02 IA03 IA04 IA05 IA10 IA11 IA12 IA13 ... IA94 IA95 - */ - -/* - * Page 0x58: Multicast hash table filter - * - * In case the 10 individual addresses aren't enough, we also have a multicast - * hash filter, enabled through MSR:5. The most significant six bits of the - * CRC on each incoming packet are reversed and used as an index into the 64 - * bits of the hash table. If the appropriate bit is set the packet it - * received, although higher layers may still need to filter it out. The CRC - * calculation is as follows: - * - * crc = 0xffffffff; - * poly = 0x04c11db6; - * for (i = 0; i < 6; i++) { - * current = mcast_addr[i]; - * for (k = 1; k <= 8; k++) { - * if (crc & 0x80000000) - * crc31 = 0x01; - * else - * crc31 = 0; - * bit = crc31 ^ (current & 0x01); - * crc <<= 1; - * current >>= 1; - * if (bit) - * crc = (crc ^ poly)|1 - * } - * } - */ - - - -/**************** - * MII registers - ****************/ - -/* - * Basic MII-compliant PHY register definitions. According to the Dingo spec, - * PHYs from (at least) MicroLinear, National Semiconductor, ICS, TDK and - * Quality Semiconductor have been used. These apparently all come up with - * PHY ID 0x00 unless the "interceptor module" on the Dingo 3 is in use. With - * the interceptor enabled, the PHY is faked up to look like an ICS unit with - * ID 0x16. The interceptor can be enabled/disabled in software. - * - * The ML6692 (and maybe others) doesn't have a 10Mbps mode -- this is handled - * by an internal 10Mbps transceiver that we know nothing about... some cards - * seem to work with the MII in 10Mbps mode, so I guess some PHYs must support - * it. The question is, how can you figure out which one you have? Just to - * add to the fun there are also 10Mbps _only_ Mohawk/Dingo cards. Aaargh! - */ - -/* - * Masks for the MII-related bits in GPR2 - */ -#define XE_MII_CLK XE_GPR2_GP3_OUT -#define XE_MII_DIR XE_GPR2_GP4_SELECT -#define XE_MII_WRD XE_GPR2_GP4_OUT -#define XE_MII_RDD XE_GPR2_GP4_IN - -/* - * MII PHY ID register values - */ -#define PHY_ID_ML6692 0x0000 /* MicroLinear ML6692? Or unknown */ -#define PHY_ID_ICS1890 0x0015 /* ICS1890 */ -#define PHY_ID_QS6612 0x0181 /* Quality QS6612 */ -#define PHY_ID_DP83840 0x2000 /* National DP83840 */ - -/* - * MII command (etc) bit strings. - */ -#define XE_MII_STARTDELIM 0x01 -#define XE_MII_READOP 0x02 -#define XE_MII_WRITEOP 0x01 -#define XE_MII_TURNAROUND 0x02 - -/* - * PHY registers. - */ -#define PHY_BMCR 0x00 /* Basic Mode Control Register */ -#define PHY_BMSR 0x01 /* Basic Mode Status Register */ -#define PHY_ID1 0x02 /* PHY ID 1 */ -#define PHY_ID2 0x03 /* PHY ID 2 */ -#define PHY_ANAR 0x04 /* Auto-Negotiation Advertisement Register */ -#define PHY_LPAR 0x05 /* Auto-Negotiation Link Partner Ability Register */ -#define PHY_ANER 0x06 /* Auto-Negotiation Expansion Register */ - -/* BMCR bits */ -#define PHY_BMCR_RESET 0x8000 /* Soft reset PHY. Self-clearing */ -#define PHY_BMCR_LOOPBK 0x4000 /* Enable loopback */ -#define PHY_BMCR_SPEEDSEL 0x2000 /* 1=100Mbps, 0=10Mbps */ -#define PHY_BMCR_AUTONEGENBL 0x1000 /* Auto-negotiation enabled */ -#define PHY_BMCR_ISOLATE 0x0400 /* Isolate ML6692 from MII */ -#define PHY_BMCR_AUTONEGRSTR 0x0200 /* Restart auto-negotiation. Self-clearing */ -#define PHY_BMCR_DUPLEX 0x0100 /* Full duplex operation */ -#define PHY_BMCR_COLLTEST 0x0080 /* Enable collision test */ - -/* BMSR bits */ -#define PHY_BMSR_100BT4 0x8000 /* 100Base-T4 capable */ -#define PHY_BMSR_100BTXFULL 0x4000 /* 100Base-TX full duplex capable */ -#define PHY_BMSR_100BTXHALF 0x2000 /* 100Base-TX half duplex capable */ -#define PHY_BMSR_10BTFULL 0x1000 /* 10Base-T full duplex capable */ -#define PHY_BMSR_10BTHALF 0x0800 /* 10Base-T half duplex capable */ -#define PHY_BMSR_AUTONEGCOMP 0x0020 /* Auto-negotiation complete */ -#define PHY_BMSR_CANAUTONEG 0x0008 /* Auto-negotiation supported */ -#define PHY_BMSR_LINKSTAT 0x0004 /* Link is up */ -#define PHY_BMSR_EXTENDED 0x0001 /* Extended register capabilities */ - -/* ANAR bits */ -#define PHY_ANAR_NEXTPAGE 0x8000 /* Additional link code word pages */ -#define PHY_ANAR_TLRFLT 0x2000 /* Remote wire fault detected */ -#define PHY_ANAR_100BT4 0x0200 /* 100Base-T4 capable */ -#define PHY_ANAR_100BTXFULL 0x0100 /* 100Base-TX full duplex capable */ -#define PHY_ANAR_100BTXHALF 0x0080 /* 100Base-TX half duplex capable */ -#define PHY_ANAR_10BTFULL 0x0040 /* 10Base-T full duplex capable */ -#define PHY_ANAR_10BTHALF 0x0020 /* 10Base-T half duplex capable */ -#define PHY_ANAR_PROTO4 0x0010 /* Protocol selection (00001 = 802.3) */ -#define PHY_ANAR_PROTO3 0x0008 -#define PHY_ANAR_PROTO2 0x0004 -#define PHY_ANAR_PROTO1 0x0002 -#define PHY_ANAR_PROTO0 0x0001 -#define PHY_ANAR_8023 PHY_ANAR_PROTO0 -#define PHY_ANAR_DINGO PHY_ANAR_100BT+PHY_ANAR_10BT_FD+PHY_ANAR_10BT+PHY_ANAR_8023 -#define PHY_ANAR_MOHAWK PHY_ANAR_100BT+PHY_ANAR_10BT_FD+PHY_ANAR_10BT+PHY_ANAR_8023 - -/* LPAR bits */ -#define PHY_LPAR_NEXTPAGE 0x8000 /* Additional link code word pages */ -#define PHY_LPAR_LPACK 0x4000 /* Link partner acknowledged receipt */ -#define PHY_LPAR_TLRFLT 0x2000 /* Remote wire fault detected */ -#define PHY_LPAR_100BT4 0x0200 /* 100Base-T4 capable */ -#define PHY_LPAR_100BTXFULL 0x0100 /* 100Base-TX full duplex capable */ -#define PHY_LPAR_100BTXHALF 0x0080 /* 100Base-TX half duplex capable */ -#define PHY_LPAR_10BTFULL 0x0040 /* 10Base-T full duplex capable */ -#define PHY_LPAR_10BTHALF 0x0020 /* 10Base-T half duplex capable */ -#define PHY_LPAR_PROTO4 0x0010 /* Protocol selection (00001 = 802.3) */ -#define PHY_LPAR_PROTO3 0x0008 -#define PHY_LPAR_PROTO2 0x0004 -#define PHY_LPAR_PROTO1 0x0002 -#define PHY_LPAR_PROTO0 0x0001 - -/* ANER bits */ -#define PHY_ANER_MLFAULT 0x0010 /* More than one link is up! */ -#define PHY_ANER_LPNPABLE 0x0008 /* Link partner supports next page */ -#define PHY_ANER_NPABLE 0x0004 /* Local port supports next page */ -#define PHY_ANER_PAGERX 0x0002 /* Page received */ -#define PHY_ANER_LPAUTONEG 0x0001 /* Link partner can auto-negotiate */ - -#endif /* DEV_XE_IF_XEREG_H */ diff --git a/sys/dev/xe/if_xevar.h b/sys/dev/xe/if_xevar.h deleted file mode 100644 index 57211dc47946..000000000000 --- a/sys/dev/xe/if_xevar.h +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998, 1999 Scott Mitchell - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: if_xe.c,v 1.20 1999/06/13 19:17:40 scott Exp $ - * $FreeBSD$ - */ -#ifndef DEV_XE_IF_XEDEV_H -#define DEV_XE_IF_XEDEV_H - -/* - * One of these structures per allocated device - */ -struct xe_softc { - struct ifmedia ifmedia; - struct ifmib_iso_8802_3 mibdata; - struct callout media_timer; - struct callout wdog_timer; - int tx_timeout; - struct mtx lock; - struct ifnet *ifp; - struct ifmedia *ifm; - u_char enaddr[ETHER_ADDR_LEN]; - const char *card_type; /* Card model name */ - const char *vendor; /* Card manufacturer */ - device_t dev; /* Device */ - void *intrhand; - struct resource *irq_res; - int irq_rid; - struct resource *port_res; - int port_rid; - struct resource *ce2_port_res; - int ce2_port_rid; - int srev; /* Silicon revision */ - int tx_queued; /* Transmit packets currently waiting */ - int tx_tpr; /* Last value of TPR reg on card */ - int tx_timeouts; /* Count of transmit timeouts */ - uint16_t tx_min; /* Smallest packet for no padding */ - uint16_t tx_thres; /* Threshold bytes for early transmit */ - int autoneg_status; /* Autonegotiation progress state */ - int media; /* Private media word */ - u_char version; /* Bonding Version register from card */ - u_char modem; /* 1 = Card has a modem */ - u_char ce2; /* 1 = Card has CE2 silicon */ - u_char mohawk; /* 1 = Card has Mohawk (CE3) silicon */ - u_char dingo; /* 1 = Card has Dingo (CEM56) silicon */ - u_char phy_ok; /* 1 = MII-compliant PHY found */ - u_char gone; /* 1 = Card bailed out */ -}; - -#define XE_LOCK(sc) mtx_lock(&(sc)->lock) -#define XE_UNLOCK(sc) mtx_unlock(&(sc)->lock) -#define XE_ASSERT_LOCKED(sc) mtx_assert(&(sc)->lock, MA_OWNED) - -/* - * For accessing card registers - */ -#define XE_INB(r) bus_read_1(scp->port_res, (r)) -#define XE_INW(r) bus_read_2(scp->port_res, (r)) -#define XE_OUTB(r, b) bus_write_1(scp->port_res, (r), (b)) -#define XE_OUTW(r, w) bus_write_2(scp->port_res, (r), (w)) -#define XE_SELECT_PAGE(p) XE_OUTB(XE_PR, (p)) - -int xe_attach(device_t dev); -int xe_activate(device_t dev); -void xe_deactivate(device_t dev); -void xe_stop(struct xe_softc *scp); - -#endif /* DEV_XE_IF_XEVAR_H */ diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 904741c1b17a..ecf8e16a180c 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -264,7 +264,6 @@ device vte # DM&P Vortex86 RDC R6040 Fast Ethernet device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') # ISA Ethernet NICs. pccard NICs included. -device xe # Xircom pccard Ethernet # Wireless NIC cards device wlan # 802.11 support diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 12f4bec3407f..ecaf858ac57e 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -387,7 +387,6 @@ SUBDIR= \ ${_wpi} \ ${_wpifw} \ ${_x86bios} \ - ${_xe} \ xl \ xz \ zlib @@ -610,7 +609,6 @@ _sppp= sppp _vmware= vmware _wbwd= wbwd _wi= wi -_xe= xe _aac= aac _aacraid= aacraid diff --git a/sys/modules/xe/Makefile b/sys/modules/xe/Makefile deleted file mode 100644 index 8ebd53f115c3..000000000000 --- a/sys/modules/xe/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/xe - -KMOD= if_xe -SRCS= if_xe.c if_xe_pccard.c -SRCS+= bus_if.h card_if.h device_if.h pccarddevs.h - -.include <bsd.kmod.mk> |