Remove IFF_LINK[01] "connector" support.
Add if_media support. Still missing a software autosense FSM.
This commit is contained in:
parent
90789b53dd
commit
f11d74c508
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: elink3.c,v 1.22 1997/03/30 22:47:10 jonathan Exp $ */
|
||||
/* $NetBSD: elink3.c,v 1.23 1997/04/07 23:49:47 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Jonathan Stone <jonathan@NetBSD.org>
|
||||
@ -77,13 +77,78 @@
|
||||
#define ETHER_MAX_LEN 1518
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
/*
|
||||
* Structure to map media-present bits in boards to
|
||||
* ifmedia codes and printable media names. Used for table-driven
|
||||
* ifmedia initialization.
|
||||
*/
|
||||
struct ep_media {
|
||||
int epm_eeprom_data; /* bitmask for eeprom config */
|
||||
int epm_conn; /* sc->ep_connectors code for medium */
|
||||
char* epm_name; /* name of medium */
|
||||
int epm_ifmedia; /* ifmedia word for medium */
|
||||
int epm_ifdata;
|
||||
};
|
||||
|
||||
/*
|
||||
* ep_media table for Vortex/Demon/Boomerang:
|
||||
* map from media-present bits in register RESET_OPTIONS+2
|
||||
* to ifmedia "media words" and printable names.
|
||||
*
|
||||
* XXX indexed directly by INTERNAL_CONFIG default_media field,
|
||||
* (i.e., EPMEDIA_ constants) forcing order of entries.
|
||||
* Note that 3 is reserved.
|
||||
*/
|
||||
struct ep_media ep_vortex_media[8] = {
|
||||
{ EP_PCI_UTP, EPC_UTP, "utp", IFM_ETHER|IFM_10_T,
|
||||
EPMEDIA_10BASE_T },
|
||||
{ EP_PCI_AUI, EPC_AUI, "aui", IFM_ETHER|IFM_10_5,
|
||||
EPMEDIA_AUI },
|
||||
{ 0, 0, "reserved", IFM_NONE, EPMEDIA_RESV1 },
|
||||
{ EP_PCI_BNC, EPC_BNC, "bnc", IFM_ETHER|IFM_10_2,
|
||||
EPMEDIA_10BASE_2 },
|
||||
{ EP_PCI_100BASE_TX, EPC_100TX, "100-TX", IFM_ETHER|IFM_100_TX,
|
||||
EPMEDIA_100BASE_TX },
|
||||
{ EP_PCI_100BASE_FX, EPC_100FX, "100-FX", IFM_ETHER|IFM_100_FX,
|
||||
EPMEDIA_100BASE_FX },
|
||||
{ EP_PCI_100BASE_MII,EPC_MII, "mii", IFM_ETHER|IFM_100_TX,
|
||||
EPMEDIA_MII },
|
||||
{ EP_PCI_100BASE_T4, EPC_100T4, "100-T4", IFM_ETHER|IFM_100_T4,
|
||||
EPMEDIA_100BASE_T4 }
|
||||
};
|
||||
|
||||
/*
|
||||
* ep_media table for 3c509/3c509b/3c579/3c589:
|
||||
* map from media-present bits in register CNFG_CNTRL
|
||||
* (window 0, offset ?) to ifmedia "media words" and printable names.
|
||||
*/
|
||||
struct ep_media ep_isa_media[3] = {
|
||||
{ EP_W0_CC_UTP, EPC_UTP, "utp", IFM_ETHER|IFM_10_T, EPMEDIA_10BASE_T },
|
||||
{ EP_W0_CC_AUI, EPC_AUI, "aui", IFM_ETHER|IFM_10_5, EPMEDIA_AUI },
|
||||
{ EP_W0_CC_BNC, EPC_BNC, "bnc", IFM_ETHER|IFM_10_2, EPMEDIA_10BASE_2 },
|
||||
};
|
||||
|
||||
/* Map vortex reset_options bits to if_media codes. */
|
||||
const u_int ep_default_to_media[8] = {
|
||||
IFM_ETHER | IFM_10_T,
|
||||
IFM_ETHER | IFM_10_5,
|
||||
0, /* reserved by 3Com */
|
||||
IFM_ETHER | IFM_10_2,
|
||||
IFM_ETHER | IFM_100_TX,
|
||||
IFM_ETHER | IFM_100_FX,
|
||||
IFM_ETHER | IFM_100_TX, /* XXX really MII: need to talk to PHY */
|
||||
IFM_ETHER | IFM_100_T4,
|
||||
};
|
||||
|
||||
/* Autoconfig defintion of driver back-end */
|
||||
struct cfdriver ep_cd = {
|
||||
NULL, "ep", DV_IFNET
|
||||
};
|
||||
|
||||
|
||||
void ep_internalconfig __P((struct ep_softc *sc));
|
||||
void ep_vortex_probemedia __P((struct ep_softc *sc));
|
||||
void ep_default_probemedia __P((struct ep_softc *sc));
|
||||
void ep_isa_probemedia __P((struct ep_softc *sc));
|
||||
|
||||
static void eptxstat __P((struct ep_softc *));
|
||||
static int epstatus __P((struct ep_softc *));
|
||||
@ -93,12 +158,16 @@ void epstart __P((struct ifnet *));
|
||||
void epwatchdog __P((struct ifnet *));
|
||||
void epreset __P((struct ep_softc *));
|
||||
static void epshutdown __P((void *));
|
||||
void epread __P((struct ep_softc *));
|
||||
void epread __P((struct ep_softc *));
|
||||
struct mbuf *epget __P((struct ep_softc *, int));
|
||||
void epmbuffill __P((void *));
|
||||
void epmbufempty __P((struct ep_softc *));
|
||||
void epsetfilter __P((struct ep_softc *));
|
||||
void epsetlink __P((struct ep_softc *));
|
||||
void epmbuffill __P((void *));
|
||||
void epmbufempty __P((struct ep_softc *));
|
||||
void epsetfilter __P((struct ep_softc *));
|
||||
int epsetmedia __P((struct ep_softc *, int epmedium));
|
||||
|
||||
/* ifmedia callbacks */
|
||||
int ep_media_change __P((struct ifnet *ifp));
|
||||
void ep_media_status __P((struct ifnet *ifp, struct ifmediareq *req));
|
||||
|
||||
static int epbusyeeprom __P((struct ep_softc *));
|
||||
static inline void ep_complete_cmd __P((struct ep_softc *sc,
|
||||
@ -148,13 +217,6 @@ epconfig(sc, chipset)
|
||||
u_int16_t i;
|
||||
u_int8_t myla[6];
|
||||
|
||||
printf("%s: ", sc->sc_dev.dv_xname);
|
||||
|
||||
|
||||
/* print RAM size */
|
||||
ep_internalconfig(sc);
|
||||
GO_WINDOW(0);
|
||||
|
||||
sc->ep_chipset = chipset;
|
||||
|
||||
/*
|
||||
@ -163,22 +225,24 @@ epconfig(sc, chipset)
|
||||
for (i = 0; i < 3; i++) {
|
||||
u_int16_t x;
|
||||
if (epbusyeeprom(sc))
|
||||
return;
|
||||
return; /* XXX why is eeprom busy? */
|
||||
bus_space_write_2(iot, ioh, EP_W0_EEPROM_COMMAND,
|
||||
READ_EEPROM | i);
|
||||
if (epbusyeeprom(sc))
|
||||
return;
|
||||
return; /* XXX why is eeprom busy? */
|
||||
x = bus_space_read_2(iot, ioh, EP_W0_EEPROM_DATA);
|
||||
myla[(i << 1)] = x >> 8;
|
||||
myla[(i << 1) + 1] = x;
|
||||
}
|
||||
|
||||
printf("MAC address %s\n", ether_sprintf(myla));
|
||||
printf("%s: MAC address %s\n", sc->sc_dev.dv_xname,
|
||||
ether_sprintf(myla));
|
||||
|
||||
/*
|
||||
* Vortex-based (3c59x, eisa)? and Boomerang (3c900)cards allow
|
||||
* FDDI-sized (4500) byte packets. Commands only take an 11-bit
|
||||
* parameter, and 11 bits isn't enough to hold a full-size pkt length.
|
||||
* Vortex-based (3c59x pci,eisa) and Boomerang (3c900,3c515?) cards
|
||||
* allow FDDI-sized (4500) byte packets. Commands only take an
|
||||
* 11-bit parameter, and 11 bits isn't enough to hold a full-size
|
||||
* packet length.
|
||||
* Commands to these cards implicitly upshift a packet size
|
||||
* or threshold by 2 bits.
|
||||
* To detect cards with large-packet support, we probe by setting
|
||||
@ -199,7 +263,7 @@ epconfig(sc, chipset)
|
||||
|
||||
case (EP_LARGEWIN_PROBE << 2):
|
||||
sc->ep_pktlenshift = 2;
|
||||
/* XXX do 3c579, 3c515 support Vortex-style RESET_OPTIONS? */
|
||||
/* XXX does the 3c515 support Vortex-style RESET_OPTIONS? */
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -212,26 +276,49 @@ epconfig(sc, chipset)
|
||||
/*
|
||||
* Ensure Tx-available interrupts are enabled for
|
||||
* start the interface.
|
||||
* XXX should be in epinit().
|
||||
* XXX should be in epinit()?
|
||||
*/
|
||||
bus_space_write_2(iot, ioh, EP_COMMAND,
|
||||
SET_TX_AVAIL_THRESH | (1600 >> sc->ep_pktlenshift));
|
||||
|
||||
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
|
||||
ifp->if_softc = sc;
|
||||
ifp->if_start = epstart;
|
||||
ifp->if_ioctl = epioctl;
|
||||
ifp->if_watchdog = epwatchdog;
|
||||
ifp->if_flags =
|
||||
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
|
||||
|
||||
if_attach(ifp);
|
||||
ether_ifattach(ifp, myla);
|
||||
|
||||
/*
|
||||
* Finish configuration:
|
||||
* determine chipset if the front-end couldn't do so,
|
||||
* show board details, set media.
|
||||
*/
|
||||
|
||||
/* print RAM size */
|
||||
ep_internalconfig(sc);
|
||||
GO_WINDOW(0);
|
||||
|
||||
ifmedia_init(&sc->sc_media, 0, ep_media_change, ep_media_status);
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* If we've got an indirect (ISA, PCMCIA?) board, the chipset
|
||||
* is unknown. If the board has large-packet support, it's a
|
||||
* Vortex/Boomerang, otherwise it's a 3c509.
|
||||
* XXX use eeprom capability word instead?
|
||||
*/
|
||||
if (sc->sc_chipset == EP_CHIPSET_UNKNOWN && sc->ep_pktlenshift) {
|
||||
if (sc->ep_chipset == EP_CHIPSET_UNKNOWN && sc->ep_pktlenshift) {
|
||||
printf("warning: unknown chipset, possibly 3c515?\n");
|
||||
#ifdef notyet
|
||||
sc->sc_chipset = EP_CHIPSET_VORTEX;
|
||||
}
|
||||
#endif /* notyet */
|
||||
}
|
||||
|
||||
/*
|
||||
* Ascertain which media types are present.
|
||||
* Ascertain which media types are present and inform ifmedia.
|
||||
*/
|
||||
switch (sc->ep_chipset) {
|
||||
/* on a direct bus, the attach routine can tell, but check anyway. */
|
||||
@ -243,23 +330,12 @@ epconfig(sc, chipset)
|
||||
/* on ISA we can't yet tell 3c509 from 3c515. Assume the former. */
|
||||
case EP_CHIPSET_3C509:
|
||||
default:
|
||||
ep_default_probemedia(sc);
|
||||
ep_isa_probemedia(sc);
|
||||
break;
|
||||
}
|
||||
|
||||
GO_WINDOW(1); /* Window 1 is operating window */
|
||||
|
||||
|
||||
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
|
||||
ifp->if_softc = sc;
|
||||
ifp->if_start = epstart;
|
||||
ifp->if_ioctl = epioctl;
|
||||
ifp->if_watchdog = epwatchdog;
|
||||
ifp->if_flags =
|
||||
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
|
||||
|
||||
if_attach(ifp);
|
||||
ether_ifattach(ifp, myla);
|
||||
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->sc_ethercom.ec_if.if_bpf, ifp, DLT_EN10MB,
|
||||
sizeof(struct ether_header));
|
||||
@ -274,6 +350,7 @@ epconfig(sc, chipset)
|
||||
ep_complete_cmd(sc, EP_COMMAND, TX_RESET);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Show interface-model-independent info from window 3
|
||||
* internal-configuration register.
|
||||
@ -308,45 +385,77 @@ ep_internalconfig(sc)
|
||||
|
||||
ram_split = (config1 & CONFIG_RAMSPLIT) >> CONFIG_RAMSPLIT_SHIFT;
|
||||
|
||||
printf("%dKB %s-wide FIFO, %s Rx:Tx split, ",
|
||||
8 << ram_size,
|
||||
(ram_width) ? "word" : "byte",
|
||||
onboard_ram_config[ram_split]);
|
||||
printf("%s: %dKB %s-wide FIFO, %s Rx:Tx split, ",
|
||||
sc->sc_dev.dv_xname,
|
||||
8 << ram_size,
|
||||
(ram_width) ? "word" : "byte",
|
||||
onboard_ram_config[ram_split]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find media present on 3c509-generation hardware that doesn't have
|
||||
* Find supported media on 3c509-generation hardware that doesn't have
|
||||
* a "reset_options" register in window 3.
|
||||
* Use the config_cntrl register in window 0.
|
||||
* XXX ifmedia?
|
||||
* Use the config_cntrl register in window 0 instead.
|
||||
* Used on original, 10Mbit ISA (3c509), 3c509B, and pre-Demon EISA cards
|
||||
* that implement CONFIG_CTRL. We don't have a good way to set the
|
||||
* default active mediuim; punt to ifconfig instead.
|
||||
*
|
||||
* XXX what about 3c515, pcmcia 10/100?
|
||||
*/
|
||||
void
|
||||
ep_default_probemedia(sc)
|
||||
ep_isa_probemedia(sc)
|
||||
struct ep_softc *sc;
|
||||
{
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
bus_space_handle_t ioh = sc->sc_ioh;
|
||||
int conn;
|
||||
struct ifmedia *ifm = &sc->sc_media;
|
||||
|
||||
int conn, i;
|
||||
u_int16_t ep_w0_config, port;
|
||||
|
||||
conn = 0;
|
||||
GO_WINDOW(0);
|
||||
conn = bus_space_read_2(iot, ioh, EP_W0_CONFIG_CTRL);
|
||||
if (conn & IS_AUI)
|
||||
sc->ep_connectors |= AUI;
|
||||
if (conn & IS_BNC)
|
||||
sc->ep_connectors |= BNC;
|
||||
if (conn & IS_UTP)
|
||||
sc->ep_connectors |= UTP;
|
||||
ep_w0_config = bus_space_read_2(iot, ioh, EP_W0_CONFIG_CTRL);
|
||||
for (i = 0; i < 3; i++) {
|
||||
struct ep_media * epm = ep_isa_media + i;
|
||||
|
||||
if ((ep_w0_config & epm->epm_eeprom_data) != 0) {
|
||||
|
||||
ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_ifdata, 0);
|
||||
if (conn)
|
||||
printf("/");
|
||||
printf(epm->epm_name);
|
||||
conn |= epm->epm_conn;
|
||||
}
|
||||
}
|
||||
sc->ep_connectors = conn;
|
||||
|
||||
/* get default medium from EEPROM */
|
||||
if (epbusyeeprom(sc))
|
||||
return; /* XXX why is eeprom busy? */
|
||||
bus_space_write_2(iot, ioh, EP_W0_EEPROM_COMMAND,
|
||||
READ_EEPROM | 8);
|
||||
if (epbusyeeprom(sc))
|
||||
return; /* XXX why is eeprom busy? */
|
||||
port = bus_space_read_2(iot, ioh, EP_W0_EEPROM_DATA);
|
||||
port = port >> 14;
|
||||
|
||||
printf(" (default %s)\n", ep_vortex_media[port].epm_name);
|
||||
/* tell ifconfig what currently-active media is. */
|
||||
ifmedia_set(ifm, ep_default_to_media[port]);
|
||||
|
||||
/* XXX autoselect not yet implemented */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find media present on large-packet-capable elink3 devices (Demon,
|
||||
* Vortex, Boomerang), using media and card-version info in window 3.
|
||||
* Find media present on large-packet-capable elink3 devices.
|
||||
* Show onboard configuration of large-packet-capable elink3 devices
|
||||
* (Demon, Vortex, Boomerang), which do not implement CONFIG_CTRL in window 0.
|
||||
* Use media and card-version info in window 3 instead.
|
||||
*
|
||||
* XXX How much of this works with 3c515, pcmcia 10/100? With 3c509, 3c589?
|
||||
* XXX Be noisy about what's present, as NetBSD provides no way to
|
||||
* change media. You need to run the vendor config utility under DOS.
|
||||
* XXX ifmedia?
|
||||
* XXX how much of this works with 3c515, pcmcia 10/100? With 3c509B, 3c589?
|
||||
*/
|
||||
void
|
||||
ep_vortex_probemedia(sc)
|
||||
@ -354,58 +463,59 @@ ep_vortex_probemedia(sc)
|
||||
{
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
bus_space_handle_t ioh = sc->sc_ioh;
|
||||
u_int config0;
|
||||
struct ifmedia *ifm = &sc->sc_media;
|
||||
|
||||
u_int config1;
|
||||
int reset_options;
|
||||
int conn;
|
||||
u_int conn = 0;
|
||||
|
||||
int default_media; /* 3-bit encoding of default (EEPROM) media */
|
||||
int autoselect; /* boolean: should default to autoselect */
|
||||
|
||||
|
||||
int defmedia, autoselect;
|
||||
/* Names for media in the media bitmask field. */
|
||||
const char *medium_name;
|
||||
const char *media_names[8] ={
|
||||
"10baseT",
|
||||
"10base AUI",
|
||||
"undefined",
|
||||
"10base2",
|
||||
"100baseTX",
|
||||
"100baseFX",
|
||||
"MII",
|
||||
"100baseT4"};
|
||||
register int i;
|
||||
|
||||
GO_WINDOW(3);
|
||||
config0 = (u_int)bus_space_read_2(iot, ioh, EP_W3_INTERNAL_CONFIG);
|
||||
config1 = (u_int)bus_space_read_2(iot, ioh, EP_W3_INTERNAL_CONFIG+2);
|
||||
reset_options = (int)bus_space_read_1(iot, ioh, EP_W3_RESET_OPTIONS);
|
||||
GO_WINDOW(0);
|
||||
|
||||
|
||||
defmedia = (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
|
||||
default_media = (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
|
||||
autoselect = (config1 & CONFIG_AUTOSELECT) >> CONFIG_AUTOSELECT_SHIFT;
|
||||
|
||||
medium_name = (defmedia > 8) ? "(unknown/impossible media)"
|
||||
: media_names[defmedia];
|
||||
/* set available media options */
|
||||
for (i = 0; i < 8; i++) {
|
||||
struct ep_media * epm = ep_vortex_media + i;
|
||||
|
||||
conn = 0;
|
||||
if (reset_options & IS_PCI_AUI)
|
||||
conn |= AUI;
|
||||
if (reset_options & IS_PCI_BNC)
|
||||
conn |= BNC;
|
||||
if (reset_options & IS_PCI_UTP)
|
||||
conn |= UTP;
|
||||
if (reset_options & IS_PCI_100BASE_TX)
|
||||
conn |= TX;
|
||||
if (reset_options & IS_PCI_100BASE_T4)
|
||||
conn |= T4;
|
||||
if (reset_options & IS_PCI_100BASE_FX)
|
||||
conn |= FX;
|
||||
if (reset_options & IS_PCI_100BASE_MII)
|
||||
conn |= MII;
|
||||
if ((reset_options & epm->epm_eeprom_data) != 0) {
|
||||
if (conn) printf("/");
|
||||
printf(epm->epm_name);
|
||||
conn |= epm->epm_conn;
|
||||
ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_ifdata, 0);
|
||||
}
|
||||
}
|
||||
|
||||
sc->ep_connectors = conn;
|
||||
|
||||
printf("%s: default medium %s, autoselect %s\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
medium_name, (autoselect)? "on" : "off" );
|
||||
/* Show eeprom's idea of default media. */
|
||||
medium_name = (default_media > 8)
|
||||
? "(unknown/impossible media)"
|
||||
: ep_vortex_media[default_media].epm_name;
|
||||
printf(" default %s%s\n",
|
||||
medium_name, (autoselect)? ", autoselect" : "" );
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Set default: either the active interface the card
|
||||
* reads from the EEPROM, or if autoselect is true,
|
||||
* whatever we find is actually connected.
|
||||
*
|
||||
* XXX autoselect not yet implemented.
|
||||
*/
|
||||
#endif /* notyet */
|
||||
|
||||
/* tell ifconfig what currently-active media is. */
|
||||
ifmedia_set(ifm, ep_default_to_media[default_media]);
|
||||
}
|
||||
|
||||
|
||||
@ -476,7 +586,7 @@ epinit(sc)
|
||||
bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR | 0xff);
|
||||
|
||||
epsetfilter(sc);
|
||||
epsetlink(sc);
|
||||
epsetmedia(sc, sc->sc_media.ifm_cur->ifm_data);
|
||||
|
||||
bus_space_write_2(iot, ioh, EP_COMMAND, RX_ENABLE);
|
||||
bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
|
||||
@ -511,53 +621,203 @@ epsetfilter(sc)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Select media based on link{0,1,2} switches.
|
||||
* Assumes 10Mbit interface, totatlly broken for 10/100 adaptors.
|
||||
*/
|
||||
void
|
||||
epsetlink(sc)
|
||||
register struct ep_softc *sc;
|
||||
int
|
||||
ep_media_change(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
register struct ep_softc *sc = ifp->if_softc;
|
||||
|
||||
return epsetmedia(sc, sc->sc_media.ifm_cur->ifm_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set active media to a specific given EPMEDIA_<> value.
|
||||
* For dumb 3c509 cards, just power on the selected transceiver.
|
||||
* For vortex/demon/boomerang cards, update media field in w3_internal_config,
|
||||
* and power on selected transciever.
|
||||
* for pcmcia cards, update media field in w0_address_config.
|
||||
* and power on selected transciever.
|
||||
*/
|
||||
int
|
||||
epsetmedia(sc, medium)
|
||||
register struct ep_softc *sc;
|
||||
int medium;
|
||||
{
|
||||
register struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
bus_space_handle_t ioh = sc->sc_ioh;
|
||||
int config0, config1;
|
||||
int w4_media;
|
||||
int port;
|
||||
|
||||
port = sc->sc_media.ifm_cur->ifm_data;
|
||||
|
||||
|
||||
/*
|
||||
* you can `ifconfig (link0|-link0) ep0' to get the following
|
||||
* behaviour:
|
||||
* -link0 disable AUI/UTP. enable BNC.
|
||||
* link0 disable BNC. enable AUI.
|
||||
* link1 if the card has a UTP connector, and link0 is
|
||||
* set too, then you get the UTP port.
|
||||
* First, change the media-control bits in EP_W4_MEDIA_TYPE.
|
||||
*/
|
||||
|
||||
/* Turn everything off. First turn off linkbeat and UTP. */
|
||||
GO_WINDOW(4);
|
||||
bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE, DISABLE_UTP);
|
||||
if (!(ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & BNC)) {
|
||||
if (sc->bustype == EP_BUS_PCMCIA) {
|
||||
GO_WINDOW(0);
|
||||
bus_space_write_2(iot, ioh, EP_W0_ADDRESS_CFG,3<<14);
|
||||
GO_WINDOW(1);
|
||||
w4_media = bus_space_read_2(iot, ioh, EP_W4_MEDIA_TYPE);
|
||||
w4_media = w4_media & ~(ENABLE_UTP|SQE_ENABLE);
|
||||
bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE, w4_media);
|
||||
|
||||
/* Turn off coax */
|
||||
bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
|
||||
delay(1000);
|
||||
|
||||
/* If pcmcia, do the pcmcia media (power?) dance. */
|
||||
if (sc->bustype == EP_BUS_PCMCIA) {
|
||||
GO_WINDOW(0);
|
||||
switch (medium) {
|
||||
case EPMEDIA_10BASE_T:
|
||||
bus_space_write_2(iot, ioh,
|
||||
EP_W0_ADDRESS_CFG,0<<14);
|
||||
DELAY(1000);
|
||||
break;
|
||||
|
||||
case EPMEDIA_10BASE_2:
|
||||
bus_space_write_2(iot, ioh,
|
||||
EP_W0_ADDRESS_CFG,3<<14);
|
||||
DELAY(1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now turn on the selected media/transciever. */
|
||||
GO_WINDOW(4);
|
||||
switch (medium) {
|
||||
case EPMEDIA_10BASE_T:
|
||||
bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE,
|
||||
w4_media | ENABLE_UTP);
|
||||
break;
|
||||
|
||||
case EPMEDIA_10BASE_2:
|
||||
bus_space_write_2(iot, ioh, EP_COMMAND, START_TRANSCEIVER);
|
||||
delay(1000);
|
||||
DELAY(1000); /* 50ms not enmough? */
|
||||
break;
|
||||
|
||||
/* XXX following only for new-generation cards */
|
||||
case EPMEDIA_100BASE_TX:
|
||||
case EPMEDIA_100BASE_FX:
|
||||
case EPMEDIA_100BASE_T4: /* XXX check documentation */
|
||||
bus_space_write_2(iot, ioh,
|
||||
EP_W4_MEDIA_TYPE, w4_media | LINKBEAT_ENABLE);
|
||||
DELAY(1000); /* not strictly necessary? */
|
||||
break;
|
||||
|
||||
case EPMEDIA_AUI:
|
||||
/* we already did everything necessary. */
|
||||
bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE,
|
||||
w4_media | SQE_ENABLE);
|
||||
DELAY(1000); /* not strictly necessary? */
|
||||
break;
|
||||
case EPMEDIA_MII:
|
||||
break;
|
||||
default:
|
||||
#if defined(DEBUG)
|
||||
printf("%s uknown medium 0x%x\n",
|
||||
sc->sc_dev.dv_xname, medium);
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
if (ifp->if_flags & IFF_LINK0) {
|
||||
bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
|
||||
delay(1000);
|
||||
if ((ifp->if_flags & IFF_LINK1) && (sc->ep_connectors & UTP)) {
|
||||
if (sc->bustype == EP_BUS_PCMCIA) {
|
||||
GO_WINDOW(0);
|
||||
bus_space_write_2(iot, ioh,
|
||||
EP_W0_ADDRESS_CFG,0<<14);
|
||||
GO_WINDOW(4);
|
||||
}
|
||||
bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE, ENABLE_UTP);
|
||||
}
|
||||
|
||||
/*
|
||||
* For Vortex/Demon/Boomerang, tell the chip which PHY [sic] to use.
|
||||
*/
|
||||
if (sc->ep_chipset==EP_CHIPSET_VORTEX ||
|
||||
sc->ep_chipset==EP_CHIPSET_BOOMERANG2) {
|
||||
|
||||
GO_WINDOW(3);
|
||||
config0 = (u_int)bus_space_read_2(iot, ioh,
|
||||
EP_W3_INTERNAL_CONFIG);
|
||||
config1 = (u_int)bus_space_read_2(iot, ioh,
|
||||
EP_W3_INTERNAL_CONFIG+2);
|
||||
|
||||
#if defined(DEBUG)
|
||||
printf("%s: read 0x%x, 0x%x from EP_W3_CONFIG register\n",
|
||||
sc->sc_dev.dv_xname, config0, config1);
|
||||
#endif
|
||||
config1 = config1 & ~CONFIG_MEDIAMASK;
|
||||
config1 |= (medium << CONFIG_MEDIAMASK_SHIFT);
|
||||
|
||||
#if defined(DEBUG)
|
||||
printf("epsetmedia: %s: medium 0x%x, 0x%x to EP_W3_CONFIG\n",
|
||||
sc->sc_dev.dv_xname, medium, config1);
|
||||
#endif
|
||||
bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG,
|
||||
config0);
|
||||
bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG+2,
|
||||
config1);
|
||||
}
|
||||
GO_WINDOW(1);
|
||||
|
||||
GO_WINDOW(1); /* Window 1 is operating window */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get currently-selected media from card.
|
||||
* (if_media callback, may be called before interface is brought up).
|
||||
*/
|
||||
void
|
||||
ep_media_status(ifp, req)
|
||||
struct ifnet *ifp;
|
||||
struct ifmediareq *req;
|
||||
{
|
||||
register struct ep_softc *sc = ifp->if_softc;
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
bus_space_handle_t ioh = sc->sc_ioh;
|
||||
u_int config1 = 0;
|
||||
u_int ep_mediastatus;
|
||||
|
||||
/* XXX read from softc when we start autosensing media */
|
||||
req->ifm_active = sc->sc_media.ifm_cur->ifm_media;
|
||||
|
||||
switch (sc->ep_chipset) {
|
||||
case EP_CHIPSET_VORTEX:
|
||||
case EP_CHIPSET_BOOMERANG:
|
||||
GO_WINDOW(3);
|
||||
delay(5000);
|
||||
|
||||
config1 = bus_space_read_2(iot, ioh, EP_W3_INTERNAL_CONFIG+2);
|
||||
GO_WINDOW(1);
|
||||
|
||||
|
||||
config1 =
|
||||
(config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
|
||||
req->ifm_active = ep_default_to_media[config1];
|
||||
|
||||
/* XXX check full-duplex bits? */
|
||||
|
||||
GO_WINDOW(4);
|
||||
req->ifm_status = IFM_AVALID; /* XXX */
|
||||
ep_mediastatus = bus_space_read_2(iot, ioh, EP_W4_MEDIA_TYPE);
|
||||
if (ep_mediastatus & LINKBEAT_DETECT)
|
||||
req->ifm_status |= IFM_ACTIVE; /* XXX automedia */
|
||||
|
||||
break;
|
||||
|
||||
case EP_CHIPSET_UNKNOWN:
|
||||
case EP_CHIPSET_3C509:
|
||||
req->ifm_status = 0; /* XXX */
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("%s: media_status on unknown chipset 0x%x\n",
|
||||
ifp->if_xname, sc->ep_chipset);
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX look for softc heartbeat for other chips or media */
|
||||
|
||||
GO_WINDOW(1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Start outputting on the interface.
|
||||
* Always called as splnet().
|
||||
@ -1179,6 +1439,11 @@ epioctl(ifp, cmd, data)
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCSIFMEDIA:
|
||||
case SIOCGIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
|
||||
break;
|
||||
|
||||
case SIOCSIFFLAGS:
|
||||
if ((ifp->if_flags & IFF_UP) == 0 &&
|
||||
(ifp->if_flags & IFF_RUNNING) != 0) {
|
||||
@ -1198,11 +1463,9 @@ epioctl(ifp, cmd, data)
|
||||
} else {
|
||||
/*
|
||||
* deal with flags changes:
|
||||
* IFF_MULTICAST, IFF_PROMISC,
|
||||
* IFF_LINK0, IFF_LINK1,
|
||||
* IFF_MULTICAST, IFF_PROMISC.
|
||||
*/
|
||||
epsetfilter(sc);
|
||||
epsetlink(sc);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1294,7 +1557,6 @@ epshutdown(arg)
|
||||
ep_complete_cmd(sc, EP_COMMAND, GLOBAL_RESET);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We get eeprom data from the id_port given an offset into the
|
||||
* eeprom. Basically; after the ID_sequence is sent to all of
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: elink3reg.h,v 1.11 1996/12/30 19:18:30 jonathan Exp $ */
|
||||
/* $NetBSD: elink3reg.h,v 1.12 1997/04/07 23:49:48 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Herb Peyerl <hpeyerl@beer.org>
|
||||
@ -185,14 +185,11 @@
|
||||
#define TX_RESET (u_short) (0xb<<11)
|
||||
#define REQ_INTR (u_short) (0xc<<11)
|
||||
|
||||
/* busmastering-cards only? */
|
||||
#define STATUS_ENABLE (u_short) (0xf<<11)
|
||||
|
||||
/*
|
||||
* The following C_* acknowledge the various interrupts.
|
||||
* Some of them don't do anything. See the manual.
|
||||
*/
|
||||
#define ACK_INTR (u_short) (0x6800)
|
||||
#define ACK_INTR (u_short) (0xd << 11)
|
||||
# define C_INTR_LATCH (u_short) (ACK_INTR|0x01)
|
||||
# define C_CARD_FAILURE (u_short) (ACK_INTR|0x02)
|
||||
# define C_TX_COMPLETE (u_short) (ACK_INTR|0x04)
|
||||
@ -201,17 +198,26 @@
|
||||
# define C_RX_EARLY (u_short) (ACK_INTR|0x20)
|
||||
# define C_INT_RQD (u_short) (ACK_INTR|0x40)
|
||||
# define C_UPD_STATS (u_short) (ACK_INTR|0x80)
|
||||
|
||||
#define SET_INTR_MASK (u_short) (0x0e<<11)
|
||||
|
||||
/* busmastering-cards only? */
|
||||
#define STATUS_ENABLE (u_short) (0xf<<11)
|
||||
|
||||
#define SET_RD_0_MASK (u_short) (0x0f<<11)
|
||||
|
||||
#define SET_RX_FILTER (u_short) (0x10<<11)
|
||||
# define FIL_INDIVIDUAL (u_short) (0x01)
|
||||
# define FIL_MULTICAST (u_short) (0x02)
|
||||
# define FIL_BRDCST (u_short) (0x04)
|
||||
# define FIL_PROMISC (u_short) (0x08)
|
||||
|
||||
#define SET_RX_EARLY_THRESH (u_short) (0x11<<11)
|
||||
#define SET_TX_AVAIL_THRESH (u_short) (0x12<<11)
|
||||
#define SET_TX_START_THRESH (u_short) (0x13<<11)
|
||||
#define START_DMA (u_short) (0x14<<11) /* busmaster-only */
|
||||
# define START_DMA_TX (START_DMA | 0x0)) /* busmaster-only */
|
||||
# define START_DMA_RX (START_DMA | 0x1) /* busmaster-only */
|
||||
#define STATS_ENABLE (u_short) (0x15<<11)
|
||||
#define STATS_DISABLE (u_short) (0x16<<11)
|
||||
#define STOP_TRANSCEIVER (u_short) (0x17<<11)
|
||||
@ -313,6 +319,12 @@
|
||||
#define TXS_MAX_COLLISION 0x08
|
||||
#define TXS_STATUS_OVERFLOW 0x04
|
||||
|
||||
/*
|
||||
* RX status
|
||||
* Window 1/Port 0x08.
|
||||
*/
|
||||
#define RX_BYTES_MASK (u_short) (0x07ff)
|
||||
|
||||
/*
|
||||
* Internal Config and MAC control (Window 3)
|
||||
* Window 3 / Port 0: 32-bit internal config register:
|
||||
@ -349,19 +361,37 @@
|
||||
#define CONFIG_MEDIAMASK (u_short) 0x0070
|
||||
#define CONFIG_MEDIAMASK_SHIFT (u_short) 4
|
||||
|
||||
#define CONFIG_MEDIA_10BASE_T (u_short) 0x00
|
||||
#define CONFIG_MEDIA_AUI (u_short) 0x01
|
||||
#define CONFIG_MEDIA_RESV1 (u_short) 0x02
|
||||
#define CONFIG_MEDIA_10BASE_2 (u_short) 0x03
|
||||
#define CONFIG_MEDIA_100BASE_TX (u_short) 0x04
|
||||
#define CONFIG_MEDIA_100BASE_FX (u_short) 0x05
|
||||
#define CONFIG_MEDIA_MII (u_short) 0x06
|
||||
#define CONFIG_MEDIA_RESV2 (u_short) 0x07 /* 100Base-T4? */
|
||||
/* Active media in EP_W3_RESET_OPTIONS mediamask bits */
|
||||
|
||||
#define EPMEDIA_10BASE_T (u_short) 0x00
|
||||
#define EPMEDIA_AUI (u_short) 0x01
|
||||
#define EPMEDIA_RESV1 (u_short) 0x02
|
||||
#define EPMEDIA_10BASE_2 (u_short) 0x03
|
||||
#define EPMEDIA_100BASE_TX (u_short) 0x04
|
||||
#define EPMEDIA_100BASE_FX (u_short) 0x05
|
||||
#define EPMEDIA_MII (u_short) 0x06
|
||||
#define EPMEDIA_100BASE_T4 (u_short) 0x07
|
||||
|
||||
|
||||
#define CONFIG_AUTOSELECT (u_short) 0x0100
|
||||
#define CONFIG_AUTOSELECT_SHIFT (u_short) 8
|
||||
|
||||
/*
|
||||
* RESET_OPTIONS (Window 4, on Demon/Vortex/Bomerang only)
|
||||
* also mapped to PCI configuration space on PCI adaptors.
|
||||
*
|
||||
* (same register as Vortex EP_W3_RESET_OPTIONS, mapped to pci-config space)
|
||||
*/
|
||||
#define EP_PCI_100BASE_T4 (1<<0)
|
||||
#define EP_PCI_100BASE_TX (1<<1)
|
||||
#define EP_PCI_100BASE_FX (1<<2)
|
||||
#define EP_PCI_10BASE_T (1<<3)
|
||||
# define EP_PCI_UTP EP_PCI_10BASE_T
|
||||
#define EP_PCI_BNC (1<<4)
|
||||
#define EP_PCI_AUI (1<<5)
|
||||
#define EP_PCI_100BASE_MII (1<<6)
|
||||
#define EP_PCI_INTERNAL_VCO (1<<8)
|
||||
|
||||
/*
|
||||
* FIFO Status (Window 4)
|
||||
*
|
||||
@ -401,6 +431,40 @@
|
||||
#define FIFOS_RX_OVERRUN (u_short) 0x0800
|
||||
#define FIFOS_TX_OVERRUN (u_short) 0x0400
|
||||
|
||||
/*
|
||||
* ISA/eisa CONFIG_CNTRL media-present bits.
|
||||
*/
|
||||
#define EP_W0_CC_AUI (1<<13)
|
||||
#define EP_W0_CC_BNC (1<<12)
|
||||
#define EP_W0_CC_UTP (1<<9)
|
||||
|
||||
|
||||
/* EEPROM state flags/commands */
|
||||
#define EEPROM_BUSY (1<<15)
|
||||
#define EEPROM_TST_MODE (1<<14)
|
||||
#define READ_EEPROM (1<<7)
|
||||
|
||||
/* window 4, MEDIA_STATUS bits */
|
||||
#define SQE_ENABLE 0x08 /* Enables SQE on AUI ports */
|
||||
#define JABBER_GUARD_ENABLE 0x40
|
||||
#define LINKBEAT_ENABLE 0x80
|
||||
#define ENABLE_UTP (JABBER_GUARD_ENABLE|LINKBEAT_ENABLE)
|
||||
#define DISABLE_UTP 0x0
|
||||
#define LINKBEAT_DETECT 0x800
|
||||
|
||||
/*
|
||||
* ep_connectors softc media-preset bitflags
|
||||
*/
|
||||
#define EPC_AUI 0x01
|
||||
#define EPC_BNC 0x02
|
||||
#define EPC_RESERVED 0x04
|
||||
#define EPC_UTP 0x08
|
||||
#define EPC_100TX 0x10
|
||||
#define EPC_100FX 0x20
|
||||
#define EPC_MII 0x40
|
||||
#define EPC_100T4 0x80
|
||||
|
||||
|
||||
/*
|
||||
* Misc defines for various things.
|
||||
*/
|
||||
@ -412,58 +476,6 @@
|
||||
#define GO_WINDOW(x) bus_space_write_2(sc->sc_iot, \
|
||||
sc->sc_ioh, EP_COMMAND, WINDOW_SELECT|x)
|
||||
|
||||
/*
|
||||
* ep_connectors softc media-preset bitflags
|
||||
*/
|
||||
#define AUI 0x01
|
||||
#define BNC 0x02
|
||||
#define UTP 0x04
|
||||
#define TX 0x08
|
||||
#define FX 0x10
|
||||
#define T4 0x20
|
||||
#define MII 0x40
|
||||
|
||||
|
||||
/*
|
||||
* ISA/eisa CONFIG_CNTRL media-present bits.
|
||||
* XXX Also used as bus-independent media flags to epconfig().
|
||||
*/
|
||||
#define IS_AUI (1<<13)
|
||||
#define IS_BNC (1<<12)
|
||||
#define IS_UTP (1<<9)
|
||||
/*
|
||||
* XXX Bogus values to allow 10/100 PCI media.
|
||||
* Should be replaced with Demon, 3c515, or 10/100 PCMCIA equivalents.
|
||||
* for now, make sure they don't overlap 3c509 CONFIG_CNTRL bits.
|
||||
*/
|
||||
#define IS_100BASE_T4 (1<<16)
|
||||
#define IS_100BASE_TX (1<<17)
|
||||
#define IS_100BASE_FX (1<<18)
|
||||
#define IS_100BASE_MII (1<<19)
|
||||
|
||||
|
||||
/* EEPROM state flags/commands */
|
||||
#define EEPROM_BUSY (1<<15)
|
||||
#define EEPROM_TST_MODE (1<<14)
|
||||
#define READ_EEPROM (1<<7)
|
||||
|
||||
#define ENABLE_UTP 0xc0
|
||||
#define DISABLE_UTP 0x0
|
||||
#define RX_BYTES_MASK (u_short) (0x07ff)
|
||||
|
||||
/*
|
||||
* PCI configuration-space register media-present bits
|
||||
* (same register as Vortex EP_W3_RESET_OPTIONS, mapped to pci-config space)
|
||||
*/
|
||||
#define IS_PCI_100BASE_T4 (1<<0)
|
||||
#define IS_PCI_100BASE_TX (1<<1)
|
||||
#define IS_PCI_100BASE_FX (1<<2)
|
||||
#define IS_PCI_10BASE_T (1<<3)
|
||||
# define IS_PCI_UTP IS_PCI_10BASE_T
|
||||
#define IS_PCI_BNC (1<<4)
|
||||
#define IS_PCI_AUI (1<<5)
|
||||
#define IS_PCI_100BASE_MII (1<<6)
|
||||
#define IS_PCI_INTERNAL_VCO (1<<8)
|
||||
|
||||
/* Used to probe for large-packet support. */
|
||||
#define EP_LARGEWIN_PROBE EP_THRESH_DISABLE
|
||||
|
Loading…
Reference in New Issue
Block a user