Add enable/disable support and EEPROM size selection, prerequisites

for getting the cardbus fxp attachment to work.

Tested on the built-in 82559 in a VAIO Z505S.

From Johan Danielsson / PR8631; changed slightly to KNF.
This commit is contained in:
sommerfeld 1999-10-30 16:07:58 +00:00
parent 3d0e8ae9dd
commit db05febdfa
3 changed files with 95 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: i82557.c,v 1.9 1999/10/28 19:21:51 sommerfeld Exp $ */
/* $NetBSD: i82557.c,v 1.10 1999/10/30 16:07:58 sommerfeld Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@ -191,6 +191,9 @@ void fxp_power __P((int, void *));
int fxp_copy_small = 0;
int fxp_enable __P((struct fxp_softc*));
void fxp_disable __P((struct fxp_softc*));
struct fxp_phytype {
int fp_phy; /* type of PHY, -1 for MII at the end. */
void (*fp_init) __P((struct fxp_softc *));
@ -480,6 +483,34 @@ fxp_get_info(sc, enaddr)
CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
DELAY(10);
/*
* Figure out EEPROM size.
*
* Cards can have either 64-word or 256-word EEPROMs, with
* addresses fed in using a bit-at-a-time protocol, MSB first.
*
* XXX this is probably not the best way to do this; the linux
* driver does a checksum of the eeprom, but there is
* (AFAIK) no on-line documentation on what this checksum
* should look like (you could just steal the code from
* linux, but that's cheating); for now we just use the fact
* that the upper two bits of word 10 should be 01
*/
for(sc->sc_eeprom_size = 6;
sc->sc_eeprom_size <= 8;
sc->sc_eeprom_size += 2) {
fxp_read_eeprom(sc, &data, 10, 1);
if((data & 0xc000) == 0x4000)
break;
}
if(sc->sc_eeprom_size > 8)
panic("%s: failed to get EEPROM size", sc->sc_dev.dv_xname);
#ifdef DEBUG
printf("%s: assuming %d word EEPROM\n",
sc->sc_dev.dv_xname,
1 << sc->sc_eeprom_size);
#endif
/*
* Get info about the primary PHY
*/
@ -533,7 +564,7 @@ fxp_read_eeprom(sc, data, offset, words)
/*
* Shift in address.
*/
for (x = 6; x > 0; x--) {
for (x = sc->sc_eeprom_size; x > 0; x--) {
if ((i + offset) & (1 << (x - 1))) {
reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
} else {
@ -1380,6 +1411,12 @@ fxp_mii_mediastatus(ifp, ifmr)
{
struct fxp_softc *sc = ifp->if_softc;
if(sc->sc_enabled == 0) {
ifmr->ifm_active = IFM_ETHER | IFM_NONE;
ifmr->ifm_status = 0;
return;
}
mii_pollstat(&sc->sc_mii);
ifmr->ifm_status = sc->sc_mii.mii_media_status;
ifmr->ifm_active = sc->sc_mii.mii_media_active;
@ -1521,6 +1558,8 @@ fxp_ioctl(ifp, command, data)
switch (command) {
case SIOCSIFADDR:
if ((error = fxp_enable(sc)) != 0)
break;
ifp->if_flags |= IFF_UP;
switch (ifa->ifa_addr->sa_family) {
@ -1568,24 +1607,33 @@ fxp_ioctl(ifp, command, data)
* stop it.
*/
fxp_stop(sc, 1);
fxp_disable(sc);
} else if ((ifp->if_flags & IFF_UP) != 0 &&
(ifp->if_flags & IFF_RUNNING) == 0) {
/*
* If interface is marked up and it is stopped, then
* start it.
*/
if((error = fxp_enable(sc)) != 0)
break;
error = fxp_init(sc);
} else if ((ifp->if_flags & IFF_UP) != 0) {
/*
* Reset the interface to pick up change in any other
* flags that affect the hardware state.
*/
if((error = fxp_enable(sc)) != 0)
break;
error = fxp_init(sc);
}
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
if(sc->sc_enabled == 0) {
error = EIO;
break;
}
error = (command == SIOCADDMULTI) ?
ether_addmulti(ifr, &sc->sc_ethercom) :
ether_delmulti(ifr, &sc->sc_ethercom);
@ -1700,3 +1748,31 @@ fxp_mc_setup(sc)
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
} while ((mcsp->cb_status & FXP_CB_STATUS_C) == 0);
}
int
fxp_enable(sc)
struct fxp_softc *sc;
{
if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
if ((*sc->sc_enable)(sc) != 0) {
printf("%s: device enable failed\n",
sc->sc_dev.dv_xname);
return (EIO);
}
}
sc->sc_enabled = 1;
return 0;
}
void
fxp_disable(sc)
struct fxp_softc *sc;
{
if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
(*sc->sc_disable)(sc);
sc->sc_enabled = 0;
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: i82557var.h,v 1.7 1999/10/28 19:21:51 sommerfeld Exp $ */
/* $NetBSD: i82557var.h,v 1.8 1999/10/30 16:07:58 sommerfeld Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@ -199,9 +199,16 @@ struct fxp_softc {
int phy_primary_addr; /* address of primary PHY */
int phy_primary_device; /* device type of primary PHY */
int phy_10Mbps_only; /* PHY is 10Mbps-only device */
int sc_enabled; /* boolean; power enabled on interface */
int (*sc_enable) __P((struct fxp_softc *));
void (*sc_disable) __P((struct fxp_softc *));
int sc_eeprom_size; /* log2 size of EEPROM */
#if NRND > 0
rndsource_element_t rnd_source; /* random source */
#endif
};
#define FXP_RXMAP_GET(sc) ((sc)->sc_rxmaps[(sc)->sc_rxfree++])
@ -307,3 +314,7 @@ do { \
void fxp_attach __P((struct fxp_softc *));
int fxp_intr __P((void *));
int fxp_enable __P((struct fxp_softc*));
void fxp_disable __P((struct fxp_softc*));

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_fxp_pci.c,v 1.1 1999/06/20 16:35:40 thorpej Exp $ */
/* $NetBSD: if_fxp_pci.c,v 1.2 1999/10/30 16:07:59 sommerfeld Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@ -135,6 +135,10 @@ fxp_pci_attach(parent, self, aux)
bus_size_t size;
int flags;
sc->sc_enabled = 1;
sc->sc_enable = NULL;
sc->sc_disable = NULL;
/*
* Map control/status registers.
*/