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
This commit is contained in:
Warner Losh 2005-10-05 05:21:07 +00:00
parent 97fb6f6f5d
commit 95a2adef58
10 changed files with 591 additions and 67 deletions

38
sys/dev/ed/ax88x90reg.h Normal file
View File

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

42
sys/dev/ed/dl100xxreg.h Normal file
View File

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

View File

@ -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;

View File

@ -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);
}
@ -447,6 +467,8 @@ ed_pccard_attach(device_t dev)
error = ed_pccard_dl100xx(dev, pp);
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)
@ -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);
@ -839,6 +873,117 @@ ed_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits)
return val;
}
/*
* 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.
*/

View File

@ -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,6 +84,9 @@ ed_pci_attach(device_t dev)
int flags = 0;
int error;
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);

211
sys/dev/ed/if_ed_rtl80x9.c Normal file
View File

@ -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;
}

View File

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

View File

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

58
sys/dev/ed/rtl80x9reg.h Normal file
View File

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

38
sys/dev/ed/tc5299jreg.h Normal file
View File

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