PERFORCE change 148085 for review

John Birrell jb at FreeBSD.org
Fri Aug 22 06:57:45 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=148085

Change 148085 by jb at freebsd3 on 2008/08/22 06:57:06

	IF7

Affected files ...

.. //depot/projects/dtrace7/src/sbin/ifconfig/Makefile#2 integrate
.. //depot/projects/dtrace7/src/sbin/ifconfig/ifconfig.8#5 integrate
.. //depot/projects/dtrace7/src/sbin/ifconfig/ifgre.c#1 branch
.. //depot/projects/dtrace7/src/share/man/man4/gre.4#2 integrate
.. //depot/projects/dtrace7/src/sys/amd64/amd64/exception.S#4 integrate
.. //depot/projects/dtrace7/src/sys/compat/ndis/ntoskrnl_var.h#2 integrate
.. //depot/projects/dtrace7/src/sys/compat/ndis/subr_ndis.c#2 integrate
.. //depot/projects/dtrace7/src/sys/compat/ndis/subr_ntoskrnl.c#5 integrate
.. //depot/projects/dtrace7/src/sys/conf/files#17 integrate
.. //depot/projects/dtrace7/src/sys/dev/cxgb/cxgb_adapter.h#4 integrate
.. //depot/projects/dtrace7/src/sys/dev/cxgb/cxgb_lro.c#3 delete
.. //depot/projects/dtrace7/src/sys/dev/cxgb/cxgb_main.c#5 integrate
.. //depot/projects/dtrace7/src/sys/dev/cxgb/cxgb_sge.c#4 integrate
.. //depot/projects/dtrace7/src/sys/modules/cxgb/cxgb/Makefile#3 integrate
.. //depot/projects/dtrace7/src/sys/net/if_gre.c#3 integrate
.. //depot/projects/dtrace7/src/sys/net/if_gre.h#3 integrate
.. //depot/projects/dtrace7/src/usr.sbin/ndiscvt/inf.c#3 integrate

Differences ...

==== //depot/projects/dtrace7/src/sbin/ifconfig/Makefile#2 (text+ko) ====

@@ -1,5 +1,5 @@
 #	From: @(#)Makefile	8.1 (Berkeley) 6/5/93
-# $FreeBSD: src/sbin/ifconfig/Makefile,v 1.33 2007/04/17 00:35:09 thompsa Exp $
+# $FreeBSD: src/sbin/ifconfig/Makefile,v 1.33.2.1 2008/08/22 03:55:37 thompsa Exp $
 
 .include <bsd.own.mk>
 
@@ -24,6 +24,7 @@
 SRCS+=	ifmedia.c		# SIOC[GS]IFMEDIA support
 SRCS+=	ifvlan.c		# SIOC[GS]ETVLAN support
 SRCS+=	ifieee80211.c		# SIOC[GS]IEEE80211 support
+SRCS+=	ifgre.c			# GRE keys etc
 
 SRCS+=	ifcarp.c		# SIOC[GS]VH support
 SRCS+=	ifgroup.c		# ...

==== //depot/projects/dtrace7/src/sbin/ifconfig/ifconfig.8#5 (text+ko) ====

