1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-02-05 18:05:16 +00:00

Fix problem with RTL8201L PHY. From submitter:

Bugfix for the Realtek PHY driver... an RTL8201L standalone PHY
    needs different handling than the integrated ones in terms of
    speed detection.  There was a bogus test based on the parent
    device driver name string controlling which speed register to
    query.  That test began failing when the rl driver was split into
    separate rl and re drivers some time ago.  Apparently nobody ever
    noticed because the buggy code only executes if NWAY negotiation
    failed.  Since we happen to be testing with an ancient dumb hub
    rather than a modern switch, we found it.

    To fix it all, have the attach() routine notice whether we're
    dealing with an integrated PHY or an RTL8201L and store that info
    in a struct accessible to the status() routine that needs to know
    which register to query.

I touched up the fixes because they were relative to RELENG_6 and to
bring a few nits into line with style(9).

MFC After: 2 weeks
Submitted by: Ian Lepore
This commit is contained in:
Warner Losh 2007-02-08 19:16:15 +00:00
parent 71ddf30bd2
commit 6d2b26f4a0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=166572

View File

@ -57,6 +57,11 @@ __FBSDID("$FreeBSD$");
#include "miibus_if.h"
struct rlphy_softc {
struct mii_softc sc_mii; /* generic PHY */
int sc_is_RTL8201L; /* is an external RTL8201L PHY */
};
static int rlphy_probe(device_t);
static int rlphy_attach(device_t);
@ -74,7 +79,7 @@ static devclass_t rlphy_devclass;
static driver_t rlphy_driver = {
"rlphy",
rlphy_methods,
sizeof(struct mii_softc)
sizeof(struct rlphy_softc)
};
DRIVER_MODULE(rlphy, miibus, rlphy_driver, rlphy_devclass, 0, 0);
@ -118,12 +123,21 @@ rlphy_attach(device_t dev)
struct mii_softc *sc;
struct mii_attach_args *ma;
struct mii_data *mii;
struct rlphy_softc *rsc;
sc = device_get_softc(dev);
ma = device_get_ivars(dev);
sc->mii_dev = device_get_parent(dev);
mii = device_get_softc(sc->mii_dev);
/*
* Check whether we're the RTL8201L PHY and remember so the status
* routine can query the proper register for speed detection.
*/
rsc = (struct rlphy_softc *)sc;
if (mii_phy_dev_probe(dev, rlphys, BUS_PROBE_DEFAULT) == 0)
rsc->sc_is_RTL8201L++;
/*
* The RealTek PHY can never be isolated, so never allow non-zero
* instances!
@ -210,6 +224,7 @@ rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
static void
rlphy_status(struct mii_softc *phy)
{
struct rlphy_softc *rsc =(struct rlphy_softc *)phy;
struct mii_data *mii = phy->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int bmsr, bmcr, anlpar;
@ -286,7 +301,7 @@ rlphy_status(struct mii_softc *phy)
* can test the 'SPEED10' bit of the MAC's media status
* register.
*/
if (strcmp(mii->mii_ifp->if_dname, "rl") != 0) {
if (rsc->sc_is_RTL8201L) {
if (PHY_READ(phy, 0x0019) & 0x01)
mii->mii_media_active |= IFM_100_TX;
else