Instead of storing mii_media_table array index in ifm_data, determine

it in mii_phy_setmedia() functionally.

Sponsored by:	Nginx, Inc.
This commit is contained in:
Gleb Smirnoff 2015-04-21 09:39:48 +00:00
parent 6775608bea
commit 27e1f92dbf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=281821
4 changed files with 120 additions and 77 deletions

View File

@ -139,14 +139,12 @@ acphy_attach(device_t dev)
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask;
device_printf(dev, " ");
#define ADD(m, c) ifmedia_add(&sc->mii_pdata->mii_media, (m), (c), NULL)
#define ADD(m) ifmedia_add(&sc->mii_pdata->mii_media, (m), 0, NULL)
if ((PHY_READ(sc, MII_ACPHY_MCTL) & AC_MCTL_FX_SEL) != 0) {
sc->mii_flags |= MIIF_HAVEFIBER;
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst),
MII_MEDIA_100_TX);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst));
printf("100baseFX, ");
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst),
MII_MEDIA_100_TX_FDX);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst));
printf("100baseFX-FDX, ");
}
#undef ADD

View File

@ -142,12 +142,10 @@ lxtphy_attach(device_t dev)
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask;
device_printf(dev, " ");
#define ADD(m, c) ifmedia_add(&sc->mii_pdata->mii_media, (m), (c), NULL)
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst),
MII_MEDIA_100_TX);
#define ADD(m) ifmedia_add(&sc->mii_pdata->mii_media, (m), 0, NULL)
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst));
printf("100baseFX, ");
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst),
MII_MEDIA_100_TX_FDX);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst));
printf("100baseFX-FDX, ");
#undef ADD

View File

