Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Apr 2010 15:40:24 +0000 (UTC)
From:      Andrew Gallatin <gallatin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r207280 - stable/7/sys/dev/mxge
Message-ID:  <201004271540.o3RFeOML050280@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gallatin
Date: Tue Apr 27 15:40:24 2010
New Revision: 207280
URL: http://svn.freebsd.org/changeset/base/207280

Log:
  MFC 206662: Cleanup if_media handling in mxge(4)

Modified:
  stable/7/sys/dev/mxge/if_mxge.c
  stable/7/sys/dev/mxge/if_mxge_var.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/mxge/if_mxge.c
==============================================================================
--- stable/7/sys/dev/mxge/if_mxge.c	Tue Apr 27 15:38:58 2010	(r207279)
+++ stable/7/sys/dev/mxge/if_mxge.c	Tue Apr 27 15:40:24 2010	(r207280)
@@ -876,6 +876,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 "
@@ -2596,37 +2599,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
@@ -2637,6 +2628,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++) {
@@ -2649,17 +2641,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 = 
@@ -2667,9 +2686,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 = 
@@ -2677,10 +2694,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;
 	}
 
@@ -2723,7 +2738,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++) {
@@ -2733,12 +2751,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;
 }
@@ -2798,10 +2820,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");
 			}
@@ -3759,9 +3783,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
@@ -3868,6 +3892,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;
@@ -4484,7 +4511,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/7/sys/dev/mxge/if_mxge_var.h
==============================================================================
--- stable/7/sys/dev/mxge/if_mxge_var.h	Tue Apr 27 15:38:58 2010	(r207279)
+++ stable/7/sys/dev/mxge/if_mxge_var.h	Tue Apr 27 15:40:24 2010	(r207280)
@@ -251,6 +251,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;
@@ -276,6 +278,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))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004271540.o3RFeOML050280>