@@ -26,9 +26,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     From: @(#)ifconfig.8	8.3 (Berkeley) 1/5/94
-.\" $FreeBSD: src/sbin/ifconfig/ifconfig.8,v 1.142.2.5 2008/08/18 00:51:19 sam Exp $
+.\" $FreeBSD: src/sbin/ifconfig/ifconfig.8,v 1.142.2.6 2008/08/22 03:55:37 thompsa Exp $
 .\"
-.Dd February 29, 2008
+.Dd June 20, 2008
 .Dt IFCONFIG 8
 .Os
 .Sh NAME
@@ -1692,6 +1692,16 @@
 parameter.
 .El
 .Pp
+The following parameters are specific to GRE tunnel interfaces,
+.Xr gre 4 :
+.Bl -tag -width indent
+.It Cm grekey Ar key
+Configure the GRE key to be used for outgoing packets.
+Note that
+.Xr gre 4 will always accept GRE packets with invalid or absent keys.
+This command will result in a four byte MTU reduction on the interface.
+.El
+.Pp
 The following parameters are specific to
 .Xr pfsync 4
 interfaces:

==== //depot/projects/dtrace7/src/share/man/man4/gre.4#2 (text+ko) ====

@@ -34,9 +34,9 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/man/man4/gre.4,v 1.7 2006/10/19 07:41:47 danger Exp $
+.\" $FreeBSD: src/share/man/man4/gre.4,v 1.7.2.1 2008/08/22 03:55:37 thompsa Exp $
 .\"
-.Dd June 9, 2002
+.Dd June 20, 2008
 .Dt GRE 4
 .Os
 .Sh NAME
@@ -167,6 +167,12 @@
 section below.
 .It Dv GREGPROTO
 Query operation mode.
+.It Dv GRESKEY
+Set the GRE key used for outgoing packets.
+A value of 0 disables the key option.
+.It Dv GREGKEY
+Get the GRE key currently used for outgoing packets.
+0 means no outgoing key.
 .El
 .Pp
 Note that the IP addresses of the tunnel endpoints may be the same as the
@@ -264,6 +270,7 @@
 The MTU of
 .Nm
 interfaces is set to 1476 by default, to match the value used by Cisco routers.
+If grekey is set this is lowered to 1472.
 This may not be an optimal value, depending on the link between the two tunnel
 endpoints.
 It can be adjusted via
@@ -332,4 +339,9 @@
 .Nm
 interface itself.
 .Pp
-The GRE RFCs are not yet fully implemented (no GRE options).
+The current implementation uses the key only for outgoing packets.
+Incomming packets with a different key or without a key will be treated as if they
+would belong to this interface.
+.Pp
+RFC1701 is not fully supported, however all unsupported features have been
+deprecated in RFC2784. 

==== //depot/projects/dtrace7/src/sys/amd64/amd64/exception.S#4 (text+ko) ====

@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.131 2007/12/07 08:20:15 jkoshy Exp $
+ * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.129.2.2 2008/08/21 09:58:18 kib Exp $
  */
 
 #include "opt_atpic.h"
@@ -636,13 +636,10 @@
 	.globl	doreti_iret_fault
 doreti_iret_fault:
 	subq	$TF_RIP,%rsp		/* space including tf_err, tf_trapno */
-	testb	$SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
-	jz	1f			/* already running with kernel GS.base */
-	swapgs
-1:	testl	$PSL_I,TF_RFLAGS(%rsp)
-	jz	2f
+	testl	$PSL_I,TF_RFLAGS(%rsp)
+	jz	1f
 	sti
-2:	movq	%rdi,TF_RDI(%rsp)
+1:	movq	%rdi,TF_RDI(%rsp)
 	movq	%rsi,TF_RSI(%rsp)
 	movq	%rdx,TF_RDX(%rsp)
 	movq	%rcx,TF_RCX(%rsp)

==== //depot/projects/dtrace7/src/sys/compat/ndis/ntoskrnl_var.h#2 (text+ko) ====

@@ -29,7 +29,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/compat/ndis/ntoskrnl_var.h,v 1.43 2006/08/17 22:50:32 imp Exp $
+ * $FreeBSD: src/sys/compat/ndis/ntoskrnl_var.h,v 1.43.2.1 2008/08/22 03:08:31 thompsa Exp $
  */
 
 #ifndef _NTOSKRNL_VAR_H_
@@ -1309,6 +1309,7 @@
 extern int ntoskrnl_libfini(void);
 
 extern void ntoskrnl_intr(void *);
+extern void ntoskrnl_time(uint64_t *);
 
 extern uint16_t ExQueryDepthSList(slist_header *);
 extern slist_entry

==== //depot/projects/dtrace7/src/sys/compat/ndis/subr_ndis.c#2 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/compat/ndis/subr_ndis.c,v 1.108 2007/05/31 11:51:49 kib Exp $");
+__FBSDID("$FreeBSD: src/sys/compat/ndis/subr_ndis.c,v 1.108.2.1 2008/08/22 03:08:31 thompsa Exp $");
 
 /*
  * This file implements a translation layer between the BSD networking
@@ -282,6 +282,7 @@
 	uint32_t, uint32_t, ndis_packet *, uint32_t, uint32_t *);
 static void NdisCopyFromPacketToPacketSafe(ndis_packet *,
 	uint32_t, uint32_t, ndis_packet *, uint32_t, uint32_t *, uint32_t);
+static void NdisIMCopySendPerPacketInfo(ndis_packet *, ndis_packet *);
 static ndis_status NdisMRegisterDevice(ndis_handle,
 	unicode_string *, unicode_string *, driver_dispatch **,
 	void **, ndis_handle *);
@@ -1017,7 +1018,7 @@
 	sc = device_get_softc(dev);
 	ifp = sc->ifp;
 
-	if (ifp->if_flags & IFF_DEBUG) {
+	if (ifp != NULL && ifp->if_flags & IFF_DEBUG) {
 		error = pe_get_message((vm_offset_t)drv->dro_driverstart,
 		    code, &str, &i, &flags);
 		if (error == 0) {
@@ -1035,7 +1036,7 @@
 	device_printf (dev, "NDIS ERROR: %x (%s)\n", code,
 	    str == NULL ? "unknown error" : str);
 
-	if (ifp->if_flags & IFF_DEBUG) {
+	if (ifp != NULL && ifp->if_flags & IFF_DEBUG) {
 		device_printf (dev, "NDIS NUMERRORS: %x\n", numerrors);
 		va_start(ap, numerrors);
 		for (i = 0; i < numerrors; i++)
@@ -1359,6 +1360,10 @@
 
 	block = (ndis_miniport_block *)adapter;
 	sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
+	if (sc->ifp == NULL) {
+		*status = NDIS_STATUS_FAILURE;
+		return;
+	}
 
 #ifdef IFP2ENADDR
 	if (bcmp(IFP2ENADDR(sc->ifp), empty, ETHER_ADDR_LEN) == 0)
@@ -2661,20 +2666,11 @@
 	return(KeSynchronizeExecution(intr->ni_introbj, syncfunc, syncctx));
 }
 
-/*
- * Return the number of 100 nanosecond intervals since
- * January 1, 1601. (?!?!)
- */
 static void
 NdisGetCurrentSystemTime(tval)
 	uint64_t		*tval;
 {
-	struct timespec		ts;
-
-	nanotime(&ts);
-	*tval = (uint64_t)ts.tv_nsec / 100 + (uint64_t)ts.tv_sec * 10000000 +
-	    11644473600;
-
+	ntoskrnl_time(tval);
 	return;
 }
 
@@ -3288,6 +3284,14 @@
 	return;
 }
 
