summaryrefslogtreecommitdiffstats
path: root/sys/dev/ed
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2005-10-05 05:21:07 +0000
committerimp <imp@FreeBSD.org>2005-10-05 05:21:07 +0000
commit3918200e48a817e74de0f2777a079aa6737fd612 (patch)
tree34ef6141c98919a5f829ba081df4954be3f56cb4 /sys/dev/ed
parent0f2fe8b63d1ea3957b6eba4885d45691a3e5d0f1 (diff)
downloadFreeBSD-src-3918200e48a817e74de0f2777a079aa6737fd612.zip
FreeBSD-src-3918200e48a817e74de0f2777a079aa6737fd612.tar.gz
MFp4:
o Add support for Tamarack TC5299J + MII found on SMC 8041TX V.2 and corega PCCCCTXD o Add support for ISA/PCI RTL80[12]9 chips o Improve support for the ax88790 based o minor code movement Submitted by: (#2) David Madole
Diffstat (limited to 'sys/dev/ed')
-rw-r--r--sys/dev/ed/ax88x90reg.h38
-rw-r--r--sys/dev/ed/dl100xxreg.h42
-rw-r--r--sys/dev/ed/if_ed_isa.c8
-rw-r--r--sys/dev/ed/if_ed_pccard.c213
-rw-r--r--sys/dev/ed/if_ed_pci.c8
-rw-r--r--sys/dev/ed/if_ed_rtl80x9.c211
-rw-r--r--sys/dev/ed/if_edreg.h41
-rw-r--r--sys/dev/ed/if_edvar.h1
-rw-r--r--sys/dev/ed/rtl80x9reg.h58
-rw-r--r--sys/dev/ed/tc5299jreg.h38
10 files changed, 591 insertions, 67 deletions
diff --git a/sys/dev/ed/ax88x90reg.h b/sys/dev/ed/ax88x90reg.h
new file mode 100644
index 0000000..9d2eeed
--- /dev/null
+++ b/sys/dev/ed/ax88x90reg.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2005, M. Warner Losh.
+ * 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 unmodified, 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$
+ */
+
+/* AX88x90 based miibus defines */
+#define ED_AX88X90_MIIBUS 0x04 /* MII bus register on ASIC */
+#define ED_AX88X90_MII_CLK 0x01
+#define ED_AX88X90_MII_DIROUT 0x02
+#define ED_AX88X90_MII_DATAIN 0x04
+#define ED_AX88X90_MII_DATAOUT 0x08
+#define ED_AX88X90_TEST 0x05 /* "test" register on asic */
+#define ED_AX88X90_GPIO 0x07 /* GPIO pins */
+#define ED_AX88X90_GPIO_INT_PHY 0x10
diff --git a/sys/dev/ed/dl100xxreg.h b/sys/dev/ed/dl100xxreg.h
new file mode 100644
index 0000000..a4659b0
--- /dev/null
+++ b/sys/dev/ed/dl100xxreg.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2005, M. Warner Losh.
+ * 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 unmodified, 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$
+ */
+
+/* Dlink chipset used on some Netgear and Dlink PCMCIA cards */
+#define ED_DL100XX_MIIBUS 0x0c /* MII bus register on ASIC */
+#define ED_DL100XX_DIAG 0x0d
+#define ED_DL100XX_COLLISON_DIS 4 /* Disable collision detection */
+
+#define ED_DL100XX_MII_RESET1 0x04
+#define ED_DL100XX_MII_RESET2 0x08
+
+#define ED_DL100XX_MII_DATAIN 0x10
+#define ED_DL100XX_MII_DIROUT_22 0x20
+#define ED_DL100XX_MII_DIROUT_19 0x10
+#define ED_DL100XX_MII_DATAOUT 0x40
+#define ED_DL100XX_MII_CLK 0x80
diff --git a/sys/dev/ed/if_ed_isa.c b/sys/dev/ed/if_ed_isa.c
index fcf9b20..ec970e1 100644
--- a/sys/dev/ed/if_ed_isa.c
+++ b/sys/dev/ed/if_ed_isa.c
@@ -114,6 +114,11 @@ ed_isa_probe(device_t dev)
goto end;
ed_release_resources(dev);
+ error = ed_probe_RTL80x9(dev, 0, flags);
+ if (error == 0)
+ goto end;
+ ed_release_resources(dev);
+
#ifdef ED_3C503
error = ed_probe_3Com(dev, 0, flags);
if (error == 0)
@@ -166,6 +171,9 @@ ed_isa_attach(device_t dev)
return (error);
}
+ if (sc->chip_type == ED_CHIP_TYPE_RTL8029)
+ ed_Novell_read_mac(sc);
+
#ifdef ED_HPP
if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS)
sc->readmem = ed_hpp_readmem;
diff --git a/sys/dev/ed/if_ed_pccard.c b/sys/dev/ed/if_ed_pccard.c
index 9c3cd9a..0c36b61 100644
--- a/sys/dev/ed/if_ed_pccard.c
+++ b/sys/dev/ed/if_ed_pccard.c
@@ -64,7 +64,8 @@
* 0-1 PHY01 00 auto, 01 res, 10 10B5, 11 TPI
* 2 GDLINK 1 disable checking of link
* 6 LINK 0 bad link, 1 good link
- * TMI tc5299 (not seen in the wild, afaik) 10/100 chip
+ * TMI tc5299 10/100 chip, has a different MII interaction than
+ * dl100xx and ax88x90.
*
* EN5017A, EN5020 no data, but very popular
* Other chips?
@@ -92,6 +93,9 @@
#include <dev/ed/if_edreg.h>
#include <dev/ed/if_edvar.h>
+#include <dev/ed/ax88x90reg.h>
+#include <dev/ed/dl100xxreg.h>
+#include <dev/ed/tc5299jreg.h>
#include <dev/pccard/pccardvar.h>
#include <dev/pccard/pccardreg.h>
#include <dev/pccard/pccard_cis.h>
@@ -104,18 +108,15 @@
#include "pccarddevs.h"
/*
- * PC Cards should be using a network specific FUNCE in the CIS to
- * communicate their MAC address to the driver. However, there are a
- * large number of NE-2000ish PC Cards that don't do this. Nearly all
- * of them store the MAC address at a fixed offset into attribute
- * memory, without any reference at all appearing in the CIS. And
- * nearly all of those store it at the same location.
+ * NE-2000 based PC Cards have a number of ways to get the MAC address.
+ * Some cards encode this as a FUNCE. Others have this in the ROMs the
+ * same way that ISA cards do. Some have it encoded in the attribute
+ * memory somewhere that isn't in the CIS. Some new chipsets have it
+ * in special registers in the ASIC part of the chip.
*
- * This applies only to the older, NE-2000 compatbile cards. The newer
- * cards based on the AX88x90 or DL100XX chipsets have a specific place
- * to look for MAC information. And only to those NE-2000 compatible cards
- * that don't the NE-2000 compatible thing of placing the PROM contents
- * starting at location 0 of memory.
+ * For those cards that have the MAC adress stored in attribute memory,
+ * nearly all of them have it at a fixed offset (0xff0). We use that
+ * offset as a source of last resource if other offsets have failed.
*/
#define ED_DEFAULT_MAC_OFFSET 0xff0
@@ -124,9 +125,10 @@ static const struct ed_product {
int flags;
#define NE2000DVF_DL100XX 0x0001 /* chip is D-Link DL10019/22 */
#define NE2000DVF_AX88X90 0x0002 /* chip is ASIX AX88[17]90 */
-#define NE2000DVF_ENADDR 0x0004 /* Get MAC from attr mem */
-#define NE2000DVF_ANYFUNC 0x0008 /* Allow any function type */
-#define NE2000DVF_MODEM 0x0010 /* Has a modem/serial */
+#define NE2000DVF_TC5299J 0x0004 /* chip is Tamarack TC5299J */
+#define NE2000DVF_ENADDR 0x0100 /* Get MAC from attr mem */
+#define NE2000DVF_ANYFUNC 0x0200 /* Allow any function type */
+#define NE2000DVF_MODEM 0x0400 /* Has a modem/serial */
int enoff;
} ed_pccard_products[] = {
{ PCMCIA_CARD(ACCTON, EN2212), 0},
@@ -194,7 +196,7 @@ static const struct ed_product {
NE2000DVF_ANYFUNC | NE2000DVF_AX88X90 | NE2000DVF_MODEM},
{ PCMCIA_CARD(RACORE, ETHERNET), 0},
{ PCMCIA_CARD(RACORE, FASTENET), NE2000DVF_AX88X90},
- { PCMCIA_CARD(RACORE, 8041TX), NE2000DVF_AX88X90},
+ { PCMCIA_CARD(RACORE, 8041TX), NE2000DVF_AX88X90 | NE2000DVF_TC5299J},
{ PCMCIA_CARD(RELIA, COMBO), 0},
{ PCMCIA_CARD(RPTI, EP400), 0},
{ PCMCIA_CARD(RPTI, EP401), 0},
@@ -228,15 +230,21 @@ static u_int ed_pccard_dl100xx_mii_readbits(struct ed_softc *sc, int nbits);
static void ed_pccard_dl100xx_mii_writebits(struct ed_softc *sc, u_int val,
int nbits);
+static int ed_pccard_ax88x90(device_t dev, const struct ed_product *);
static void ed_pccard_ax88x90_mii_reset(struct ed_softc *sc);
static u_int ed_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits);
static void ed_pccard_ax88x90_mii_writebits(struct ed_softc *sc, u_int val,
int nbits);
+
static int ed_miibus_readreg(device_t dev, int phy, int reg);
static int ed_ifmedia_upd(struct ifnet *);
static void ed_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-static int ed_pccard_ax88x90(device_t dev, const struct ed_product *);
+static int ed_pccard_tc5299j(device_t dev, const struct ed_product *);
+static void ed_pccard_tc5299j_mii_reset(struct ed_softc *sc);
+static u_int ed_pccard_tc5299j_mii_readbits(struct ed_softc *sc, int nbits);
+static void ed_pccard_tc5299j_mii_writebits(struct ed_softc *sc, u_int val,
+ int nbits);
static void
ed_pccard_print_entry(const struct ed_product *pp)
@@ -388,11 +396,23 @@ ed_pccard_tick(void *arg)
{
struct ed_softc *sc = arg;
struct mii_data *mii;
+ int media = 0;
ED_ASSERT_LOCKED(sc);
if (sc->miibus != NULL) {
mii = device_get_softc(sc->miibus);
+ media = mii->mii_media_status;
mii_tick(mii);
+ if (mii->mii_media_status & IFM_ACTIVE &&
+ media != mii->mii_media_status && 0 &&
+ sc->chip_type == ED_CHIP_TYPE_DL10022) {
+ printf("'22: state change up: %x %x\n",
+ mii->mii_media_status, mii->mii_media_active);
+ ed_asic_outb(sc, ED_DL100XX_DIAG,
+ (mii->mii_media_active & IFM_FDX) ?
+ ED_DL100XX_COLLISON_DIS : 0);
+ }
+
}
callout_reset(&sc->tick_ch, hz, ed_pccard_tick, sc);
}
@@ -448,6 +468,8 @@ ed_pccard_attach(device_t dev)
if (error != 0)
error = ed_pccard_ax88x90(dev, pp);
if (error != 0)
+ error = ed_pccard_tc5299j(dev, pp);
+ if (error != 0)
error = ed_probe_Novell_generic(dev, device_get_flags(dev));
if (error)
goto bad;
@@ -528,6 +550,14 @@ ed_pccard_attach(device_t dev)
goto bad;
}
+ } else if (sc->chip_type == ED_CHIP_TYPE_TC5299J) {
+ ed_pccard_tc5299j_mii_reset(sc);
+ if ((error = mii_phy_probe(dev, &sc->miibus, ed_ifmedia_upd,
+ ed_ifmedia_sts)) != 0) {
+ device_printf(dev, "Missing mii!\n");
+ goto bad;
+ }
+
}
if (sc->miibus != NULL) {
sc->sc_tick = ed_pccard_tick;
@@ -662,7 +692,7 @@ ed_pccard_dl100xx_mii_readbits(struct ed_softc *sc, int nbits)
DL100XX_MIISET(sc, ED_DL100XX_MII_CLK);
DELAY(10);
val <<= 1;
- if (ed_asic_inb(sc, ED_DL100XX_MIIBUS) & ED_DL100XX_MII_DATATIN)
+ if (ed_asic_inb(sc, ED_DL100XX_MIIBUS) & ED_DL100XX_MII_DATAIN)
val++;
DL100XX_MIICLR(sc, ED_DL100XX_MII_CLK);
DELAY(10);
@@ -740,6 +770,24 @@ ed_pccard_ax88x90(device_t dev, const struct ed_product *pp)
pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE0, iobase & 0xff);
pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE1, (iobase >> 8) & 0xff);
+ ts = "AX88190";
+ if (ed_asic_inb(sc, ED_AX88X90_TEST) != 0) {
+ /*
+ * AX88790 (and I think AX88190A) chips need to be
+ * powered down. There's an erratum that says we should
+ * power down the PHY for 2.5s, but this seems to power
+ * down the whole card. I'm unsure why this was done, but
+ * appears to be required for proper operation.
+ */
+ pccard_ccr_write_1(dev, PCCARD_CCR_STATUS,
+ PCCARD_CCR_STATUS_PWRDWN);
+ /*
+ * Linux axnet driver selects the internal phy for the ax88790
+ */
+ ed_asic_outb(sc, ED_AX88X90_GPIO, ED_AX88X90_GPIO_INT_PHY);
+ ts = "AX88790";
+ }
+
/*
* Check to see if we have a MII PHY ID at any of the first 17
* locations. All AX88x90 devices have MII and a PHY, so we use
@@ -759,20 +807,6 @@ ed_pccard_ax88x90(device_t dev, const struct ed_product *pp)
return (ENXIO);
}
-
- ts = "AX88190";
- if (ed_asic_inb(sc, ED_ASIX_TEST) != 0) {
- /*
- * AX88790 (and I think AX88190A) chips need to be
- * powered down. There's an erratum that says we should
- * power down the PHY for 2.5s, but this seems to power
- * down the whole card. I'm unsure why this was done, but
- * appears to be required for proper operation.
- */
- pccard_ccr_write_1(dev, PCCARD_CCR_STATUS,
- PCCARD_CCR_STATUS_PWRDWN);
- ts = "AX88790";
- }
sc->chip_type = ED_CHIP_TYPE_AX88190;
error = ed_pccard_ax88x90_geteprom(sc);
if (error)
@@ -789,7 +823,7 @@ ed_pccard_ax88x90(device_t dev, const struct ed_product *pp)
return (error);
}
-/* MII bit-twiddling routines for cards using Dlink chipset */
+/* MII bit-twiddling routines for cards using AX88x90 chipset */
#define AX88X90_MIISET(sc, x) ed_asic_outb(sc, ED_AX88X90_MIIBUS, \
ed_asic_inb(sc, ED_AX88X90_MIIBUS) | (x))
#define AX88X90_MIICLR(sc, x) ed_asic_outb(sc, ED_AX88X90_MIIBUS, \
@@ -831,7 +865,7 @@ ed_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits)
AX88X90_MIISET(sc, ED_AX88X90_MII_CLK);
DELAY(10);
val <<= 1;
- if (ed_asic_inb(sc, ED_AX88X90_MIIBUS) & ED_AX88X90_MII_DATATIN)
+ if (ed_asic_inb(sc, ED_AX88X90_MIIBUS) & ED_AX88X90_MII_DATAIN)
val++;
AX88X90_MIICLR(sc, ED_AX88X90_MII_CLK);
DELAY(10);
@@ -840,6 +874,117 @@ ed_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits)
}
/*
+ * Special setup for TC5299J
+ */
+static int
+ed_pccard_tc5299j(device_t dev, const struct ed_product *pp)
+{
+ int error, i, id;
+ char *ts;
+ struct ed_softc *sc = device_get_softc(dev);
+
+ if (!(pp->flags & NE2000DVF_TC5299J))
+ return (ENXIO);
+
+ if (bootverbose)
+ device_printf(dev, "Checking Tc5299j\n");
+
+ /*
+ * Check to see if we have a MII PHY ID at any of the first 32
+ * locations. All TC5299J devices have MII and a PHY, so we use
+ * this to weed out chips that would otherwise make it through
+ * the tests we have after this point.
+ */
+ sc->mii_readbits = ed_pccard_tc5299j_mii_readbits;
+ sc->mii_writebits = ed_pccard_tc5299j_mii_writebits;
+ for (i = 0; i < 32; i++) {
+ id = ed_miibus_readreg(dev, i, MII_PHYIDR1);
+ if (id != 0 && id != 0xffff)
+ break;
+ }
+ if (i == 32) {
+ sc->mii_readbits = 0;
+ sc->mii_writebits = 0;
+ return (ENXIO);
+ }
+
+ ts = "TC5299J";
+ error = ed_probe_Novell_generic(dev, device_get_flags(dev));
+ if (bootverbose)
+ device_printf(dev, "probe novel returns %d\n", error);
+ if (error != 0) {
+ sc->mii_readbits = 0;
+ sc->mii_writebits = 0;
+ return (error);
+ }
+ if (ed_pccard_rom_mac(dev, sc->enaddr) == 0) {
+ sc->mii_readbits = 0;
+ sc->mii_writebits = 0;
+ return (ENXIO);
+ }
+ sc->vendor = ED_VENDOR_NOVELL;
+ sc->type = ED_TYPE_NE2000;
+ sc->chip_type = ED_CHIP_TYPE_TC5299J;
+ sc->type_str = ts;
+ return (0);
+}
+
+/* MII bit-twiddling routines for cards using TC5299J chipset */
+#define TC5299J_MIISET(sc, x) ed_nic_outb(sc, ED_TC5299J_MIIBUS, \
+ ed_nic_inb(sc, ED_TC5299J_MIIBUS) | (x))
+#define TC5299J_MIICLR(sc, x) ed_nic_outb(sc, ED_TC5299J_MIIBUS, \
+ ed_nic_inb(sc, ED_TC5299J_MIIBUS) & ~(x))
+
+static void
+ed_pccard_tc5299j_mii_reset(struct ed_softc *sc)
+{
+ /* Do nothing! */
+}
+
+static void
+ed_pccard_tc5299j_mii_writebits(struct ed_softc *sc, u_int val, int nbits)
+{
+ int i;
+ uint8_t cr;
+
+ cr = ed_nic_inb(sc, ED_P0_CR);
+ ed_nic_outb(sc, ED_P0_CR, cr | ED_CR_PAGE_3);
+
+ TC5299J_MIICLR(sc, ED_TC5299J_MII_DIROUT);
+ for (i = nbits - 1; i >= 0; i--) {
+ if ((val >> i) & 1)
+ TC5299J_MIISET(sc, ED_TC5299J_MII_DATAOUT);
+ else
+ TC5299J_MIICLR(sc, ED_TC5299J_MII_DATAOUT);
+ TC5299J_MIISET(sc, ED_TC5299J_MII_CLK);
+ TC5299J_MIICLR(sc, ED_TC5299J_MII_CLK);
+ }
+ ed_nic_outb(sc, ED_P0_CR, cr);
+}
+
+static u_int
+ed_pccard_tc5299j_mii_readbits(struct ed_softc *sc, int nbits)
+{
+ int i;
+ u_int val = 0;
+ uint8_t cr;
+
+ cr = ed_nic_inb(sc, ED_P0_CR);
+ ed_nic_outb(sc, ED_P0_CR, cr | ED_CR_PAGE_3);
+
+ TC5299J_MIISET(sc, ED_TC5299J_MII_DIROUT);
+ for (i = nbits - 1; i >= 0; i--) {
+ TC5299J_MIISET(sc, ED_TC5299J_MII_CLK);
+ val <<= 1;
+ if (ed_nic_inb(sc, ED_TC5299J_MIIBUS) & ED_TC5299J_MII_DATAIN)
+ val++;
+ TC5299J_MIICLR(sc, ED_TC5299J_MII_CLK);
+ }
+ ed_nic_outb(sc, ED_P0_CR, cr);
+ return val;
+}
+
+/*
* MII bus support routines.
*/
static int
diff --git a/sys/dev/ed/if_ed_pci.c b/sys/dev/ed/if_ed_pci.c
index 2a88576..bdb3e73 100644
--- a/sys/dev/ed/if_ed_pci.c
+++ b/sys/dev/ed/if_ed_pci.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/ed/if_edvar.h>
+#include <dev/ed/rtl80x9reg.h>
static struct _pcsid
{
@@ -48,7 +49,7 @@ static struct _pcsid
const char *desc;
} pci_ids[] =
{
- { 0x802910ec, "RealTek 8029" },
+ { ED_RTL8029_PCI_ID, "RealTek 8029" },
{ 0x50004a14, "NetVin 5000" },
{ 0x09401050, "ProLAN" },
{ 0x140111f6, "Compex" },
@@ -83,7 +84,10 @@ ed_pci_attach(device_t dev)
int flags = 0;
int error;
- error = ed_probe_Novell(dev, PCIR_BAR(0), flags);
+ if (pci_get_devid(dev) == ED_RTL8029_PCI_ID)
+ error = ed_probe_RTL80x9(dev, PCIR_BAR(0), flags);
+ else
+ error = ed_probe_Novell(dev, PCIR_BAR(0), flags);
if (error) {
ed_release_resources(dev);
return (error);
diff --git a/sys/dev/ed/if_ed_rtl80x9.c b/sys/dev/ed/if_ed_rtl80x9.c
new file mode 100644
index 0000000..f2c1a43
--- /dev/null
+++ b/sys/dev/ed/if_ed_rtl80x9.c
@@ -0,0 +1,211 @@
+/*-
+ * Copyright (c) 2003, David Madole
+ * All rights reserved.
+ * Copyright (c) 2005, M. Warner Losh.
+ * 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 unmodified, 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.
+ *
+ * Based on patches subitted by: David Madole, edited by M. Warner Losh.
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ed.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_mib.h>
+#include <net/if_media.h>
+
+#include <net/bpf.h>
+
+#include <dev/ed/if_edreg.h>
+#include <dev/ed/if_edvar.h>
+#include <dev/ed/rtl80x9reg.h>
+
+static int ed_rtl_set_media(struct ifnet *ifp);
+static void ed_rtl_get_media(struct ifnet *ifp, struct ifmediareq *);
+
+static int
+ed_rtl80x9_media_ioctl(struct ed_softc *sc, struct ifreq *ifr, u_long command)
+{
+ return (ifmedia_ioctl(sc->ifp, ifr, &sc->ifmedia, command));
+}
+
+int
+ed_probe_RTL80x9(device_t dev, int port_rid, int flags)
+{
+ struct ed_softc *sc = device_get_softc(dev);
+ int error;
+
+ if ((error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS)))
+ return (error);
+
+ if (!ed_probe_generic8390(sc))
+ return (ENXIO);
+
+ if (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_PS0 | ED_CR_PS1))
+ ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
+
+ if (ed_nic_inb(sc, ED_RTL80X9_80X9ID0) != ED_RTL80X9_ID0)
+ return (ENXIO);
+
+ switch (ed_nic_inb(sc, ED_RTL80X9_80X9ID1)) {
+ case ED_RTL8019_ID1:
+ sc->chip_type = ED_CHIP_TYPE_RTL8019;
+ break;
+ case ED_RTL8029_ID1:
+ sc->chip_type = ED_CHIP_TYPE_RTL8029;
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
+ sc->nic_offset = ED_NOVELL_NIC_OFFSET;
+
+ if ((error = ed_probe_Novell_generic(dev, flags)))
+ return (error);
+
+ sc->sc_media_ioctl = &ed_rtl80x9_media_ioctl;
+ ifmedia_init(&sc->ifmedia, 0, ed_rtl_set_media, ed_rtl_get_media);
+
+ ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, 0);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, 0);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_2, 0, 0);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_5, 0, 0);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, 0);
+
+ ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_3 | ED_CR_STP);
+
+ switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) & ED_RTL80X9_CF2_MEDIA) {
+ case ED_RTL80X9_CF2_AUTO:
+ ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO);
+ break;
+ case ED_RTL80X9_CF2_10_5:
+ ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_5);
+ break;
+ case ED_RTL80X9_CF2_10_2:
+ ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_2);
+ break;
+ case ED_RTL80X9_CF2_10_T:
+ ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T |
+ (ed_nic_inb(sc, ED_RTL80X9_CONFIG3)
+ & ED_RTL80X9_CF3_FUDUP) ? IFM_FDX : 0);
+ break;
+ }
+ return (0);
+}
+
+static int
+ed_rtl_set_media(struct ifnet *ifp)
+{
+ struct ed_softc *sc;
+
+ sc = ifp->if_softc;
+ ED_LOCK(sc);
+ ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3
+ | (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP)));
+
+ switch(IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) {
+ case IFM_10_T:
+ ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_T
+ | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
+ & ~ED_RTL80X9_CF2_MEDIA));
+ break;
+ case IFM_10_2:
+ ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_2
+ | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
+ & ~ED_RTL80X9_CF2_MEDIA));
+ break;
+ case IFM_10_5:
+ ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_5
+ | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
+ & ~ED_RTL80X9_CF2_MEDIA));
+ break;
+ case IFM_AUTO:
+ ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_AUTO
+ | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
+ & ~ED_RTL80X9_CF2_MEDIA));
+ break;
+ }
+ ed_nic_outb(sc, ED_RTL80X9_CONFIG3,
+ (sc->ifmedia.ifm_cur->ifm_media & IFM_FDX) ?
+ (ed_nic_inb(sc, ED_RTL80X9_CONFIG3) | ED_RTL80X9_CF3_FUDUP) :
+ (ed_nic_inb(sc, ED_RTL80X9_CONFIG3) & ~ED_RTL80X9_CF3_FUDUP));
+
+ ED_UNLOCK(sc);
+ return (0);
+}
+
+static void
+ed_rtl_get_media(struct ifnet *ifp, struct ifmediareq *imr)
+{
+ struct ed_softc *sc;
+
+ sc = ifp->if_softc;
+ imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media;
+
+
+ if (IFM_SUBTYPE(imr->ifm_active) == IFM_AUTO) {
+ ED_LOCK(sc);
+ ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 |
+ (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP)));
+
+ switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG0)
+ & (ED_CHIP_TYPE_RTL8029 ? ED_RTL80X9_CF0_BNC
+ : (ED_RTL80X9_CF0_AUI | ED_RTL80X9_CF0_BNC))) {
+ case ED_RTL80X9_CF0_BNC:
+ imr->ifm_active |= IFM_10_2;
+ break;
+ case ED_RTL80X9_CF0_AUI:
+ imr->ifm_active |= IFM_10_5;
+ break;
+ default:
+ imr->ifm_active |= IFM_10_T;
+ break;
+ }
+ ED_UNLOCK(sc);
+ }
+ imr->ifm_status = 0;
+}
+
diff --git a/sys/dev/ed/if_edreg.h b/sys/dev/ed/if_edreg.h
index f73b1e1..3f2b719 100644
--- a/sys/dev/ed/if_edreg.h
+++ b/sys/dev/ed/if_edreg.h
@@ -174,7 +174,7 @@
* 0 0 0
* 0 1 1
* 1 0 2
- * 1 1 reserved
+ * 1 1 3 (some chips it is reserved)
*/
#define ED_CR_PS0 0x40
#define ED_CR_PS1 0x80
@@ -182,6 +182,7 @@
#define ED_CR_PAGE_0 0x00 /* (for consistency) */
#define ED_CR_PAGE_1 0x40
#define ED_CR_PAGE_2 0x80
+#define ED_CR_PAGE_3 0xc0
/*
* Interrupt Status Register (ISR) definitions
@@ -1066,16 +1067,14 @@ struct ed_ring {
* Chip types.
*/
-#define ED_CHIP_TYPE_DP8390 0x00
-#define ED_CHIP_TYPE_WD790 0x01
-#define ED_CHIP_TYPE_AX88190 0x02
-#define ED_CHIP_TYPE_DL10019 0x03
-#define ED_CHIP_TYPE_DL10022 0x04
-
-/*
- * Test for AX88790 vs 88190 cards.
- */
-#define ED_ASIX_TEST 0x05
+#define ED_CHIP_TYPE_DP8390 0
+#define ED_CHIP_TYPE_WD790 1
+#define ED_CHIP_TYPE_AX88190 2
+#define ED_CHIP_TYPE_DL10019 3
+#define ED_CHIP_TYPE_DL10022 4
+#define ED_CHIP_TYPE_TC5299J 5
+#define ED_CHIP_TYPE_RTL8019 6
+#define ED_CHIP_TYPE_RTL8029 7
/*
* MII bus definitions. These are common to both DL100xx and AX88x90
@@ -1095,23 +1094,3 @@ struct ed_ring {
#define ED_MII_DATA_BITS 16
#define ED_MII_ACK_BITS 1
#define ED_MII_IDLE_BITS 1
-
-/* Dlink chipset used on some Netgear and Dlink PCMCIA cards */
-#define ED_DL100XX_MIIBUS 0x0c /* MII bus register on ASIC */
-
-#define ED_DL100XX_MII_RESET1 0x04
-#define ED_DL100XX_MII_RESET2 0x08
-
-#define ED_DL100XX_MII_DATATIN 0x10
-#define ED_DL100XX_MII_DIROUT_22 0x20
-#define ED_DL100XX_MII_DIROUT_19 0x10
-#define ED_DL100XX_MII_DATAOUT 0x40
-#define ED_DL100XX_MII_CLK 0x80
-
-/* AX88x90 based miibus defines */
-#define ED_AX88X90_MIIBUS 0x04 /* MII bus register on ASIC */
-
-#define ED_AX88X90_MII_DATAOUT 0x08
-#define ED_AX88X90_MII_DATATIN 0x04
-#define ED_AX88X90_MII_DIROUT 0x02
-#define ED_AX88X90_MII_CLK 0x01
diff --git a/sys/dev/ed/if_edvar.h b/sys/dev/ed/if_edvar.h
index 4e8afe8..4c9b95b 100644
--- a/sys/dev/ed/if_edvar.h
+++ b/sys/dev/ed/if_edvar.h
@@ -194,6 +194,7 @@ int ed_alloc_irq(device_t, int, int);
int ed_probe_generic8390(struct ed_softc *);
int ed_probe_WD80x3(device_t, int, int);
int ed_probe_WD80x3_generic(device_t, int, uint16_t *[]);
+int ed_probe_RTL80x9(device_t, int, int);
#ifdef ED_3C503
int ed_probe_3Com(device_t, int, int);
#endif
diff --git a/sys/dev/ed/rtl80x9reg.h b/sys/dev/ed/rtl80x9reg.h
new file mode 100644
index 0000000..2120fcf
--- /dev/null
+++ b/sys/dev/ed/rtl80x9reg.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2003, David Madole
+ * All rights reserved.
+ * Copyright (c) 2005, M. Warner Losh.
+ * 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 unmodified, 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.
+ *
+ * Based on patches subitted by: David Madole, edited by M. Warner Losh.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * RTL8019/8029 Specific Registers
+ */
+
+#define ED_RTL80X9_CONFIG0 0x03
+#define ED_RTL80X9_CONFIG2 0x05
+#define ED_RTL80X9_CONFIG3 0x06
+#define ED_RTL80X9_80X9ID0 0x0a
+#define ED_RTL80X9_ID0 0x50
+#define ED_RTL80X9_80X9ID1 0x0b
+#define ED_RTL8019_ID1 0x70
+#define ED_RTL8029_ID1 0x43
+
+#define ED_RTL80X9_CF0_BNC 0x04
+#define ED_RTL80X9_CF0_AUI 0x20
+
+#define ED_RTL80X9_CF2_MEDIA 0xc0
+#define ED_RTL80X9_CF2_AUTO 0x00
+#define ED_RTL80X9_CF2_10_T 0x40
+#define ED_RTL80X9_CF2_10_5 0x80
+#define ED_RTL80X9_CF2_10_2 0xc0
+
+#define ED_RTL80X9_CF3_FUDUP 0x40
+
+#define ED_RTL8029_PCI_ID 0x802910ec
diff --git a/sys/dev/ed/tc5299jreg.h b/sys/dev/ed/tc5299jreg.h
new file mode 100644
index 0000000..6fb7939
--- /dev/null
+++ b/sys/dev/ed/tc5299jreg.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2005, M. Warner Losh.
+ * 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 unmodified, 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$
+ */
+
+/* Tamarack TC5299J */
+#define ED_TC5299J_CRA 0x0a /* Config Register A */
+#define ED_TC5299J_CRB 0x0b /* Config Register B */
+#define ED_TC5299J_MIIBUS 0x03 /* MII bus register on in bank 3 */
+
+#define ED_TC5299J_MII_CLK 0x01
+#define ED_TC5299J_MII_DATAOUT 0x02
+#define ED_TC5299J_MII_DIROUT 0x04
+#define ED_TC5299J_MII_DATAIN 0x08
OpenPOWER on IntegriCloud