From owner-svn-src-all@FreeBSD.ORG Tue Apr 27 15:38:59 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 07FC9106566C; Tue, 27 Apr 2010 15:38:59 +0000 (UTC) (envelope-from gallatin@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E801D8FC22; Tue, 27 Apr 2010 15:38:58 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o3RFcwJH049907; Tue, 27 Apr 2010 15:38:58 GMT (envelope-from gallatin@svn.freebsd.org) Received: (from gallatin@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o3RFcwCb049906; Tue, 27 Apr 2010 15:38:58 GMT (envelope-from gallatin@svn.freebsd.org) Message-Id: <201004271538.o3RFcwCb049906@svn.freebsd.org> From: Andrew Gallatin Date: Tue, 27 Apr 2010 15:38:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r207279 - stable/8/sys/dev/mxge X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Apr 2010 15:38:59 -0000 Author: gallatin Date: Tue Apr 27 15:38:58 2010 New Revision: 207279 URL: http://svn.freebsd.org/changeset/base/207279 Log: MFC 206662: Cleanup if_media handling in mxge(4) Modified: stable/8/sys/dev/mxge/if_mxge.c stable/8/sys/dev/mxge/if_mxge_var.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/geom/sched/ (props changed) Modified: stable/8/sys/dev/mxge/if_mxge.c ============================================================================== --- stable/8/sys/dev/mxge/if_mxge.c Tue Apr 27 15:16:54 2010 (r207278) +++ stable/8/sys/dev/mxge/if_mxge.c Tue Apr 27 15:38:58 2010 (r207279) @@ -883,6 +883,9 @@ mxge_send_cmd(mxge_softc_t *sc, uint32_t 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_m }; 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; - - sc->need_media_probe = 0; + int i; - /* 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, str 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 com 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); Modified: stable/8/sys/dev/mxge/if_mxge_var.h ============================================================================== --- stable/8/sys/dev/mxge/if_mxge_var.h Tue Apr 27 15:16:54 2010 (r207278) +++ stable/8/sys/dev/mxge/if_mxge_var.h Tue Apr 27 15:38:58 2010 (r207279) @@ -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))