+static void
+NdisIMCopySendPerPacketInfo(dpkt, spkt)
+	ndis_packet		*dpkt;
+	ndis_packet		*spkt;
+{
+	memcpy(&dpkt->np_ext, &spkt->np_ext, sizeof(ndis_packet_extension));
+}
+
 static ndis_status
 NdisMRegisterDevice(handle, devname, symname, majorfuncs, devobj, devhandle)
 	ndis_handle		handle;
@@ -3365,6 +3369,7 @@
 image_patch_table ndis_functbl[] = {
 	IMPORT_SFUNC(NdisCopyFromPacketToPacket, 6),
 	IMPORT_SFUNC(NdisCopyFromPacketToPacketSafe, 7),
+	IMPORT_SFUNC(NdisIMCopySendPerPacketInfo, 2),
 	IMPORT_SFUNC(NdisScheduleWorkItem, 1),
 	IMPORT_SFUNC(NdisMIndicateStatusComplete, 1),
 	IMPORT_SFUNC(NdisMIndicateStatus, 4),

==== //depot/projects/dtrace7/src/sys/compat/ndis/subr_ntoskrnl.c#5 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/compat/ndis/subr_ntoskrnl.c,v 1.90.2.3 2008/08/21 05:13:55 weongyo Exp $");
+__FBSDID("$FreeBSD: src/sys/compat/ndis/subr_ntoskrnl.c,v 1.90.2.4 2008/08/22 03:08:31 thompsa Exp $");
 
 #include <sys/ctype.h>
 #include <sys/unistd.h>
@@ -218,7 +218,8 @@
 static long atol (const char *);
 static int rand(void);
 static void srand(unsigned int);
-static void ntoskrnl_time(uint64_t *);
+static void KeQuerySystemTime(uint64_t *);
+static uint32_t KeTickCount(void);
 static uint8_t IoIsWdmVersionAvailable(uint8_t, uint8_t);
 static void ntoskrnl_thrfunc(void *);
 static ndis_status PsCreateSystemThread(ndis_handle *,
@@ -243,11 +244,13 @@
 static void *ntoskrnl_memmove(void *, void *, size_t);
 static void *ntoskrnl_memchr(void *, unsigned char, size_t);
 static char *ntoskrnl_strstr(char *, char *);
+static char *ntoskrnl_strncat(char *, char *, size_t);
 static int ntoskrnl_toupper(int);
 static int ntoskrnl_tolower(int);
 static funcptr ntoskrnl_findwrap(funcptr);
 static uint32_t DbgPrint(char *, ...);
 static void DbgBreakPoint(void);
+static void KeBugCheckEx(uint32_t, u_long, u_long, u_long, u_long);
 static void dummy(void);
 
 static struct mtx ntoskrnl_dispatchlock;
@@ -478,6 +481,29 @@
 	return ((char *)s);
 }
 
+/* Taken from libc */
+static char *
+ntoskrnl_strncat(dst, src, n)
+	char		*dst;
+	char		*src;
+	size_t		n;
+{
+	if (n != 0) {
+		char *d = dst;
+		const char *s = src;
+
+		while (*d != 0)
+			d++;
+		do {
+			if ((*d = *s++) == 0)
+				break;
+			d++;
+		} while (--n != 0);
+		*d = 0;
+        }
+        return (dst);
+}
+
 static int
 ntoskrnl_toupper(c)
 	int			c;
@@ -1577,7 +1603,11 @@
 	return;
 }
 
-static void 
+/*
+ * Return the number of 100 nanosecond intervals since
+ * January 1, 1601. (?!?!)
+ */
+void
 ntoskrnl_time(tval)
 	uint64_t                *tval;
 {
@@ -1585,11 +1615,27 @@
 
 	nanotime(&ts);
 	*tval = (uint64_t)ts.tv_nsec / 100 + (uint64_t)ts.tv_sec * 10000000 +
-	    11644473600;
+	    11644473600 * 10000000; /* 100ns ticks from 1601 to 1970 */
 
 	return;
 }
 
+static void
+KeQuerySystemTime(current_time)
+	uint64_t		*current_time;
+{
+	ntoskrnl_time(current_time);
+}
+
+static uint32_t
+KeTickCount(void)
+{
+	struct timeval tv;
+	getmicrouptime(&tv);
+	return tvtohz(&tv);
+}
+
+
 /*
  * KeWaitForSingleObject() is a tricky beast, because it can be used
  * with several different object types: semaphores, timers, events,
@@ -3605,6 +3651,17 @@
 }
 
 static void
+KeBugCheckEx(code, param1, param2, param3, param4)
+    uint32_t			code;
+    u_long			param1;
+    u_long			param2;
+    u_long			param3;
+    u_long			param4;
+{
+	panic("KeBugCheckEx: STOP 0x%X", code);
+}
+
+static void
 ntoskrnl_timercall(arg)
 	void			*arg;
 {
@@ -4229,6 +4286,7 @@
 	IMPORT_CFUNC_MAP(_vsnprintf, vsnprintf, 0),
 	IMPORT_CFUNC(DbgPrint, 0),
 	IMPORT_SFUNC(DbgBreakPoint, 0),
+	IMPORT_SFUNC(KeBugCheckEx, 5),
 	IMPORT_CFUNC(strncmp, 0),
 	IMPORT_CFUNC(strcmp, 0),
 	IMPORT_CFUNC_MAP(stricmp, strcasecmp, 0),
@@ -4238,6 +4296,7 @@
 	IMPORT_CFUNC_MAP(toupper, ntoskrnl_toupper, 0),
 	IMPORT_CFUNC_MAP(tolower, ntoskrnl_tolower, 0),
 	IMPORT_CFUNC_MAP(strstr, ntoskrnl_strstr, 0),
+	IMPORT_CFUNC_MAP(strncat, ntoskrnl_strncat, 0),
 	IMPORT_CFUNC_MAP(strchr, index, 0),
 	IMPORT_CFUNC_MAP(strrchr, rindex, 0),
 	IMPORT_CFUNC(memcpy, 0),
@@ -4380,6 +4439,8 @@
 	IMPORT_SFUNC(IoWMIRegistrationControl, 2),
 	IMPORT_SFUNC(WmiQueryTraceInformation, 5),
 	IMPORT_CFUNC(WmiTraceMessage, 0),
+	IMPORT_SFUNC(KeQuerySystemTime, 1),
+	IMPORT_CFUNC(KeTickCount, 0),
 
 	/*
 	 * This last entry is a catch-all for any function we haven't

==== //depot/projects/dtrace7/src/sys/conf/files#17 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/files,v 1.1243.2.35 2008/08/11 20:43:01 jfv Exp $
+# $FreeBSD: src/sys/conf/files,v 1.1243.2.36 2008/08/22 01:23:39 kmacy Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -517,7 +517,6 @@
 dev/cs/if_cs_pccard.c		optional cs pccard
 dev/cxgb/cxgb_main.c		optional cxgb pci
 dev/cxgb/cxgb_offload.c		optional cxgb pci
-dev/cxgb/cxgb_lro.c		optional cxgb pci
 dev/cxgb/cxgb_sge.c		optional cxgb pci
 dev/cxgb/cxgb_multiq.c		optional cxgb pci
 dev/cxgb/common/cxgb_mc5.c	optional cxgb pci

==== //depot/projects/dtrace7/src/sys/dev/cxgb/cxgb_adapter.h#4 (text+ko) ====

@@ -26,7 +26,7 @@
 POSSIBILITY OF SUCH DAMAGE.
 
 
-$FreeBSD: src/sys/dev/cxgb/cxgb_adapter.h,v 1.20.2.2 2008/07/28 23:37:33 kmacy Exp $
+$FreeBSD: src/sys/dev/cxgb/cxgb_adapter.h,v 1.20.2.4 2008/08/22 01:28:57 kmacy Exp $
 
 
 ***************************************************************************/
@@ -48,6 +48,7 @@
 #include <net/if.h>
 #include <net/if_media.h>
 #include <net/if_dl.h>
+#include <netinet/tcp_lro.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -168,32 +169,9 @@
 #define WR_LEN (WR_FLITS * 8)
 #define PIO_LEN (WR_LEN - sizeof(struct cpl_tx_pkt_lso))
 
-
-/* careful, the following are set on priv_flags and must not collide with
- * IFF_ flags!
- */
-enum {
-	LRO_ACTIVE = (1 << 8),
-};
-
-/* Max concurrent LRO sessions per queue set */
-#define MAX_LRO_SES 8
-
-struct t3_lro_session {
-	struct mbuf *head;
-	struct mbuf *tail;
-	uint32_t seq;
-	uint16_t ip_len;
-	uint16_t mss;
-	uint16_t vtag;
-	uint8_t npkts;
-};
-
 struct lro_state {
 	unsigned short enabled;
-	unsigned short active_idx;
-	unsigned int nactive;
-	struct t3_lro_session sess[MAX_LRO_SES];
+	struct lro_ctrl ctrl;
 };
 
 #define RX_BUNDLE_SIZE 8
@@ -312,12 +290,9 @@
 	SGE_PSTAT_TX_CSUM,          /* # of TX checksum offloads */
 	SGE_PSTAT_VLANEX,           /* # of VLAN tag extractions */
 	SGE_PSTAT_VLANINS,          /* # of VLAN tag insertions */
-	SGE_PSTATS_LRO_QUEUED,	    /* # of LRO appended packets */
-	SGE_PSTATS_LRO_FLUSHED,	    /* # of LRO flushed packets */
-	SGE_PSTATS_LRO_X_STREAMS,   /* # of exceeded LRO contexts */
 };
 
-#define SGE_PSTAT_MAX (SGE_PSTATS_LRO_X_STREAMS+1)
+#define SGE_PSTAT_MAX (SGE_PSTAT_VLANINS+1)
 
 #define QS_EXITING              0x1
 #define QS_RUNNING              0x2
@@ -401,6 +376,8 @@
 	struct callout		cxgb_tick_ch;
 	struct callout		sge_timer_ch;
 
+	unsigned int		check_task_cnt;
+
 	/* Register lock for use by the hardware layer */
 	struct mtx		mdio_lock;
 	struct mtx		elmer_lock;
@@ -582,16 +559,18 @@
 void t3_free_tx_desc(struct sge_txq *q, int n);
 void t3_free_tx_desc_all(struct sge_txq *q);
 
-void t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m,
-    int ethpad, uint32_t rss_hash, uint32_t rss_csum, int lro);
 void t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad);
-void t3_lro_flush(adapter_t *adap, struct sge_qset *qs, struct lro_state *state);
 
 void t3_add_attach_sysctls(adapter_t *sc);
 void t3_add_configured_sysctls(adapter_t *sc);
 int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
     unsigned char *data);
 void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p);
+
+#define CXGB_TICKS(a) ((a)->params.linkpoll_period ? \
+    (hz * (a)->params.linkpoll_period) / 10 : \
+    (a)->params.stats_update_period * hz)
+
 /*
  * XXX figure out how we can return this to being private to sge
  */

==== //depot/projects/dtrace7/src/sys/dev/cxgb/cxgb_main.c#5 (text+ko) ====

@@ -28,7 +28,7 @@
 ***************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.36.2.3 2008/07/28 23:37:33 kmacy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.36.2.5 2008/08/22 01:28:57 kmacy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -624,11 +624,6 @@
 	if ((error = bus_generic_attach(dev)) != 0)
 		goto out;
 
-	/*
-	 * XXX need to poll for link status
-	 */
-	sc->params.stats_update_period = 1;
-
 	/* initialize sge private state */
 	t3_sge_init_adapter(sc);
 
@@ -648,7 +643,7 @@
 	    G_FW_VERSION_MICRO(vers));
 
 	device_printf(sc->dev, "Firmware Version %s\n", &sc->fw_version[0]);
-	callout_reset(&sc->cxgb_tick_ch, hz, cxgb_tick, sc);
+	callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc);
 	t3_add_attach_sysctls(sc);
 out:
 	if (error)
@@ -903,9 +898,9 @@
 
 
 #ifdef TSO_SUPPORTED
-#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU)
+#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO)
 /* Don't enable TSO6 yet */
-#define CXGB_CAP_ENABLE (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO4 | IFCAP_JUMBO_MTU)
+#define CXGB_CAP_ENABLE (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO4 | IFCAP_JUMBO_MTU | IFCAP_LRO)
 #else
 #define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_JUMBO_MTU)
 /* Don't enable TSO6 yet */
@@ -1927,7 +1922,25 @@
 	return (error);
 }
 
+/*
+ * Mark lro enabled or disabled in all qsets for this port
+ */
 static int
+cxgb_set_lro(struct port_info *p, int enabled)
+{
+	int i;
+	struct adapter *adp = p->adapter;
+	struct sge_qset *q;
+
+	PORT_LOCK_ASSERT_OWNED(p);
+	for (i = 0; i < p->nqsets; i++) {
+		q = &adp->sge.qs[p->first_qset + i];
+		q->lro.enabled = (enabled != 0);
+	}
+	return (0);
+}
+
+static int
 cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
 {
 	struct port_info *p = ifp->if_softc;
@@ -2012,6 +2025,12 @@
 				error = EINVAL;
 			}
 		}
+		if (mask & IFCAP_LRO) {
+			ifp->if_capenable ^= IFCAP_LRO;
+
+			/* Safe to do this even if cxgb_up not called yet */
+			cxgb_set_lro(p, ifp->if_capenable & IFCAP_LRO);
+		}
 		if (mask & IFCAP_VLAN_HWTAGGING) {
 			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
 			reinit = ifp->if_drv_flags & IFF_DRV_RUNNING;
@@ -2177,7 +2196,7 @@
 		return;
 
 	taskqueue_enqueue(sc->tq, &sc->tick_task);
-	callout_reset(&sc->cxgb_tick_ch, hz, cxgb_tick, sc);
+	callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc);
 }
 
 static void
