From owner-p4-projects@FreeBSD.ORG Fri Aug 22 06:57:45 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0AA9A106568F; Fri, 22 Aug 2008 06:57:45 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C23A6106568D for ; Fri, 22 Aug 2008 06:57:44 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id AF03E8FC08 for ; Fri, 22 Aug 2008 06:57:44 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m7M6viuw098558 for ; Fri, 22 Aug 2008 06:57:44 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m7M6viR7098556 for perforce@freebsd.org; Fri, 22 Aug 2008 06:57:44 GMT (envelope-from jb@freebsd.org) Date: Fri, 22 Aug 2008 06:57:44 GMT Message-Id: <200808220657.m7M6viR7098556@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 148085 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Aug 2008 06:57:45 -0000 http://perforce.freebsd.org/chv.cgi?CH=148085 Change 148085 by jb@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 @@ -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 -__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 -__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 #include @@ -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 #include #include +#include #include #include @@ -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 -__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 #include @@ -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 -__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 #include @@ -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) <<<