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