@@ -2185,6 +2204,7 @@
 {
 	adapter_t *sc = (adapter_t *)arg;
 	const struct adapter_params *p = &sc->params;
+	int i;
 
 	if(sc->flags & CXGB_SHUTDOWN)
 		return;
@@ -2193,6 +2213,8 @@
 	if (p->linkpoll_period)
 		check_link_status(sc);
 
+	sc->check_task_cnt++;
+
 	/*
 	 * adapter lock can currently only be acquired after the
 	 * port lock
@@ -2201,6 +2223,19 @@
 
 	if (p->rev == T3_REV_B2 && p->nports < 4 && sc->open_device_map) 
 		check_t3b2_mac(sc);
+
+	/* Update MAC stats if it's time to do so */
+	if (!p->linkpoll_period ||
+	    (sc->check_task_cnt * p->linkpoll_period) / 10 >=
+	    p->stats_update_period) {
+		for_each_port(sc, i) {
+			struct port_info *port = &sc->port[i];
+			PORT_LOCK(port);
+			t3_mac_update_stats(&port->mac);
+			PORT_UNLOCK(port);
+		}
+		sc->check_task_cnt = 0;
+	}
 }
 
 static void

==== //depot/projects/dtrace7/src/sys/dev/cxgb/cxgb_sge.c#4 (text+ko) ====

@@ -30,7 +30,7 @@
 
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_sge.c,v 1.30.2.2 2008/07/28 23:37:33 kmacy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_sge.c,v 1.30.2.5 2008/08/22 01:30:39 kmacy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -195,7 +195,6 @@
 };
 
 
-static int lro_default = 0;
 int cxgb_debug = 0;
 
 static void sge_timer_cb(void *arg);
@@ -1335,17 +1334,12 @@
 		
 		return (0);		
 	} else if (tso_info) {
-		int undersized, eth_type;
+		int min_size = TCPPKTHDRSIZE, eth_type, tagged;
 		struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)txd;
 		struct ip *ip;
 		struct tcphdr *tcp;
-		char *pkthdr, tmp[TCPPKTHDRSIZE];
-		struct mbuf_vec *mv;
-		struct mbuf_iovec *tmpmi;
+		char *pkthdr;
 
-		mv = mtomv(m0);
-		tmpmi = mv->mv_vec;
-		
 		txd->flit[2] = 0;
 		GET_VTAG(cntrl, m0);
 		cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT_LSO);
@@ -1354,21 +1348,29 @@
 		hdr->len = htonl(mlen | 0x80000000);
 
 		DPRINTF("tso buf len=%d\n", mlen);
-		undersized = (((tmpmi->mi_len < TCPPKTHDRSIZE) &&
-			(m0->m_flags & M_VLANTAG)) ||
-		    (tmpmi->mi_len < TCPPKTHDRSIZE - ETHER_VLAN_ENCAP_LEN));
+
+		tagged = m0->m_flags & M_VLANTAG;
+		if (!tagged)
+			min_size -= ETHER_VLAN_ENCAP_LEN;
 
-		if (__predict_false(undersized)) {
-			pkthdr = tmp;
-			if (mi)
-				dump_mi(mi);
+		if (__predict_false(mlen < min_size)) {
 			printf("mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x",
-			    m0, mlen, m0->m_pkthdr.tso_segsz, m0->m_pkthdr.csum_flags, m0->m_flags);
-			panic("discontig packet - fixxorz");
-		} else 
-			pkthdr = m0->m_data;
+			    m0, mlen, m0->m_pkthdr.tso_segsz,
+			    m0->m_pkthdr.csum_flags, m0->m_flags);
+			panic("tx tso packet too small");
+		}
+
+		/* Make sure that ether, ip, tcp headers are all in m0 */
+		if (__predict_false(m0->m_len < min_size)) {
+			m0 = m_pullup(m0, min_size);
+			if (__predict_false(m0 == NULL)) {
+				/* XXX panic probably an overreaction */
+				panic("couldn't fit header into mbuf");
+			}
+		}
+		pkthdr = m0->m_data;
 
-		if (__predict_false(m0->m_flags & M_VLANTAG)) {
+		if (tagged) {
 			eth_type = CPL_ETH_II_VLAN;
 			ip = (struct ip *)(pkthdr + ETHER_HDR_LEN +
 			    ETHER_VLAN_ENCAP_LEN);
@@ -1771,6 +1773,8 @@
 		MTX_DESTROY(&q->rspq.lock);
 	}
 
+	tcp_lro_free(&q->lro.ctrl);
+
 	bzero(q, sizeof(*q));
 }
 
@@ -2383,7 +2387,18 @@
 	q->fl[1].zone = zone_jumbop;
 	q->fl[1].type = EXT_JUMBOP;
 #endif
-	q->lro.enabled = lro_default;
+
+	/*
+	 * We allocate and setup the lro_ctrl structure irrespective of whether
+	 * lro is available and/or enabled.
+	 */
+	q->lro.enabled = !!(pi->ifp->if_capenable & IFCAP_LRO);
+	ret = tcp_lro_init(&q->lro.ctrl);
+	if (ret) {
+		printf("error %d from tcp_lro_init\n", ret);
+		goto err;
+	}
+	q->lro.ctrl.ifp = pi->ifp;
 
 	mtx_lock_spin(&sc->sge.reg_lock);
 	ret = -t3_sge_init_rspcntxt(sc, q->rspq.cntxt_id, irq_vec_idx,
@@ -2462,6 +2477,11 @@
 	return (ret);
 }
 