@ -54,9 +54,28 @@ __FBSDID("$FreeBSD$");
#include "miibus_if.h"
/*
* Media to register setting conversion table. Order matters.
*
* An array of structures to map MII media types to BMCR/ANAR settings.
*/
static const struct mii_media mii_media_table[MII_NMEDIA] = {
enum {
MII_MEDIA_NONE = 0,
MII_MEDIA_10_T,
MII_MEDIA_10_T_FDX,
MII_MEDIA_100_T4,
MII_MEDIA_100_TX,
MII_MEDIA_100_TX_FDX,
MII_MEDIA_1000_X,
MII_MEDIA_1000_X_FDX,
MII_MEDIA_1000_T,
MII_MEDIA_1000_T_FDX,
MII_NMEDIA,
};
static const struct mii_media {
u_int mm_bmcr; /* BMCR settings for this media */
u_int mm_anar; /* ANAR settings for this media */
u_int mm_gtcr; /* 100base-T2 or 1000base-T CR */
} mii_media_table[MII_NMEDIA] = {
/* None */
{ BMCR_ISO, ANAR_CSMA,
0, },
@ -104,8 +123,10 @@ mii_phy_setmedia(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int bmcr, anar, gtcr;
int index = -1;
if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
switch (IFM_SUBTYPE(ife->ifm_media)) {
case IFM_AUTO:
/*
* Force renegotiation if MIIF_DOPAUSE or MIIF_FORCEANEG.
* The former is necessary as we might switch from flow-
@ -115,19 +136,78 @@ mii_phy_setmedia(struct mii_softc *sc)
(sc->mii_flags & (MIIF_DOPAUSE | MIIF_FORCEANEG)) != 0)
(void)mii_phy_auto(sc);
return;
case IFM_NONE:
index = MII_MEDIA_NONE;
break;
case IFM_HPNA_1:
index = MII_MEDIA_10_T;
break;
case IFM_10_T:
switch (IFM_OPTIONS(ife->ifm_media)) {
case 0:
index = MII_MEDIA_10_T;
break;
case IFM_FDX:
case (IFM_FDX | IFM_FLOW):
index = MII_MEDIA_10_T_FDX;
break;
};
break;
case IFM_100_TX:
case IFM_100_FX:
switch (IFM_OPTIONS(ife->ifm_media)) {
case 0:
index = MII_MEDIA_100_TX;
break;
case IFM_FDX:
case (IFM_FDX | IFM_FLOW):
index = MII_MEDIA_100_TX_FDX;
break;
}
break;
case IFM_100_T4:
index = MII_MEDIA_100_T4;
break;
case IFM_1000_SX:
switch (IFM_OPTIONS(ife->ifm_media)) {
case 0:
index = MII_MEDIA_1000_X;
break;
case IFM_FDX:
case (IFM_FDX | IFM_FLOW):
index = MII_MEDIA_1000_X_FDX;
break;
}
break;
case IFM_1000_T:
switch (IFM_OPTIONS(ife->ifm_media)) {
case 0:
case IFM_ETH_MASTER:
index = MII_MEDIA_1000_T;
break;
case IFM_FDX:
case (IFM_FDX | IFM_ETH_MASTER):
case (IFM_FDX | IFM_FLOW):
case (IFM_FDX | IFM_FLOW | IFM_ETH_MASTER):
index = MII_MEDIA_1000_T_FDX;
break;
}
break;
}
/*
* Table index is stored in the media entry.
*/
KASSERT(index != -1, ("%s: failed to map media word %d",
__func__, ife->ifm_media));
KASSERT(ife->ifm_data >=0 && ife->ifm_data < MII_NMEDIA,
("invalid ife->ifm_data (0x%x) in mii_phy_setmedia",
ife->ifm_data));
anar = mii_media_table[ife->ifm_data].mm_anar;
bmcr = mii_media_table[ife->ifm_data].mm_bmcr;
gtcr = mii_media_table[ife->ifm_data].mm_gtcr;
anar = mii_media_table[index].mm_anar;
bmcr = mii_media_table[index].mm_bmcr;
gtcr = mii_media_table[index].mm_gtcr;
if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
gtcr |= GTCR_MAN_MS;
@ -318,12 +398,11 @@ mii_phy_add_media(struct mii_softc *sc)
*/
sc->mii_anegticks = MII_ANEGTICKS;
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
#define ADD(m) ifmedia_add(&mii->mii_media, (m), 0, NULL)
#define PRINT(s) printf("%s%s", sep, s); sep = ", "
if ((sc->mii_flags & MIIF_NOISOLATE) == 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
MII_MEDIA_NONE);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst));
PRINT("none");
}
@ -335,51 +414,44 @@ mii_phy_add_media(struct mii_softc *sc)
if ((sc->mii_flags & MIIF_IS_HPNA) != 0) {
if ((sc->mii_capabilities & BMSR_10THDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_HPNA_1, 0,
sc->mii_inst), MII_MEDIA_10_T);
sc->mii_inst));
PRINT("HomePNA1");
}
return;
}
if ((sc->mii_capabilities & BMSR_10THDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst),
MII_MEDIA_10_T);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst));
PRINT("10baseT");
}
if ((sc->mii_capabilities & BMSR_10TFDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst),
MII_MEDIA_10_T_FDX);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst));
PRINT("10baseT-FDX");
if ((sc->mii_flags & MIIF_DOPAUSE) != 0 &&
(sc->mii_flags & MIIF_NOMANPAUSE) == 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T,
IFM_FDX | IFM_FLOW, sc->mii_inst),
MII_MEDIA_10_T_FDX);
IFM_FDX | IFM_FLOW, sc->mii_inst));
PRINT("10baseT-FDX-flow");
}
fdx = 1;
}
if ((sc->mii_capabilities & BMSR_100TXHDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst),
MII_MEDIA_100_TX);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst));
PRINT("100baseTX");
}
if ((sc->mii_capabilities & BMSR_100TXFDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst),
MII_MEDIA_100_TX_FDX);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst));
PRINT("100baseTX-FDX");
if ((sc->mii_flags & MIIF_DOPAUSE) != 0 &&
(sc->mii_flags & MIIF_NOMANPAUSE) == 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX,
IFM_FDX | IFM_FLOW, sc->mii_inst),
MII_MEDIA_100_TX_FDX);
IFM_FDX | IFM_FLOW, sc->mii_inst));
PRINT("100baseTX-FDX-flow");
}
fdx = 1;
}
if ((sc->mii_capabilities & BMSR_100T4) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst),
MII_MEDIA_100_T4);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst));
PRINT("100baseT4");
}
@ -392,20 +464,19 @@ mii_phy_add_media(struct mii_softc *sc)
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_IS_1000X;
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0,
sc->mii_inst), MII_MEDIA_1000_X);
sc->mii_inst));
PRINT("1000baseSX");
}
if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0) {
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_IS_1000X;
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX,
sc->mii_inst), MII_MEDIA_1000_X_FDX);
sc->mii_inst));
PRINT("1000baseSX-FDX");
if ((sc->mii_flags & MIIF_DOPAUSE) != 0 &&
(sc->mii_flags & MIIF_NOMANPAUSE) == 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX,
IFM_FDX | IFM_FLOW, sc->mii_inst),
MII_MEDIA_1000_X_FDX);
IFM_FDX | IFM_FLOW, sc->mii_inst));
PRINT("1000baseSX-FDX-flow");
}
fdx = 1;
@ -421,31 +492,29 @@ mii_phy_add_media(struct mii_softc *sc)
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_HAVE_GTCR;
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0,
sc->mii_inst), MII_MEDIA_1000_T);
sc->mii_inst));
PRINT("1000baseT");
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T,
IFM_ETH_MASTER, sc->mii_inst), MII_MEDIA_1000_T);
IFM_ETH_MASTER, sc->mii_inst));
PRINT("1000baseT-master");
}
if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0) {
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_HAVE_GTCR;
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX,
sc->mii_inst), MII_MEDIA_1000_T_FDX);
sc->mii_inst));
PRINT("1000baseT-FDX");
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T,
IFM_FDX | IFM_ETH_MASTER, sc->mii_inst),
MII_MEDIA_1000_T_FDX);
IFM_FDX | IFM_ETH_MASTER, sc->mii_inst));
PRINT("1000baseT-FDX-master");
if ((sc->mii_flags & MIIF_DOPAUSE) != 0 &&
(sc->mii_flags & MIIF_NOMANPAUSE) == 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T,
IFM_FDX | IFM_FLOW, sc->mii_inst),
MII_MEDIA_1000_T_FDX);
IFM_FDX | IFM_FLOW, sc->mii_inst));
PRINT("1000baseT-FDX-flow");
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T,
IFM_FDX | IFM_FLOW | IFM_ETH_MASTER,
sc->mii_inst), MII_MEDIA_1000_T_FDX);
sc->mii_inst));
PRINT("1000baseT-FDX-flow-master");
}
fdx = 1;
@ -454,12 +523,11 @@ mii_phy_add_media(struct mii_softc *sc)
if ((sc->mii_capabilities & BMSR_ANEG) != 0) {
/* intentionally invalid index */
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst),
MII_NMEDIA);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst));
PRINT("auto");
if (fdx != 0 && (sc->mii_flags & MIIF_DOPAUSE) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, IFM_FLOW,
sc->mii_inst), MII_NMEDIA);
sc->mii_inst));
PRINT("auto-flow");
}
}

View File

@ -180,27 +180,6 @@ struct mii_phydesc {
MII_STR_ ## a ## _ ## b }
#define MII_PHY_END { 0, 0, NULL }
/*
* An array of these structures map MII media types to BMCR/ANAR settings.
*/
struct mii_media {
u_int mm_bmcr; /* BMCR settings for this media */
u_int mm_anar; /* ANAR settings for this media */
u_int mm_gtcr; /* 100base-T2 or 1000base-T CR */
};
#define MII_MEDIA_NONE 0
#define MII_MEDIA_10_T 1
#define MII_MEDIA_10_T_FDX 2
#define MII_MEDIA_100_T4 3
#define MII_MEDIA_100_TX 4
#define MII_MEDIA_100_TX_FDX 5
#define MII_MEDIA_1000_X 6
#define MII_MEDIA_1000_X_FDX 7
#define MII_MEDIA_1000_T 8
#define MII_MEDIA_1000_T_FDX 9
#define MII_NMEDIA 10
#ifdef _KERNEL
#define PHY_READ(p, r) \