MFC 206662: Cleanup if_media handling in mxge(4)
This commit is contained in:
parent
3db0099738
commit
953a22892c
@ -883,6 +883,9 @@ mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data)
|
||||
case MXGEFW_CMD_ERROR_BUSY:
|
||||
err = EBUSY;
|
||||
break;
|
||||
case MXGEFW_CMD_ERROR_I2C_ABSENT:
|
||||
err = ENXIO;
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->dev,
|
||||
"mxge: command %d "
|
||||
@ -2782,37 +2785,25 @@ static struct mxge_media_type mxge_sfp_media_types[] =
|
||||
};
|
||||
|
||||
static void
|
||||
mxge_set_media(mxge_softc_t *sc, int type)
|
||||
mxge_media_set(mxge_softc_t *sc, int media_type)
|
||||
{
|
||||
sc->media_flags |= type;
|
||||
ifmedia_add(&sc->media, sc->media_flags, 0, NULL);
|
||||
ifmedia_set(&sc->media, sc->media_flags);
|
||||
|
||||
|
||||
ifmedia_add(&sc->media, IFM_ETHER | IFM_FDX | media_type,
|
||||
0, NULL);
|
||||
ifmedia_set(&sc->media, IFM_ETHER | IFM_FDX | media_type);
|
||||
sc->current_media = media_type;
|
||||
sc->media.ifm_media = sc->media.ifm_cur->ifm_media;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine the media type for a NIC. Some XFPs will identify
|
||||
* themselves only when their link is up, so this is initiated via a
|
||||
* link up interrupt. However, this can potentially take up to
|
||||
* several milliseconds, so it is run via the watchdog routine, rather
|
||||
* than in the interrupt handler itself. This need only be done
|
||||
* once, not each time the link is up.
|
||||
*/
|
||||
static void
|
||||
mxge_media_probe(mxge_softc_t *sc)
|
||||
mxge_media_init(mxge_softc_t *sc)
|
||||
{
|
||||
mxge_cmd_t cmd;
|
||||
char *cage_type;
|
||||
char *ptr;
|
||||
struct mxge_media_type *mxge_media_types = NULL;
|
||||
int i, err, ms, mxge_media_type_entries;
|
||||
uint32_t byte;
|
||||
int i;
|
||||
|
||||
sc->need_media_probe = 0;
|
||||
|
||||
/* if we've already set a media type, we're done */
|
||||
if (sc->media_flags != (IFM_ETHER | IFM_AUTO))
|
||||
return;
|
||||
ifmedia_removeall(&sc->media);
|
||||
mxge_media_set(sc, IFM_AUTO);
|
||||
|
||||
/*
|
||||
* parse the product code to deterimine the interface type
|
||||
@ -2823,6 +2814,7 @@ mxge_media_probe(mxge_softc_t *sc)
|
||||
ptr = sc->product_code_string;
|
||||
if (ptr == NULL) {
|
||||
device_printf(sc->dev, "Missing product code\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++, ptr++) {
|
||||
@ -2835,17 +2827,44 @@ mxge_media_probe(mxge_softc_t *sc)
|
||||
}
|
||||
if (*ptr == 'C') {
|
||||
/* -C is CX4 */
|
||||
mxge_set_media(sc, IFM_10G_CX4);
|
||||
return;
|
||||
}
|
||||
else if (*ptr == 'Q') {
|
||||
sc->connector = MXGE_CX4;
|
||||
mxge_media_set(sc, IFM_10G_CX4);
|
||||
} else if (*ptr == 'Q') {
|
||||
/* -Q is Quad Ribbon Fiber */
|
||||
sc->connector = MXGE_QRF;
|
||||
device_printf(sc->dev, "Quad Ribbon Fiber Media\n");
|
||||
/* FreeBSD has no media type for Quad ribbon fiber */
|
||||
return;
|
||||
} else if (*ptr == 'R') {
|
||||
/* -R is XFP */
|
||||
sc->connector = MXGE_XFP;
|
||||
} else if (*ptr == 'S' || *(ptr +1) == 'S') {
|
||||
/* -S or -2S is SFP+ */
|
||||
sc->connector = MXGE_SFP;
|
||||
} else {
|
||||
device_printf(sc->dev, "Unknown media type: %c\n", *ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (*ptr == 'R') {
|
||||
/*
|
||||
* Determine the media type for a NIC. Some XFPs will identify
|
||||
* themselves only when their link is up, so this is initiated via a
|
||||
* link up interrupt. However, this can potentially take up to
|
||||
* several milliseconds, so it is run via the watchdog routine, rather
|
||||
* than in the interrupt handler itself.
|
||||
*/
|
||||
static void
|
||||
mxge_media_probe(mxge_softc_t *sc)
|
||||
{
|
||||
mxge_cmd_t cmd;
|
||||
char *cage_type;
|
||||
|
||||
struct mxge_media_type *mxge_media_types = NULL;
|
||||
int i, err, ms, mxge_media_type_entries;
|
||||
uint32_t byte;
|
||||
|
||||
sc->need_media_probe = 0;
|
||||
|
||||
if (sc->connector == MXGE_XFP) {
|
||||
/* -R is XFP */
|
||||
mxge_media_types = mxge_xfp_media_types;
|
||||
mxge_media_type_entries =
|
||||
@ -2853,9 +2872,7 @@ mxge_media_probe(mxge_softc_t *sc)
|
||||
sizeof (mxge_xfp_media_types[0]);
|
||||
byte = MXGE_XFP_COMPLIANCE_BYTE;
|
||||
cage_type = "XFP";
|
||||
}
|
||||
|
||||
if (*ptr == 'S' || *(ptr +1) == 'S') {
|
||||
} else if (sc->connector == MXGE_SFP) {
|
||||
/* -S or -2S is SFP+ */
|
||||
mxge_media_types = mxge_sfp_media_types;
|
||||
mxge_media_type_entries =
|
||||
@ -2863,10 +2880,8 @@ mxge_media_probe(mxge_softc_t *sc)
|
||||
sizeof (mxge_sfp_media_types[0]);
|
||||
cage_type = "SFP+";
|
||||
byte = 3;
|
||||
}
|
||||
|
||||
if (mxge_media_types == NULL) {
|
||||
device_printf(sc->dev, "Unknown media type: %c\n", *ptr);
|
||||
} else {
|
||||
/* nothing to do; media type cannot change */
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2909,7 +2924,10 @@ mxge_media_probe(mxge_softc_t *sc)
|
||||
if (mxge_verbose)
|
||||
device_printf(sc->dev, "%s:%s\n", cage_type,
|
||||
mxge_media_types[0].name);
|
||||
mxge_set_media(sc, mxge_media_types[0].flag);
|
||||
if (sc->current_media != mxge_media_types[0].flag) {
|
||||
mxge_media_init(sc);
|
||||
mxge_media_set(sc, mxge_media_types[0].flag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i = 1; i < mxge_media_type_entries; i++) {
|
||||
@ -2919,12 +2937,16 @@ mxge_media_probe(mxge_softc_t *sc)
|
||||
cage_type,
|
||||
mxge_media_types[i].name);
|
||||
|
||||
mxge_set_media(sc, mxge_media_types[i].flag);
|
||||
if (sc->current_media != mxge_media_types[i].flag) {
|
||||
mxge_media_init(sc);
|
||||
mxge_media_set(sc, mxge_media_types[i].flag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
device_printf(sc->dev, "%s media 0x%x unknown\n", cage_type,
|
||||
cmd.data0);
|
||||
if (mxge_verbose)
|
||||
device_printf(sc->dev, "%s media 0x%x unknown\n",
|
||||
cage_type, cmd.data0);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2988,10 +3010,12 @@ mxge_intr(void *arg)
|
||||
sc->link_state = stats->link_up;
|
||||
if (sc->link_state) {
|
||||
if_link_state_change(sc->ifp, LINK_STATE_UP);
|
||||
sc->ifp->if_baudrate = IF_Gbps(10UL);
|
||||
if (mxge_verbose)
|
||||
device_printf(sc->dev, "link up\n");
|
||||
} else {
|
||||
if_link_state_change(sc->ifp, LINK_STATE_DOWN);
|
||||
sc->ifp->if_baudrate = 0;
|
||||
if (mxge_verbose)
|
||||
device_printf(sc->dev, "link down\n");
|
||||
}
|
||||
@ -4026,9 +4050,9 @@ mxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
|
||||
if (sc == NULL)
|
||||
return;
|
||||
ifmr->ifm_status = IFM_AVALID;
|
||||
ifmr->ifm_active = IFM_ETHER | IFM_FDX;
|
||||
ifmr->ifm_status |= sc->link_state ? IFM_ACTIVE : 0;
|
||||
ifmr->ifm_active = IFM_AUTO | IFM_ETHER;
|
||||
ifmr->ifm_active |= sc->link_state ? IFM_FDX : 0;
|
||||
ifmr->ifm_active |= sc->current_media;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4135,6 +4159,9 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
break;
|
||||
|
||||
case SIOCGIFMEDIA:
|
||||
mtx_lock(&sc->driver_mtx);
|
||||
mxge_media_probe(sc);
|
||||
mtx_unlock(&sc->driver_mtx);
|
||||
err = ifmedia_ioctl(ifp, (struct ifreq *)data,
|
||||
&sc->media, command);
|
||||
break;
|
||||
@ -4767,7 +4794,7 @@ mxge_attach(device_t dev)
|
||||
/* Initialise the ifmedia structure */
|
||||
ifmedia_init(&sc->media, 0, mxge_media_change,
|
||||
mxge_media_status);
|
||||
mxge_set_media(sc, IFM_ETHER | IFM_AUTO);
|
||||
mxge_media_init(sc);
|
||||
mxge_media_probe(sc);
|
||||
sc->dying = 0;
|
||||
ether_ifattach(ifp, sc->mac_addr);
|
||||
|
@ -268,6 +268,8 @@ struct mxge_softc {
|
||||
int num_slices;
|
||||
int rx_ring_size;
|
||||
int dying;
|
||||
int connector;
|
||||
int current_media;
|
||||
mxge_dma_t dmabench_dma;
|
||||
struct callout co_hdl;
|
||||
struct taskqueue *tq;
|
||||
@ -293,6 +295,12 @@ struct mxge_softc {
|
||||
#define MXGE_MIN_THROTTLE 416
|
||||
#define MXGE_MAX_THROTTLE 4096
|
||||
|
||||
/* Types of connectors on NICs supported by this driver */
|
||||
#define MXGE_CX4 0
|
||||
#define MXGE_XFP 1
|
||||
#define MXGE_SFP 2
|
||||
#define MXGE_QRF 3
|
||||
|
||||
#define MXGE_HIGHPART_TO_U32(X) \
|
||||
(sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0)
|
||||
#define MXGE_LOWPART_TO_U32(X) ((uint32_t)(X))
|
||||
|
Loading…
x
Reference in New Issue
Block a user