+/*
+ * Remove CPL_RX_PKT headers from the mbuf and reduce it to a regular mbuf with
+ * ethernet data.  Hardware assistance with various checksums and any vlan tag
+ * will also be taken into account here.
+ */
 void
 t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad)
 {
@@ -2499,8 +2519,6 @@
 	m->m_pkthdr.len -= (sizeof(*cpl) + ethpad);
 	m->m_len -= (sizeof(*cpl) + ethpad);
 	m->m_data += (sizeof(*cpl) + ethpad);
-
-	(*ifp->if_input)(ifp, m);
 }
 
 static void
@@ -2785,7 +2803,8 @@
 	struct rsp_desc *r = &rspq->desc[rspq->cidx];
 	int budget_left = budget;
 	unsigned int sleeping = 0;
-	int lro = qs->lro.enabled;
+	int lro_enabled = qs->lro.enabled;
+	struct lro_ctrl *lro_ctrl = &qs->lro.ctrl;
 	struct mbuf *offload_mbufs[RX_BUNDLE_SIZE];
 	int ngathered = 0;
 #ifdef DEBUG	
@@ -2898,13 +2917,25 @@
 			DPRINTF("received offload packet\n");
 			
 		} else if (eth && eop) {
-			prefetch(mtod(rspq->rspq_mh.mh_head, uint8_t *)); 
-			prefetch(mtod(rspq->rspq_mh.mh_head, uint8_t *) + L1_CACHE_BYTES);
+			struct mbuf *m = rspq->rspq_mh.mh_head;
+			prefetch(mtod(m, uint8_t *)); 
+			prefetch(mtod(m, uint8_t *) + L1_CACHE_BYTES);
 
-			t3_rx_eth_lro(adap, rspq, rspq->rspq_mh.mh_head, ethpad,
-			    rss_hash, rss_csum, lro);
+			t3_rx_eth(adap, rspq, m, ethpad);
+			if (lro_enabled && lro_ctrl->lro_cnt &&
+			    (tcp_lro_rx(lro_ctrl, m, 0) == 0)) {
+				/* successfully queue'd for LRO */
+			} else {
+				/*
+				 * LRO not enabled, packet unsuitable for LRO,
+				 * or unable to queue.  Pass it up right now in
+				 * either case.
+				 */
+				struct ifnet *ifp = m->m_pkthdr.rcvif;
+				(*ifp->if_input)(ifp, m);
+			}
 			DPRINTF("received tunnel packet\n");
-				rspq->rspq_mh.mh_head = NULL;
+			rspq->rspq_mh.mh_head = NULL;
 
 		}
 		__refill_fl_lt(adap, &qs->fl[0], 32);
@@ -2913,8 +2944,14 @@
 	}
 
 	deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered);
-	t3_lro_flush(adap, qs, &qs->lro);
-	
+
+	/* Flush LRO */
+	while (!SLIST_EMPTY(&lro_ctrl->lro_active)) {
+		struct lro_entry *queued = SLIST_FIRST(&lro_ctrl->lro_active);
+		SLIST_REMOVE_HEAD(&lro_ctrl->lro_active, next);
+		tcp_lro_flush(lro_ctrl, queued);
+	}
+
 	if (sleeping)
 		check_ring_db(adap, qs, sleeping);
 
@@ -3229,34 +3266,6 @@
 }
 
 static int
-t3_lro_enable(SYSCTL_HANDLER_ARGS)
-{
-	adapter_t *sc;
-	int i, j, enabled, err, nqsets = 0;
-
-#ifndef LRO_WORKING
-	return (0);
-#endif	
-	sc = arg1;
-	enabled = sc->sge.qs[0].lro.enabled;
-        err = sysctl_handle_int(oidp, &enabled, arg2, req);
-
-	if (err != 0) 
-		return (err);
-	if (enabled == sc->sge.qs[0].lro.enabled)
-		return (0);
-
-	for (i = 0; i < sc->params.nports; i++) 
-		for (j = 0; j < sc->port[i].nqsets; j++)
-			nqsets++;
-	
-	for (i = 0; i < nqsets; i++) 
-		sc->sge.qs[i].lro.enabled = enabled;
-	
-	return (0);
-}
-
-static int
 t3_set_coalesce_usecs(SYSCTL_HANDLER_ARGS)
 {
 	adapter_t *sc = arg1;
@@ -3317,12 +3326,6 @@
 	    "firmware_version",
 	    CTLFLAG_RD, &sc->fw_version,
 	    0, "firmware version");
-
-	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 
-	    "enable_lro",
-	    CTLTYPE_INT|CTLFLAG_RW, sc,
-	    0, t3_lro_enable,
-	    "I", "enable large receive offload");
 	SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
 	    "hw_revision",
 	    CTLFLAG_RD, &sc->params.rev,
@@ -3375,7 +3378,25 @@
 	"txq_eth",
 	"txq_ofld",
 	"txq_ctrl"	
