mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Add Seeq Technology 80220 PHY support to smcphy(4). This PHY is
found on Adaptec AIC-6915 Starfire ethernet controller. While here, use status register to know resolved speed/duplex. With this change, sf(4) correctly reports speed/duplex of established link. Reviewed by: marius
This commit is contained in:
parent
4661f8627c
commit
34fe3828ba
1 changed files with 60 additions and 4 deletions
|
|
@ -55,6 +55,7 @@ static int smcphy_attach(device_t);
|
|||
static int smcphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void smcphy_reset(struct mii_softc *);
|
||||
static void smcphy_auto(struct mii_softc *, int);
|
||||
static void smcphy_status(struct mii_softc *);
|
||||
|
||||
static device_method_t smcphy_methods[] = {
|
||||
/* device interface */
|
||||
|
|
@ -76,13 +77,20 @@ static driver_t smcphy_driver = {
|
|||
DRIVER_MODULE(smcphy, miibus, smcphy_driver, smcphy_devclass, 0, 0);
|
||||
|
||||
static const struct mii_phydesc smcphys[] = {
|
||||
MII_PHY_DESC(SEEQ, 80220),
|
||||
MII_PHY_DESC(SEEQ, 84220),
|
||||
MII_PHY_END
|
||||
};
|
||||
|
||||
static const struct mii_phy_funcs smcphy80220_funcs = {
|
||||
smcphy_service,
|
||||
smcphy_status,
|
||||
mii_phy_reset
|
||||
};
|
||||
|
||||
static const struct mii_phy_funcs smcphy_funcs = {
|
||||
smcphy_service,
|
||||
ukphy_status,
|
||||
smcphy_status,
|
||||
smcphy_reset
|
||||
};
|
||||
|
||||
|
|
@ -97,11 +105,16 @@ static int
|
|||
smcphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
const struct mii_phy_funcs *mpf;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE,
|
||||
&smcphy_funcs, 1);
|
||||
ma = device_get_ivars(dev);
|
||||
if (MII_MODEL(ma->mii_id2) == MII_MODEL_SEEQ_80220)
|
||||
mpf = &smcphy80220_funcs;
|
||||
else
|
||||
mpf = &smcphy_funcs;
|
||||
mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, mpf, 1);
|
||||
mii_phy_setmedia(sc);
|
||||
|
||||
return (0);
|
||||
|
|
@ -214,3 +227,46 @@ smcphy_auto(struct mii_softc *sc, int media)
|
|||
anar = PHY_READ(sc, MII_ANAR);
|
||||
PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
|
||||
}
|
||||
|
||||
static void
|
||||
smcphy_status(struct mii_softc *sc)
|
||||
{
|
||||
struct mii_data *mii;
|
||||
uint32_t bmcr, bmsr, status;
|
||||
|
||||
mii = sc->mii_pdata;
|
||||
mii->mii_media_status = IFM_AVALID;
|
||||
mii->mii_media_active = IFM_ETHER;
|
||||
|
||||
bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
|
||||
if ((bmsr & BMSR_LINK) != 0)
|
||||
mii->mii_media_status |= IFM_ACTIVE;
|
||||
|
||||
bmcr = PHY_READ(sc, MII_BMCR);
|
||||
if ((bmcr & BMCR_ISO) != 0) {
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
mii->mii_media_status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bmcr & BMCR_LOOP) != 0)
|
||||
mii->mii_media_active |= IFM_LOOP;
|
||||
|
||||
if ((bmcr & BMCR_AUTOEN) != 0) {
|
||||
if ((bmsr & BMSR_ACOMP) == 0) {
|
||||
/* Erg, still trying, I guess... */
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
status = PHY_READ(sc, 0x12);
|
||||
if (status & 0x0080)
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
if (status & 0x0040)
|
||||
mii->mii_media_active |= IFM_FDX | mii_phy_flowstatus(sc);
|
||||
else
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue