Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Sep 2009 14:41:07 +0000 (UTC)
From:      Andrew Gallatin <gallatin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r197391 - head/sys/dev/mxge
Message-ID:  <200909211441.n8LEf721092082@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gallatin
Date: Mon Sep 21 14:41:07 2009
New Revision: 197391
URL: http://svn.freebsd.org/changeset/base/197391

Log:
  Add support for throttling transmit bandwidth.  This is most commonly
  used to reduce packet loss on high delay (WAN) paths with a
  slow link.

Modified:
  head/sys/dev/mxge/if_mxge.c
  head/sys/dev/mxge/if_mxge_var.h

Modified: head/sys/dev/mxge/if_mxge.c
==============================================================================
--- head/sys/dev/mxge/if_mxge.c	Mon Sep 21 13:09:56 2009	(r197390)
+++ head/sys/dev/mxge/if_mxge.c	Mon Sep 21 14:41:07 2009	(r197391)
@@ -106,6 +106,7 @@ static int mxge_max_slices = 1;
 static int mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
 static int mxge_always_promisc = 0;
 static int mxge_initial_mtu = ETHERMTU_JUMBO;
+static int mxge_throttle = 0;
 static char *mxge_fw_unaligned = "mxge_ethp_z8e";
 static char *mxge_fw_aligned = "mxge_eth_z8e";
 static char *mxge_fw_rss_aligned = "mxge_rss_eth_z8e";
@@ -596,10 +597,13 @@ static int
 mxge_select_firmware(mxge_softc_t *sc)
 {
 	int aligned = 0;
+	int force_firmware = mxge_force_firmware;
 
+	if (sc->throttle)
+		force_firmware = sc->throttle;
 
-	if (mxge_force_firmware != 0) {
-		if (mxge_force_firmware == 1)
+	if (force_firmware != 0) {
+		if (force_firmware == 1)
 			aligned = 1;
 		else
 			aligned = 0;
@@ -1314,10 +1318,48 @@ mxge_reset(mxge_softc_t *sc, int interru
 	mxge_change_promisc(sc, sc->ifp->if_flags & IFF_PROMISC);
 	mxge_change_pause(sc, sc->pause);
 	mxge_set_multicast_list(sc);
+	if (sc->throttle) {
+		cmd.data0 = sc->throttle;
+		if (mxge_send_cmd(sc, MXGEFW_CMD_SET_THROTTLE_FACTOR,
+				  &cmd)) {
+			device_printf(sc->dev,
+				      "can't enable throttle\n");
+		}
+	}
 	return status;
 }
 
 static int
+mxge_change_throttle(SYSCTL_HANDLER_ARGS)
+{
+	mxge_cmd_t cmd;
+	mxge_softc_t *sc;
+	int err;
+	unsigned int throttle;
+
+	sc = arg1;
+	throttle = sc->throttle;
+	err = sysctl_handle_int(oidp, &throttle, arg2, req);
+        if (err != 0) {
+                return err;
+        }
+
+	if (throttle == sc->throttle)
+		return 0;
+
+        if (throttle < MXGE_MIN_THROTTLE || throttle > MXGE_MAX_THROTTLE)
+                return EINVAL;
+	
+	mtx_lock(&sc->driver_mtx);
+	cmd.data0 = throttle;
+	err = mxge_send_cmd(sc, MXGEFW_CMD_SET_THROTTLE_FACTOR, &cmd);
+	if (err == 0)
+		sc->throttle = throttle;
+	mtx_unlock(&sc->driver_mtx);	
+	return err;
+}
+
+static int
 mxge_change_intr_coal(SYSCTL_HANDLER_ARGS)
 {
         mxge_softc_t *sc;
@@ -1505,6 +1547,12 @@ mxge_add_sysctls(mxge_softc_t *sc)
 			"I", "interrupt coalescing delay in usecs");
 
 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 
+			"throttle",
+			CTLTYPE_INT|CTLFLAG_RW, sc,
+			0, mxge_change_throttle, 
+			"I", "transmit throttling");
+
+	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 
 			"flow_control_enabled",
 			CTLTYPE_INT|CTLFLAG_RW, sc,
 			0, mxge_change_flow_control,
@@ -4016,6 +4064,7 @@ mxge_fetch_tunables(mxge_softc_t *sc)
 	TUNABLE_INT_FETCH("hw.mxge.rss_hash_type", &mxge_rss_hash_type);
 	TUNABLE_INT_FETCH("hw.mxge.rss_hashtype", &mxge_rss_hash_type);
 	TUNABLE_INT_FETCH("hw.mxge.initial_mtu", &mxge_initial_mtu);
+	TUNABLE_INT_FETCH("hw.mxge.throttle", &mxge_throttle);
 	if (sc->lro_cnt != 0)
 		mxge_lro_cnt = sc->lro_cnt;
 
@@ -4033,6 +4082,12 @@ mxge_fetch_tunables(mxge_softc_t *sc)
 	if (mxge_initial_mtu > ETHERMTU_JUMBO ||
 	    mxge_initial_mtu < ETHER_MIN_LEN)
 		mxge_initial_mtu = ETHERMTU_JUMBO;
+
+	if (mxge_throttle && mxge_throttle > MXGE_MAX_THROTTLE)
+		mxge_throttle = MXGE_MAX_THROTTLE;
+	if (mxge_throttle && mxge_throttle < MXGE_MIN_THROTTLE)
+		mxge_throttle = MXGE_MIN_THROTTLE;
+	sc->throttle = mxge_throttle;
 }
 
 

Modified: head/sys/dev/mxge/if_mxge_var.h
==============================================================================
--- head/sys/dev/mxge/if_mxge_var.h	Mon Sep 21 13:09:56 2009	(r197390)
+++ head/sys/dev/mxge/if_mxge_var.h	Mon Sep 21 14:41:07 2009	(r197391)
@@ -261,6 +261,7 @@ struct mxge_softc {
 	int fw_multicast_support;
 	int link_width;
 	int max_mtu;
+	int throttle;
 	int tx_defrag;
 	int media_flags;
 	int need_media_probe;
@@ -286,6 +287,8 @@ struct mxge_softc {
 #define MXGE_PCI_REV_Z8ES	1
 #define MXGE_XFP_COMPLIANCE_BYTE	131
 #define MXGE_SFP_COMPLIANCE_BYTE	  3
+#define MXGE_MIN_THROTTLE	416
+#define MXGE_MAX_THROTTLE	4096
 
 #define MXGE_HIGHPART_TO_U32(X) \
 (sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0)



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