-};		
+};
+
+static int
+sysctl_handle_macstat(SYSCTL_HANDLER_ARGS)
+{
+	struct port_info *p = arg1;
+	uint64_t *parg;
+
+	if (!p)
+		return (EINVAL);
+
+	parg = (uint64_t *) ((uint8_t *)&p->mac.stats + arg2);
+
+	PORT_LOCK(p);
+	t3_mac_update_stats(&p->mac);
+	PORT_UNLOCK(p);
+
+	return (sysctl_handle_quad(oidp, parg, 0, req));
+}
 
 void
 t3_add_configured_sysctls(adapter_t *sc)
@@ -3397,6 +3418,7 @@
 		struct port_info *pi = &sc->port[i];
 		struct sysctl_oid *poid;
 		struct sysctl_oid_list *poidlist;
+		struct mac_stats *mstats = &pi->mac.stats;
 		
 		snprintf(pi->namebuf, PORT_NAME_LEN, "port%d", i);
 		poid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, 
@@ -3405,11 +3427,11 @@
 		SYSCTL_ADD_INT(ctx, poidlist, OID_AUTO, 
 		    "nqsets", CTLFLAG_RD, &pi->nqsets,
 		    0, "#queue sets");
-		
+
 		for (j = 0; j < pi->nqsets; j++) {
 			struct sge_qset *qs = &sc->sge.qs[pi->first_qset + j];
-			struct sysctl_oid *qspoid, *rspqpoid, *txqpoid, *ctrlqpoid;
-			struct sysctl_oid_list *qspoidlist, *rspqpoidlist, *txqpoidlist, *ctrlqpoidlist;
+			struct sysctl_oid *qspoid, *rspqpoid, *txqpoid, *ctrlqpoid, *lropoid;
+			struct sysctl_oid_list *qspoidlist, *rspqpoidlist, *txqpoidlist, *ctrlqpoidlist, *lropoidlist;
 			struct sge_txq *txq = &qs->txq[TXQ_ETH];
 			
 			snprintf(qs->namebuf, QS_NAME_LEN, "qs%d", j);
@@ -3430,6 +3452,10 @@
 			    txq_names[2], CTLFLAG_RD, NULL, "ctrlq statistics");
 			ctrlqpoidlist = SYSCTL_CHILDREN(ctrlqpoid);
 
+			lropoid = SYSCTL_ADD_NODE(ctx, qspoidlist, OID_AUTO, 
+			    "lro_stats", CTLFLAG_RD, NULL, "LRO statistics");
+			lropoidlist = SYSCTL_CHILDREN(lropoid);
+
 			SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "size",
 			    CTLFLAG_RD, &qs->rspq.size,
 			    0, "#entries in response queue");
@@ -3521,11 +3547,95 @@
 			    CTLTYPE_STRING | CTLFLAG_RD, &qs->txq[TXQ_CTRL],
 			    0, t3_dump_txq_ctrl, "A", "dump of the transmit queue");
 
+			SYSCTL_ADD_INT(ctx, lropoidlist, OID_AUTO, "lro_queued",
+			    CTLFLAG_RD, &qs->lro.ctrl.lro_queued, 0, NULL);
+			SYSCTL_ADD_INT(ctx, lropoidlist, OID_AUTO, "lro_flushed",
+			    CTLFLAG_RD, &qs->lro.ctrl.lro_flushed, 0, NULL);
+			SYSCTL_ADD_INT(ctx, lropoidlist, OID_AUTO, "lro_bad_csum",
+			    CTLFLAG_RD, &qs->lro.ctrl.lro_bad_csum, 0, NULL);
+			SYSCTL_ADD_INT(ctx, lropoidlist, OID_AUTO, "lro_cnt",
+			    CTLFLAG_RD, &qs->lro.ctrl.lro_cnt, 0, NULL);
+		}
+
+		/* Now add a node for mac stats. */
+		poid = SYSCTL_ADD_NODE(ctx, poidlist, OID_AUTO, "mac_stats",
+		    CTLFLAG_RD, NULL, "MAC statistics");
+		poidlist = SYSCTL_CHILDREN(poid);
 
-			
+		/*
+		 * We (ab)use the length argument (arg2) to pass on the offset
+		 * of the data that we are interested in.  This is only required
+		 * for the quad counters that are updated from the hardware (we
+		 * make sure that we return the latest value).
+		 * sysctl_handle_macstat first updates *all* the counters from
+		 * the hardware, and then returns the latest value of the
+		 * requested counter.  Best would be to update only the
+		 * requested counter from hardware, but t3_mac_update_stats()
+		 * hides all the register details and we don't want to dive into
+		 * all that here.
+		 */
+#define CXGB_SYSCTL_ADD_QUAD(a)	SYSCTL_ADD_OID(ctx, poidlist, OID_AUTO, #a, \
+    (CTLTYPE_QUAD | CTLFLAG_RD), pi, offsetof(struct mac_stats, a), \
+    sysctl_handle_macstat, "QU", 0)
+		CXGB_SYSCTL_ADD_QUAD(tx_octets);
+		CXGB_SYSCTL_ADD_QUAD(tx_octets_bad);
+		CXGB_SYSCTL_ADD_QUAD(tx_frames);
+		CXGB_SYSCTL_ADD_QUAD(tx_mcast_frames);

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list