summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_fxp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pci/if_fxp.c')
-rw-r--r--sys/pci/if_fxp.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c
index c60fe39..79032ac 100644
--- a/sys/pci/if_fxp.c
+++ b/sys/pci/if_fxp.c
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxp.c,v 1.62 1999/01/28 17:32:05 dillon Exp $
+ * $Id: if_fxp.c,v 1.63 1999/02/11 21:47:09 julian Exp $
*/
/*
@@ -1485,35 +1485,62 @@ fxp_mediastatus(ifp, ifmr)
struct ifmediareq *ifmr;
{
struct fxp_softc *sc = ifp->if_softc;
- int flags;
+ int flags, stsflags;
switch (sc->phy_primary_device) {
- case FXP_PHY_DP83840:
- case FXP_PHY_DP83840A:
case FXP_PHY_82555:
case FXP_PHY_82555B:
- flags = fxp_mdi_read(sc, sc->phy_primary_addr, FXP_PHY_BMCR);
+ case FXP_PHY_DP83840:
+ case FXP_PHY_DP83840A:
+ ifmr->ifm_status = IFM_AVALID; /* IFM_ACTIVE will be valid */
ifmr->ifm_active = IFM_ETHER;
+ /*
+ * the following is not an error.
+ * You need to read this register twice to get current
+ * status. This is correct documented behaviour, the
+ * first read gets latched values.
+ */
+ stsflags = fxp_mdi_read(sc, sc->phy_primary_addr, FXP_PHY_STS);
+ stsflags = fxp_mdi_read(sc, sc->phy_primary_addr, FXP_PHY_STS);
+ if (stsflags & FXP_PHY_STS_LINK_STS)
+ ifmr->ifm_status |= IFM_ACTIVE;
+
+ /*
+ * If we are in auto mode, then try report the result.
+ */
+ flags = fxp_mdi_read(sc, sc->phy_primary_addr, FXP_PHY_BMCR);
if (flags & FXP_PHY_BMCR_AUTOEN) {
ifmr->ifm_active |= IFM_AUTO; /* XXX presently 0 */
- /*
- * XXX Find the correct subset of chips that have
- * the USC register..
- */
- if ((sc->phy_primary_device == FXP_PHY_82555)
- || (sc->phy_primary_device == FXP_PHY_82555B)) {
- flags = fxp_mdi_read(sc,
- sc->phy_primary_addr, FXP_PHY_USC);
-
- if (flags & FXP_PHY_USC_SPEED)
- ifmr->ifm_active |= IFM_100_TX;
- else
- ifmr->ifm_active |= IFM_10_T;
+ if (stsflags & FXP_PHY_STS_AUTO_DONE) {
+ /*
+ * Intel and National parts report
+ * differently on what they found.
+ */
+ if ((sc->phy_primary_device == FXP_PHY_82555)
+ || (sc->phy_primary_device == FXP_PHY_82555B)) {
+ flags = fxp_mdi_read(sc,
+ sc->phy_primary_addr,
+ FXP_PHY_USC);
+
+ if (flags & FXP_PHY_USC_SPEED)
+ ifmr->ifm_active |= IFM_100_TX;
+ else
+ ifmr->ifm_active |= IFM_10_T;
+
+ if (flags & FXP_PHY_USC_DUPLEX)
+ ifmr->ifm_active |= IFM_FDX;
+ } else { /* it's National. only know speed */
+ flags = fxp_mdi_read(sc,
+ sc->phy_primary_addr,
+ FXP_DP83840_PAR);
- if (flags & FXP_PHY_USC_DUPLEX)
- ifmr->ifm_active |= IFM_FDX;
+ if (flags & FXP_DP83840_PAR_SPEED_10)
+ ifmr->ifm_active |= IFM_10_T;
+ else
+ ifmr->ifm_active |= IFM_100_TX;
+ }
}
- } else {
+ } else { /* in manual mode.. just report what we were set to */
if (flags & FXP_PHY_BMCR_SPEED_100M)
ifmr->ifm_active |= IFM_100_TX;
else
OpenPOWER on IntegriCloud