"OPEN TOE" submission from Chelsio Communications.

The following items have been addressed:
- cleaned up indentation.
- cleaned up comments.
- cleaned up c-styles.
- using EXPORT_SYMBOL_GPL instead of EXPORT_SYMBOL
- removed 2.4 compatibility.
- created TCP_OFFLOAD config option.
- moved #defines to appropriate files.
- removed obfuscating macros.
- included necessary definitions instead of struct.
- made IS_OFFLOADED an inline function instead of macro.

The following items are currently being worked on:
- use sysfs instead of procfs.
- addressing the use of semaphores in 'register_tom'.
- use RCU, need to look at this.
- use inline function instead of TOEDEV macro, requires some work.

Comments:
- static was removed from functions '__tcp_inherit_port' & '__tcp_v4_hash' because these are called outside of tcp_ipv4.c from the TOM driver.

Signed-off-by: Scott Bardone <[EMAIL PROTECTED]>

diff -Naur linux-2.6.13-rc6-git3/include/linux/netdevice.h 
linux-2.6.13-rc6-git3.patched/include/linux/netdevice.h
--- linux-2.6.13-rc6-git3/include/linux/netdevice.h     2005-08-07 
11:18:56.000000000 -0700
+++ linux-2.6.13-rc6-git3.patched/include/linux/netdevice.h     2005-08-11 
21:28:36.000000000 -0700
@@ -408,6 +408,9 @@
 #define NETIF_F_VLAN_CHALLENGED        1024    /* Device cannot handle VLAN 
packets */
 #define NETIF_F_TSO            2048    /* Can offload TCP/IP segmentation */
 #define NETIF_F_LLTX           4096    /* LockLess TX */
+#ifdef CONFIG_TCP_OFFLOAD
+#define NETIF_F_TCPIP_OFFLOAD  65536   /* Can offload TCP/IP */
+#endif
 
        /* Called after device is detached from network. */
        void                    (*uninit)(struct net_device *dev);
diff -Naur linux-2.6.13-rc6-git3/include/linux/tcp_diag.h 
linux-2.6.13-rc6-git3.patched/include/linux/tcp_diag.h
--- linux-2.6.13-rc6-git3/include/linux/tcp_diag.h      2005-08-07 
11:18:56.000000000 -0700
+++ linux-2.6.13-rc6-git3.patched/include/linux/tcp_diag.h      2005-08-11 
21:28:36.000000000 -0700
@@ -4,6 +4,11 @@
 /* Just some random number */
 #define TCPDIAG_GETSOCK 18
 
+/* TOE API */
+#ifdef CONFIG_TCP_OFFLOAD
+#define TCPDIAG_OFFLOAD 5
+#endif
+
 /* Socket identity */
 struct tcpdiag_sockid
 {
diff -Naur linux-2.6.13-rc6-git3/include/linux/tcp.h 
linux-2.6.13-rc6-git3.patched/include/linux/tcp.h
--- linux-2.6.13-rc6-git3/include/linux/tcp.h   2005-08-07 11:18:56.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/include/linux/tcp.h   2005-08-11 
21:28:36.000000000 -0700
@@ -235,6 +235,10 @@
        return (struct tcp_request_sock *)req;
 }
 
+#ifdef CONFIG_TCP_OFFLOAD
+struct toe_funcs;
+#endif
+
 struct tcp_sock {
        /* inet_sock has to be the first member of tcp_sock */
        struct inet_sock        inet;
@@ -342,6 +346,10 @@
 
        struct tcp_func         *af_specific;   /* Operations which are 
AF_INET{4,6} specific   */
 
+#ifdef CONFIG_TCP_OFFLOAD
+       struct toe_funcs        *toe_specific; /* Operations overriden by TOEs 
*/
+#endif
+
        __u32   rcv_wnd;        /* Current receiver window              */
        __u32   rcv_wup;        /* rcv_nxt on last window update sent   */
        __u32   write_seq;      /* Tail(+1) of data held in tcp send buffer */
diff -Naur linux-2.6.13-rc6-git3/include/linux/toedev.h 
linux-2.6.13-rc6-git3.patched/include/linux/toedev.h
--- linux-2.6.13-rc6-git3/include/linux/toedev.h        1969-12-31 
16:00:00.000000000 -0800
+++ linux-2.6.13-rc6-git3.patched/include/linux/toedev.h        2005-08-11 
22:37:03.947800000 -0700
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ *                                                                           *
+ * File:                                                                     *
+ *  toedev.h                                                                 *
+ *                                                                           *
+ * Description:                                                              *
+ *  TOE device definitions.                                                  *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or modify      *
+ * it under the terms of the GNU General Public License, version 2, as       *
+ * published by the Free Software Foundation.                                *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License along   *
+ * with this program; if not, write to the Free Software Foundation, Inc.,   *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ *                                                                           *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.                     *
+ *                                                                           *
+ * http://www.chelsio.com                                                    *
+ *                                                                           *
+ * Copyright (c) 2003 - 2005 Chelsio Communications, Inc.                    *
+ * All rights reserved.                                                      *
+ *                                                                           *
+ * Maintainers: [EMAIL PROTECTED]                                      *
+ *                                                                           *
+ * Authors: Dimitrios Michailidis   <[EMAIL PROTECTED]>                        
 *
+ *                                                                           *
+ * History:                                                                  *
+ *                                                                           *
+ ****************************************************************************/
+/* $Date: 2005/08/09 18:58:21 $ $RCSfile: toedev.h,v $ $Revision: 1.4 $ */
+
+#ifndef _TOEDEV_H_
+#define _TOEDEV_H_
+
+#include <linux/list.h>
+#include <asm/atomic.h>
+#include <linux/netdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <net/neighbour.h>
+#include <net/sock.h>
+
+#define TOENAMSIZ 16
+
+/* Get the toedev associated with a net_device */
+#define TOEDEV(netdev) ((struct toedev *)(netdev)->ec_ptr)
+
+/* TOE type ids */
+enum {
+       TOE_ID_CHELSIO_T1  = 1,
+       TOE_ID_CHELSIO_T1C,
+       TOE_ID_CHELSIO_T3,
+};
+
+struct toe_id {
+       unsigned int id;
+       unsigned long data;
+};
+
+struct tom_info;
+
+struct toedev {
+       char name[TOENAMSIZ];               /* TOE device name */
+       struct list_head toe_list;          /* for list linking */
+       int toe_index;                      /* unique TOE device index */
+       unsigned int ttid;                  /* TOE type id */
+       unsigned long flags;                /* device flags */
+       unsigned int mtu;                   /* max size of TX offloaded data */ 
+       unsigned int nconn;                 /* max # of offloaded connections */
+       struct net_device *lldev;   /* LL device associated with TOE messages */
+       const struct tom_info *offload_mod; /* attached TCP offload module */
+       struct proc_dir_entry *proc_dir;    /* root of proc dir for this TOE */
+       int (*open)(struct toedev *dev);
+       int (*close)(struct toedev *dev);
+       int (*can_offload)(struct toedev *dev, struct sock *sk);
+       int (*connect)(struct toedev *dev, struct sock *sk);
+       int (*send)(struct toedev *dev, struct sk_buff *skb);
+       int (*recv)(struct toedev *dev, struct sk_buff **skb, int n);
+       int (*ctl)(struct toedev *dev, unsigned int req, void *data);
+       void (*neigh_update)(struct net_device *lldev,
+                            struct toedev *dev,
+                            struct neighbour *neigh, int fl);
+       void *priv;                         /* driver private data */
+       void *l2opt;                        /* optional layer 2 data */
+       void *l3opt;                        /* optional layer 3 data */
+       void *l4opt;                        /* optional layer 4 data */
+       void *ulp;                              /* ulp stuff */
+       atomic_t refcnt;                    /* reference count */
+};
+
+struct tom_info {
+       int (*attach)(struct toedev *dev, const struct toe_id *entry);
+       int (*detach)(struct toedev *dev);
+       const char *name;
+       struct toe_id *id_table;
+       struct list_head list_node;
+};
+
+/* Flags for toe_neigh_update() */
+enum {
+       NEIGH_ADDR_CHANGED = 1
+};
+
+static inline void toedev_hold(struct toedev *dev)
+{
+       atomic_inc(&dev->refcnt);
+}
+
+static inline void toedev_put(struct toedev *dev)
+{
+       atomic_dec(&dev->refcnt);
+}
+
+int register_tom(struct tom_info *t);
+int unregister_tom(struct tom_info *t);
+int register_toedev(struct toedev *dev, const char *name);
+int activate_toedev(struct toedev *dev);
+struct toedev *alloc_toedev(void);
+void toe_set_lldev(struct toedev *dev, struct net_device *lldev);
+int toe_send(struct toedev *dev, struct sk_buff *skb);
+int toe_receive_skb(struct toedev *dev, struct sk_buff **skb, int n);
+void toe_neigh_update(struct neighbour *neigh, int flags);
+#endif /* _TOEDEV_H_ */
diff -Naur linux-2.6.13-rc6-git3/include/net/offload.h 
linux-2.6.13-rc6-git3.patched/include/net/offload.h
--- linux-2.6.13-rc6-git3/include/net/offload.h 1969-12-31 16:00:00.000000000 
-0800
+++ linux-2.6.13-rc6-git3.patched/include/net/offload.h 2005-08-11 
22:37:03.998792000 -0700
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ *                                                                           *
+ * File:                                                                     *
+ *  offload.h                                                                *
+ *                                                                           *
+ * Description:                                                              *
+ *  TCP offload support.                                                     *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or modify      *
+ * it under the terms of the GNU General Public License, version 2, as       *
+ * published by the Free Software Foundation.                                *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License along   *
+ * with this program; if not, write to the Free Software Foundation, Inc.,   *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ *                                                                           *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.                     *
+ *                                                                           *
+ * http://www.chelsio.com                                                    *
+ *                                                                           *
+ * Copyright (c) 2003 - 2005 Chelsio Communications, Inc.                    *
+ * All rights reserved.                                                      *
+ *                                                                           *
+ * Maintainers: [EMAIL PROTECTED]                                      *
+ *                                                                           *
+ * Authors: Dimitrios Michailidis   <[EMAIL PROTECTED]>                        
 *
+ *                                                                           *
+ * History:                                                                  *
+ *                                                                           *
+ ****************************************************************************/
+/* $Date: 2005/08/09 18:58:21 $ $RCSfile: offload.h,v $ $Revision: 1.4 $ */
+
+#ifndef _NET_OFFLOAD_H
+#define _NET_OFFLOAD_H
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <linux/toedev.h>
+
+enum {
+       OFFLOAD_LISTEN_START,
+       OFFLOAD_LISTEN_STOP
+};
+
+/* Returns true if sk is an offloaded IPv4 TCP socket. */
+static inline int is_offloaded(struct sock *sk)
+{
+       return ((sk)->sk_family == AF_INET && (sk)->sk_prot != &tcp_prot);
+}
+
+/* Per-skb backlog handler.  Run when a socket's backlog is processed. */
+struct blog_skb_cb {
+       void (*backlog_rcv)(struct sock *sk, struct sk_buff *skb);
+       struct toedev *dev;
+};
+
+#define BLOG_SKB_CB(skb) ((struct blog_skb_cb *)(skb)->cb)
+
+/* Offload structure */
+struct tcpdiag_offload {
+       unsigned int offload_dev_idx;
+       unsigned int offload_cookie;
+       unsigned int mem;
+};
+
+struct notifier_block;
+
+/*
+ * TCP operations that a TOE wants to override but cannot through existing
+ * means.
+ */
+struct toe_funcs {
+       void (*rcv_consumed)(struct sock *sk, int consumed);
+       void (*pmtu_changed)(struct sock *sk);
+       void (*set_keepalive)(struct sock *sk, int on_off);
+       void (*tcpdiag_offload_info)(const struct sock *sk,
+                                    struct tcpdiag_offload *oinfo);
+       int  (*sendskb)(struct sock *sk, struct sk_buff *skb, int flags);
+};
+
+extern int register_listen_offload_notifier(struct notifier_block *nb);
+extern int unregister_listen_offload_notifier(struct notifier_block *nb);
+extern int tcp_listen_offload_stop(struct sock *sk);
+extern int tcp_listen_offload(struct sock *sk);
+extern int tcp_connect_offload(struct sock *sk);
+#endif /* _NET_OFFLOAD_H */
diff -Naur linux-2.6.13-rc6-git3/net/core/Makefile 
linux-2.6.13-rc6-git3.patched/net/core/Makefile
--- linux-2.6.13-rc6-git3/net/core/Makefile     2005-08-07 11:18:56.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/net/core/Makefile     2005-08-11 
21:28:37.000000000 -0700
@@ -17,3 +17,4 @@
 obj-$(CONFIG_NET_PKTGEN) += pktgen.o
 obj-$(CONFIG_NET_RADIO) += wireless.o
 obj-$(CONFIG_NETPOLL) += netpoll.o
+obj-$(CONFIG_TCP_OFFLOAD) += toedev.o
diff -Naur linux-2.6.13-rc6-git3/net/core/neighbour.c 
linux-2.6.13-rc6-git3.patched/net/core/neighbour.c
--- linux-2.6.13-rc6-git3/net/core/neighbour.c  2005-08-07 11:18:56.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/net/core/neighbour.c  2005-08-11 
21:28:37.000000000 -0700
@@ -32,6 +32,9 @@
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/random.h>
+#ifdef CONFIG_TCP_OFFLOAD
+#include <linux/toedev.h>
+#endif
 #include <linux/string.h>
 
 #define NEIGH_DEBUG 1
@@ -763,6 +766,9 @@
                        NEIGH_PRINTK2("neigh %p is suspected.\n", neigh);
                        neigh->nud_state = NUD_STALE;
                        neigh_suspect(neigh);
+#ifdef CONFIG_TCP_OFFLOAD
+                       toe_neigh_update(neigh, 0);
+#endif
                }
        } else if (state & NUD_DELAY) {
                if (time_before_eq(now, 
@@ -770,6 +776,9 @@
                        NEIGH_PRINTK2("neigh %p is now reachable.\n", neigh);
                        neigh->nud_state = NUD_REACHABLE;
                        neigh_connect(neigh);
+#ifdef CONFIG_TCP_OFFLOAD
+                       toe_neigh_update(neigh, 0);
+#endif
                        next = neigh->confirmed + neigh->parms->reachable_time;
                } else {
                        NEIGH_PRINTK2("neigh %p is probed.\n", neigh);
@@ -788,6 +797,9 @@
 
                neigh->nud_state = NUD_FAILED;
                notify = 1;
+#ifdef CONFIG_TCP_OFFLOAD
+               toe_neigh_update(neigh, 0);
+#endif
                NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
                NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
 
@@ -952,6 +964,9 @@
                if (old & NUD_CONNECTED)
                        neigh_suspect(neigh);
                neigh->nud_state = new;
+#ifdef CONFIG_TCP_OFFLOAD
+               toe_neigh_update(neigh, 0);
+#endif
                err = 0;
 #ifdef CONFIG_ARPD
                notify = old & NUD_VALID;
@@ -1031,6 +1046,9 @@
                notify = 1;
 #endif
        }
+#ifdef CONFIG_TCP_OFFLOAD
+       toe_neigh_update(neigh, lladdr != neigh->ha ? NEIGH_ADDR_CHANGED : 0);
+#endif
        if (new == old)
                goto out;
        if (new & NUD_CONNECTED)
diff -Naur linux-2.6.13-rc6-git3/net/core/toedev.c 
linux-2.6.13-rc6-git3.patched/net/core/toedev.c
--- linux-2.6.13-rc6-git3/net/core/toedev.c     1969-12-31 16:00:00.000000000 
-0800
+++ linux-2.6.13-rc6-git3.patched/net/core/toedev.c     2005-08-11 
22:37:03.965797000 -0700
@@ -0,0 +1,485 @@
+/*****************************************************************************
+ *                                                                           *
+ * File:                                                                     *
+ *  toedev.c                                                                 *
+ *                                                                           *
+ * Description:                                                              *
+ *  TOE device support infrastructure.                                       *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or modify      *
+ * it under the terms of the GNU General Public License, version 2, as       *
+ * published by the Free Software Foundation.                                *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License along   *
+ * with this program; if not, write to the Free Software Foundation, Inc.,   *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ *                                                                           *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.                     *
+ *                                                                           *
+ * http://www.chelsio.com                                                    *
+ *                                                                           *
+ * Copyright (c) 2003 - 2005 Chelsio Communications, Inc.                    *
+ * All rights reserved.                                                      *
+ *                                                                           *
+ * Maintainers: [EMAIL PROTECTED]                                      *
+ *                                                                           *
+ * Authors: Dimitrios Michailidis   <[EMAIL PROTECTED]>                        
 *
+ *                                                                           *
+ * History:                                                                  *
+ *                                                                           *
+ ****************************************************************************/
+/* $Date: 2005/08/10 01:33:18 $ $RCSfile: toedev.c,v $ $Revision: 1.5 $ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/toedev.h>
+#include <net/neighbour.h>
+#include <asm/semaphore.h>
+
+#define boot_phase 0
+
+#ifndef __raise_softirq_irqoff
+#define __raise_softirq_irqoff(nr) __cpu_raise_softirq(smp_processor_id(), nr)
+#endif
+
+static DECLARE_MUTEX(toedev_db_lock);
+static LIST_HEAD(toedev_list);
+static LIST_HEAD(tom_list);
+
+static int toedev_init(void);
+
+/*
+ * Returns the entry in the TOE id table 'table' that has a given id, or NULL
+ * if the id is not found.
+ */
+static const struct toe_id *id_find(unsigned int id,
+                                   const struct toe_id *table)
+{
+       const struct toe_id *p;
+
+       for (p = table; p->id; ++p)
+               if (p->id == id)
+                       return p;
+       return NULL;
+}
+
+/*
+ * Returns true if a TOE device is presently attached to an offload module.
+ */
+static inline int is_attached(const struct toedev *dev)
+{
+       return dev->offload_mod != NULL;
+}
+
+/*
+ * Try to attach a new TOE device to an existing TCP offload module that can
+ * handle the device's TOE id.  Returns 0 if it succeeds.
+ *
+ * Must be called with the toedev_db_lock held.
+ */
+static int toedev_attach(struct toedev *dev)
+{
+       struct tom_info *t;
+
+       list_for_each_entry(t, &tom_list, list_node) {
+               const struct toe_id *entry;
+
+               entry = id_find(dev->ttid, t->id_table);
+               if (entry && t->attach(dev, entry) == 0) {
+                       dev->offload_mod = t;
+                       return 0;
+               }
+       }
+       return -ENOPROTOOPT;
+}
+                       
+/*
+ * Register a TCP Offload Module (TOM).
+ */
+int register_tom(struct tom_info *t)
+{
+       down(&toedev_db_lock);
+       list_add(&t->list_node, &tom_list);
+       up(&toedev_db_lock);
+       return 0;
+}
+
+/*
+ * Unregister a TCP Offload Module (TOM).  Note that this does not affect any
+ * TOE devices to which the TOM is already attached.
+ */
+int unregister_tom(struct tom_info *t)
+{
+       down(&toedev_db_lock);
+       list_del(&t->list_node);
+       up(&toedev_db_lock);
+       return 0;
+}
+
+/*
+ * Find a TOE device by name.  Must be called with toedev_db_lock held.
+ */
+static struct toedev *__find_toedev_by_name(const char *name)
+{
+       struct toedev *dev;
+
+       list_for_each_entry(dev, &toedev_list, toe_list) {
+               if (!strncmp(dev->name, name, TOENAMSIZ))
+                       return dev;
+       }
+       return NULL;
+}
+
+#if 0
+/*
+ * Find a TOE device by name.
+ */
+static struct toedev *find_toedev_by_name(const char *name)
+{
+       struct toedev *dev;
+
+       down(&toedev_db_lock);
+       dev = __find_toedev_by_name(name);
+       if (dev)
+               toedev_hold(dev);
+       up(&toedev_db_lock);
+       return dev;
+}
+#endif
+
+/*
+ * Find a TOE device by index.  Must be called with toedev_db_lock held.
+ */
+static struct toedev *__find_toedev_by_index(int index)
+{
+       struct toedev *dev;
+
+       list_for_each_entry(dev, &toedev_list, toe_list) {
+               if (dev->toe_index == index)
+                       return dev;
+       }
+       return NULL;
+}
+
+/*
+ * Return true if a TOE device is already registered.
+ * Must be called with the toedev_db_lock held.
+ */
+static int toedev_registered(const struct toedev *dev)
+{
+       struct toedev *d;
+
+       list_for_each_entry(d, &toedev_list, toe_list) {
+       if (d == dev)
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Finalize the name of a TOE device by assigning values to any format strings
+ * in its name.
+ */
+static int toedev_assign_name(struct toedev *dev, const char *name, int limit)
+{
+       int i;
+
+       for (i = 0; i < limit; ++i) {
+               char s[TOENAMSIZ];
+
+               snprintf(s, sizeof(s), name, i);
+               if (!__find_toedev_by_name(s)) {
+                       strcpy(dev->name, s);
+                       return 0;
+               }
+       }
+       return -1;
+}
+
+/*
+ * Allocate a unique index for a TOE device.  We keep the index within 30 bits
+ * to allow it to be used as a sysctl index, which uses signed IDs.
+ *
+ * We don't handle index exhaustion.  Guess why.
+ */
+static int toedev_new_index(void)
+{
+       static int toe_index;
+
+       for (;;) {
+               if (++toe_index & 0xc0000000)
+                       toe_index = 1;
+               if (!__find_toedev_by_index(toe_index))
+                       return toe_index;
+       }
+}
+
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+
+static struct proc_dir_entry *toedev_proc_root;
+
+/* XXX This doesn't handle module unloading properly.  Do we need to? */
+
+static int devices_read_proc(char *buf, char **start, off_t offset,
+                            int length, int *eof, void *data)
+{
+       int len;
+       struct toedev *dev;
+       struct net_device *ndev;
+
+       len = sprintf(buf,
+               "Device           Offload Module       Interfaces\n");
+
+       down(&toedev_db_lock);
+       list_for_each_entry(dev, &toedev_list, toe_list) {
+               len += sprintf(buf + len, "%-16s %-20s", dev->name,
+                       is_attached(dev) ? dev->offload_mod->name : "<None>");
+               read_lock(&dev_base_lock);
+               for (ndev = dev_base; ndev; ndev = ndev->next) {
+                       if (TOEDEV(ndev) == dev)
+                               len += sprintf(buf + len, " %s", ndev->name);
+               }
+               read_unlock(&dev_base_lock);
+               len += sprintf(buf + len, "\n");
+               if (len >= length)
+                       break;
+       }
+       up(&toedev_db_lock);
+
+       if (len > length)
+               len = length;
+       *eof = 1;
+       return len;
+}
+
+static void toe_proc_cleanup(void)
+{
+       remove_proc_entry("devices", toedev_proc_root);
+       remove_proc_entry("net/toe", NULL);
+       toedev_proc_root = NULL;
+}
+
+static struct proc_dir_entry *create_toe_proc_dir(const char *name)
+{
+       struct proc_dir_entry *d;
+
+       if (!toedev_proc_root)
+               return NULL;
+
+       d = proc_mkdir(name, toedev_proc_root);
+       if (d)
+               d->owner = THIS_MODULE;
+       return d;
+}
+
+#if 0
+static void delete_toe_proc_dir(struct toedev *dev)
+{
+       if (dev->proc_dir) {
+               remove_proc_entry(dev->name, toedev_proc_root);
+               dev->proc_dir = NULL;
+       }
+}
+#endif
+
+static int __init toe_proc_init(void)
+{
+       struct proc_dir_entry *d;
+
+       toedev_proc_root = proc_mkdir("net/toe", NULL);
+       if (!toedev_proc_root)
+               return -ENOMEM;
+       toedev_proc_root->owner = THIS_MODULE;
+
+       d = create_proc_read_entry("devices", 0, toedev_proc_root, 
+                              devices_read_proc, NULL);
+       if (!d)
+               goto cleanup;
+       d->owner = THIS_MODULE;
+       return 0;
+
+cleanup:
+       toe_proc_cleanup();
+       return -ENOMEM;
+}
+#else
+#define toe_proc_init() 0
+#define create_toe_proc_dir(name) NULL
+#define delete_toe_proc_dir(dev)
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * Register a TOE device and try to attach an appropriate TCP offload module
+ * to it.  'name' is a template that may contain at most one %d format
+ * specifier.
+ */
+int register_toedev(struct toedev *dev, const char *name)
+{
+       int ret;
+       char *p;
+
+       if (boot_phase)
+               toedev_init();
+
+       /* Validate the name template.  Only one %d allowed. */
+       if (!name || !*name)
+               return -EINVAL;
+       p = strchr(name, '%');
+       if (p && (p[1] != 'd' || strchr(p + 2, '%')))
+               return -EINVAL;
+
+       down(&toedev_db_lock);
+       if (toedev_registered(dev)) {   /* device already registered */
+               ret = -EEXIST;
+               goto out;
+       }
+
+       if ((ret = toedev_assign_name(dev, name, 32)) != 0)
+               goto out;
+
+       dev->proc_dir = create_toe_proc_dir(dev->name);
+       dev->toe_index = toedev_new_index();
+       dev->offload_mod = NULL;
+       list_add_tail(&dev->toe_list, &toedev_list);
+       toedev_hold(dev);
+out:
+       up(&toedev_db_lock);
+       return ret;
+}
+
+/*
+ * Allocate and initialize a toedev structure.
+ */
+struct toedev *alloc_toedev(void)
+{
+       struct toedev *dev = kmalloc(sizeof(struct toedev), GFP_KERNEL);
+
+       if (dev) {
+               memset(dev, 0, sizeof(struct toedev));
+               atomic_set(&dev->refcnt, 0);
+               INIT_LIST_HEAD(&dev->toe_list);
+       }
+       return dev;
+}
+
+/*
+ * Activate a TOE device.
+ */
+int activate_toedev(struct toedev *dev)
+{
+       int ret = 0;
+
+       down(&toedev_db_lock);
+       if (!toedev_registered(dev))
+               ret = -ENODEV;
+       else if (!is_attached(dev))
+               ret = toedev_attach(dev);
+       up(&toedev_db_lock);
+       return ret;
+}
+       
+/*
+ * Set the link-layer device associated with a TOE.  For sniffing purposes any
+ * messages sent to/received from the TOE will be associated with this device.
+ */
+void toe_set_lldev(struct toedev *dev, struct net_device *lldev)
+{
+       struct net_device *olddev = dev->lldev;
+
+       if (lldev)
+               dev_hold(lldev);
+       dev->lldev = lldev;
+       if (olddev)
+               dev_put(olddev);
+}
+
+/*
+ * Sends an sk_buff to a TOE driver after dealing with any active network taps.
+ */
+int toe_send(struct toedev *dev, struct sk_buff *skb)
+{
+       int r;
+
+       local_bh_disable();
+       if (unlikely(netdev_nit)) {     /* deal with active taps */
+               skb->nh.raw = skb->data;
+               skb->dev = dev->lldev;
+               dev_queue_xmit_nit(skb, skb->dev);
+       }
+       r = dev->send(dev, skb);
+       local_bh_enable();
+       return r;
+}
+
+/*
+ *     toe_receive_skb - process n received TOE packets
+ *     @dev: the toe device
+ *     @skb: an array of offload packets
+ *     @n: the number of offload packets
+ *
+ *     Process an array of ingress offload packets.  Each packet is forwarded
+ *     to any active network taps and then passed to the toe device's receive
+ *     method.  We optimize passing packets to the receive method by passing
+ *     it the whole array at once except when there are active taps.
+ */
+int toe_receive_skb(struct toedev *dev, struct sk_buff **skb, int n)
+{
+       int i;
+
+       if (likely(!netdev_nit))
+               return dev->recv(dev, skb, n);
+
+       for (i = 0; i < n; ++i) {
+               struct sk_buff *p = *skb++;
+
+               p->dev = dev->lldev;
+               skb_get(p);
+               netif_receive_skb(p);
+               p->dev = NULL;
+               dev->recv(dev, &p, 1);
+       }
+       return 0;
+}
+
+void toe_neigh_update(struct neighbour *neigh, int flags)
+{
+       struct net_device *dev = neigh->dev;
+       
+       if (dev && (dev->features & NETIF_F_TCPIP_OFFLOAD)) {
+               struct toedev *tdev = TOEDEV(dev);
+
+               if (tdev && tdev->neigh_update)
+                       tdev->neigh_update(neigh->dev, tdev, neigh, flags);
+       }
+}
+
+static int __init toedev_init(void)
+{
+#ifndef boot_phase
+       boot_phase = 0;
+#endif
+
+       /* We tolerate proc failures */
+       if (toe_proc_init())
+               printk(KERN_WARNING "Unable to create /proc/net/toe entries\n");
+
+       return 0;
+}
+
+subsys_initcall(toedev_init);
+
+EXPORT_SYMBOL_GPL(register_tom);
+EXPORT_SYMBOL_GPL(unregister_tom);
+EXPORT_SYMBOL_GPL(register_toedev);
+EXPORT_SYMBOL_GPL(alloc_toedev);
+EXPORT_SYMBOL_GPL(activate_toedev);
+EXPORT_SYMBOL_GPL(toe_set_lldev);
+EXPORT_SYMBOL_GPL(toe_send);
+EXPORT_SYMBOL_GPL(toe_receive_skb);
diff -Naur linux-2.6.13-rc6-git3/net/ipv4/Makefile 
linux-2.6.13-rc6-git3.patched/net/ipv4/Makefile
--- linux-2.6.13-rc6-git3/net/ipv4/Makefile     2005-08-07 11:18:56.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/net/ipv4/Makefile     2005-08-11 
21:28:37.000000000 -0700
@@ -10,6 +10,7 @@
             datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \
             sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
 
+obj-$(CONFIG_TCP_OFFLOAD) += offload.o
 obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
 obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
 obj-$(CONFIG_PROC_FS) += proc.o
diff -Naur linux-2.6.13-rc6-git3/net/ipv4/offload.c 
linux-2.6.13-rc6-git3.patched/net/ipv4/offload.c
--- linux-2.6.13-rc6-git3/net/ipv4/offload.c    1969-12-31 16:00:00.000000000 
-0800
+++ linux-2.6.13-rc6-git3.patched/net/ipv4/offload.c    2005-08-11 
22:37:04.015789000 -0700
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ *                                                                           *
+ * File:                                                                     *
+ *  offload.c                                                                *
+ *                                                                           *
+ * Description:                                                              *
+ *  TCP offload support.                                                     *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or modify      *
+ * it under the terms of the GNU General Public License, version 2, as       *
+ * published by the Free Software Foundation.                                *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License along   *
+ * with this program; if not, write to the Free Software Foundation, Inc.,   *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ *                                                                           *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.                     *
+ *                                                                           *
+ * http://www.chelsio.com                                                    *
+ *                                                                           *
+ * Copyright (c) 2003 - 2005 Chelsio Communications, Inc.                    *
+ * All rights reserved.                                                      *
+ *                                                                           *
+ * Maintainers: [EMAIL PROTECTED]                                      *
+ *                                                                           *
+ * Authors: Dimitrios Michailidis   <[EMAIL PROTECTED]>                        
 *
+ *                                                                           *
+ * History:                                                                  *
+ *                                                                           *
+ ****************************************************************************/
+/* $Date: 2005/08/09 18:58:21 $ $RCSfile: offload.c,v $ $Revision: 1.3 $ */
+
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/notifier.h>
+#include <linux/toedev.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#include <net/offload.h>
+#include <asm/semaphore.h>
+#include <linux/netdevice.h>
+
+# define inet_addr_info(sk) inet_sk(sk)
+
+/* Replace this with a R/W semaphore someday.  See kernel/profile.c */
+static DECLARE_MUTEX(notify_mutex);
+static struct notifier_block *listen_offload_notify_list;
+
+int register_listen_offload_notifier(struct notifier_block *nb)
+{
+       int err;
+
+       down(&notify_mutex);
+       err = notifier_chain_register(&listen_offload_notify_list, nb);
+       up(&notify_mutex);
+       return err;
+}
+
+int unregister_listen_offload_notifier(struct notifier_block *nb)
+{
+       int err;
+
+       down(&notify_mutex);
+       err = notifier_chain_unregister(&listen_offload_notify_list, nb);
+       up(&notify_mutex);
+       return err;
+}
+
+/*
+ * Called when an active open has been requested through connect(2).  Decides
+ * if the connection may be offloaded based on the system's offload policies
+ * and the capabilities of the egress interface.
+ *
+ * Returns 1 if the connection is offloaded and 0 otherwise.
+ */
+int tcp_connect_offload(struct sock *sk)
+{
+       if (sk->sk_route_caps & NETIF_F_TCPIP_OFFLOAD) {
+               struct toedev *dev = TOEDEV(__sk_dst_get(sk)->dev);
+
+               if (!dev || !dev->can_offload(dev, sk))
+                       return 0;
+               /* XXX check offload policies */
+               if (dev->connect(dev, sk) == 0)
+                       return 1;
+       }
+       return 0;
+}
+
+/*
+ * TOE capable backlog handler.  This is used for offloaded listening sockets
+ * so they can deal with non-IP (TOE) packets queued in their backlogs.  We
+ * distinguish TOE from IP packets easily as the former lack network headers.
+ * Such TOE packets are fed to a TOE-specific backlog handler.
+ */
+static int listen_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       if (likely(skb->h.raw != skb->nh.raw))
+               return tcp_v4_do_rcv(sk, skb);
+       BLOG_SKB_CB(skb)->backlog_rcv(sk, skb);
+       return 0;
+}
+
+/*
+ * Called when the SW stack has transitioned a socket to listen state.
+ * We check if the socket should be offloaded according to the current 
+ * offloading policies, and if so, publish an OFFLOAD_LISTEN_START event.
+ */
+int tcp_listen_offload(struct sock *sk)
+{
+       /* IPv4 only for now */
+       if (sk->sk_family != PF_INET)
+               return 0;
+
+       /* filter out loopback listens */
+       if (LOOPBACK(inet_addr_info(sk)->rcv_saddr))
+               return 0;
+
+       /* if (nf_sock_hook(PF_INET, NF_IP_OFFLOAD, sk) != NF_ACCEPT)
+               return 0; */
+
+       /* Install a TOE capable backlog handler */
+       sk->sk_backlog_rcv = listen_backlog_rcv;
+
+       down(&notify_mutex);
+       notifier_call_chain(&listen_offload_notify_list,
+                               OFFLOAD_LISTEN_START, sk);
+       up(&notify_mutex);
+       return 1;
+}
+
+/*
+ * Called through a netfilter hook when a socket starts listening.
+ * Publishes an OFFLOAD_LISTEN_START event.
+ */
+static int tcp_listen_offload_start(struct sk_buff *skb)
+{
+       down(&notify_mutex);
+       notifier_call_chain(&listen_offload_notify_list, OFFLOAD_LISTEN_START,
+                               skb->sk);
+       up(&notify_mutex);
+       return 0;
+}
+
+/*
+ * Called when the SW stack is preparing to close an existing listening socket.
+ * We publish an OFFLOAD_LISTEN_STOP event.
+ */
+int tcp_listen_offload_stop(struct sock *sk)
+{
+       down(&notify_mutex);
+       notifier_call_chain(&listen_offload_notify_list,
+                               OFFLOAD_LISTEN_STOP, sk);
+       up(&notify_mutex);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(register_listen_offload_notifier);
+EXPORT_SYMBOL_GPL(unregister_listen_offload_notifier);
diff -Naur linux-2.6.13-rc6-git3/net/ipv4/tcp.c 
linux-2.6.13-rc6-git3.patched/net/ipv4/tcp.c
--- linux-2.6.13-rc6-git3/net/ipv4/tcp.c        2005-08-07 11:18:56.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/net/ipv4/tcp.c        2005-08-11 
21:28:37.000000000 -0700
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $
+ * Version:    $Id: tcp.c,v 1.2 2005/08/12 04:28:37 sbardone Exp $
  *
  * Authors:    Ross Biro
  *             Fred N. van Kempen, <[EMAIL PROTECTED]>
@@ -262,7 +262,9 @@
 #include <net/tcp.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
-
+#ifdef CONFIG_TCP_OFFLOAD
+#include <net/offload.h>
+#endif
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -483,6 +485,9 @@
                sk_dst_reset(sk);
                sk->sk_prot->hash(sk);
 
+#ifdef CONFIG_TCP_OFFLOAD
+               tcp_listen_offload(sk);
+#endif
                return 0;
        }
 
@@ -735,6 +740,11 @@
        ssize_t res;
        struct sock *sk = sock->sk;
 
+#ifdef CONFIG_TCP_OFFLOAD
+       if (sk->sk_prot->sendpage)
+               return sk->sk_prot->sendpage(sk, page, offset, size, flags);
+#endif
+
 #define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
 
        if (!(sk->sk_route_caps & NETIF_F_SG) ||
@@ -994,7 +1004,10 @@
  *     this, no blocking and very strange errors 8)
  */
 
-static int tcp_recv_urg(struct sock *sk, long timeo,
+#ifndef CONFIG_TCP_OFFLOAD
+static
+#endif
+int tcp_recv_urg(struct sock *sk, long timeo,
                        struct msghdr *msg, int len, int flags,
                        int *addr_len)
 {
@@ -1193,8 +1206,14 @@
        tcp_rcv_space_adjust(sk);
 
        /* Clean up data we have read: This will do ACK frames. */
-       if (copied)
-               cleanup_rbuf(sk, copied);
+       if (copied) {
+#ifdef CONFIG_TCP_OFFLOAD
+               if (tp->toe_specific)
+                       tp->toe_specific->rcv_consumed(sk, copied);
+               else
+#endif
+                       cleanup_rbuf(sk, copied);
+       }
        return copied;
 }
 
@@ -1615,6 +1634,9 @@
        sk->sk_shutdown = SHUTDOWN_MASK;
 
        if (sk->sk_state == TCP_LISTEN) {
+#ifdef CONFIG_TCP_OFFLOAD
+               tcp_listen_offload_stop(sk);
+#endif
                tcp_set_state(sk, TCP_CLOSE);
 
                /* Special case. */
diff -Naur linux-2.6.13-rc6-git3/net/ipv4/tcp_diag.c 
linux-2.6.13-rc6-git3.patched/net/ipv4/tcp_diag.c
--- linux-2.6.13-rc6-git3/net/ipv4/tcp_diag.c   2005-08-07 11:18:56.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/net/ipv4/tcp_diag.c   2005-08-11 
21:28:37.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  * tcp_diag.c  Module for monitoring TCP sockets.
  *
- * Version:    $Id: tcp_diag.c,v 1.3 2002/02/01 22:01:04 davem Exp $
+ * Version:    $Id: tcp_diag.c,v 1.2 2005/08/12 04:28:37 sbardone Exp $
  *
  * Authors:    Alexey Kuznetsov, <[EMAIL PROTECTED]>
  *
@@ -24,6 +24,9 @@
 #include <net/tcp.h>
 #include <net/ipv6.h>
 #include <net/inet_common.h>
+#ifdef CONFIG_TCP_OFFLOAD
+#include <net/offload.h>
+#endif
 
 #include <linux/inet.h>
 #include <linux/stddef.h>
@@ -54,6 +57,9 @@
        struct nlmsghdr  *nlh;
        struct tcp_info  *info = NULL;
        struct tcpdiag_meminfo  *minfo = NULL;
+#ifdef CONFIG_TCP_OFFLOAD
+       struct tcpdiag_offload *oinfo = NULL;
+#endif
        unsigned char    *b = skb->tail;
 
        nlh = NLMSG_PUT(skb, pid, seq, TCPDIAG_GETSOCK, sizeof(*r));
@@ -70,6 +76,11 @@
                        strcpy(TCPDIAG_PUT(skb, TCPDIAG_CONG, len+1),
                               tp->ca_ops->name);
                }
+#ifdef CONFIG_TCP_OFFLOAD
+               if ((ext & (1 << (TCPDIAG_OFFLOAD - 1))) &&
+                       tp->toe_specific && 
tp->toe_specific->tcpdiag_offload_info)
+                               oinfo = TCPDIAG_PUT(skb, TCPDIAG_OFFLOAD, 
sizeof(*oinfo));
+#endif
        }
        r->tcpdiag_family = sk->sk_family;
        r->tcpdiag_state = sk->sk_state;
@@ -163,6 +174,11 @@
        if (sk->sk_state < TCP_TIME_WAIT && tp->ca_ops->get_info)
                tp->ca_ops->get_info(tp, ext, skb);
 
+#ifdef CONFIG_TCP_OFFLOAD
+       if (oinfo)
+               tp->toe_specific->tcpdiag_offload_info(sk, oinfo);
+#endif
+
        nlh->nlmsg_len = skb->tail - b;
        return skb->len;
 
diff -Naur linux-2.6.13-rc6-git3/net/ipv4/tcp_ipv4.c 
linux-2.6.13-rc6-git3.patched/net/ipv4/tcp_ipv4.c
--- linux-2.6.13-rc6-git3/net/ipv4/tcp_ipv4.c   2005-08-11 16:57:48.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/net/ipv4/tcp_ipv4.c   2005-08-11 
21:28:37.000000000 -0700
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_ipv4.c,v 1.240 2002/02/01 22:01:04 davem Exp $
+ * Version:    $Id: tcp_ipv4.c,v 1.2 2005/08/12 04:28:37 sbardone Exp $
  *
  *             IPv4 specific functions
  *
@@ -68,6 +68,9 @@
 #include <net/ipv6.h>
 #include <net/inet_common.h>
 #include <net/xfrm.h>
+#ifdef CONFIG_TCP_OFFLOAD
+#include <net/offload.h>
+#endif
 
 #include <linux/inet.h>
 #include <linux/ipv6.h>
@@ -151,7 +154,10 @@
 }
 
 /* Caller must disable local BH processing. */
-static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child)
+#ifndef CONFIG_TCP_OFFLOAD
+static
+#endif
+__inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child)
 {
        struct tcp_bind_hashbucket *head =
                                &tcp_bhash[tcp_bhashfn(inet_sk(child)->num)];
@@ -351,7 +357,10 @@
        }
 }
 
-static __inline__ void __tcp_v4_hash(struct sock *sk, const int 
listen_possible)
+#ifndef CONFIG_TCP_OFFLOAD
+static
+#endif
+__inline__ void __tcp_v4_hash(struct sock *sk, const int listen_possible)
 {
        struct hlist_head *list;
        rwlock_t *lock;
@@ -835,6 +844,11 @@
        __sk_dst_set(sk, &rt->u.dst);
        tcp_v4_setup_caps(sk, &rt->u.dst);
 
+#ifdef CONFIG_TCP_OFFLOAD
+       if (tcp_connect_offload(sk))
+               return 0;
+#endif
+
        if (!tp->write_seq)
                tp->write_seq = secure_tcp_sequence_number(inet->saddr,
                                                           inet->daddr,
@@ -1494,11 +1508,20 @@
                         * to destinations, already remembered
                         * to the moment of synflood.
                         */
+#ifndef CONFIG_TCP_OFFLOAD
                        LIMIT_NETDEBUG(printk(KERN_DEBUG "TCP: drop open "
                                              "request from %u.%u."
                                              "%u.%u/%u\n",
                                              NIPQUAD(saddr),
                                              ntohs(skb->h.th->source)));
+#else
+                       NETDEBUG(if (net_ratelimit()) \
+                                       printk(KERN_DEBUG "TCP: drop open "
+                                              "request from %u.%u."
+                                              "%u.%u/%u\n", \
+                                              NIPQUAD(saddr),
+                                              ntohs(skb->h.th->source)));
+#endif
                        dst_release(dst);
                        goto drop_and_free;
                }
@@ -1626,7 +1649,12 @@
                                  skb->nh.iph->daddr, skb->csum))
                        return 0;
 
+#ifndef CONFIG_TCP_OFFLOAD
                LIMIT_NETDEBUG(printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
+#else
+               NETDEBUG(if (net_ratelimit())
+                               printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
+#endif
                skb->ip_summed = CHECKSUM_NONE;
        }
        if (skb->len <= 76) {
diff -Naur linux-2.6.13-rc6-git3/net/ipv4/tcp_timer.c 
linux-2.6.13-rc6-git3.patched/net/ipv4/tcp_timer.c
--- linux-2.6.13-rc6-git3/net/ipv4/tcp_timer.c  2005-08-07 11:18:56.000000000 
-0700
+++ linux-2.6.13-rc6-git3.patched/net/ipv4/tcp_timer.c  2005-08-11 
21:28:37.000000000 -0700
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $
+ * Version:    $Id: tcp_timer.c,v 1.2 2005/08/12 04:28:37 sbardone Exp $
  *
  * Authors:    Ross Biro
  *             Fred N. van Kempen, <[EMAIL PROTECTED]>
@@ -22,6 +22,9 @@
 
 #include <linux/module.h>
 #include <net/tcp.h>
+#ifdef CONFIG_TCP_OFFLOAD
+#include <net/offload.h>
+#endif
 
 int sysctl_tcp_syn_retries = TCP_SYN_RETRIES; 
 int sysctl_tcp_synack_retries = TCP_SYNACK_RETRIES; 
@@ -559,6 +562,13 @@
        if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))
                return;
 
+#ifdef CONFIG_TCP_OFFLOAD
+       if (tcp_sk(sk)->toe_specific) {
+               tcp_sk(sk)->toe_specific->set_keepalive(sk, val);
+               return;
+       }
+#endif
+
        if (val && !sock_flag(sk, SOCK_KEEPOPEN))
                tcp_reset_keepalive_timer(sk, keepalive_time_when(tcp_sk(sk)));
        else if (!val)
diff -Naur linux-2.6.13-rc6-git3/net/Kconfig 
linux-2.6.13-rc6-git3.patched/net/Kconfig
--- linux-2.6.13-rc6-git3/net/Kconfig   2005-08-07 11:18:56.000000000 -0700
+++ linux-2.6.13-rc6-git3.patched/net/Kconfig   2005-08-11 21:41:53.000000000 
-0700
@@ -59,6 +59,22 @@
 
 endif # if INET
 
+config TCP_OFFLOAD
+       bool "TCP Offload support"
+       depends on NET
+       default y
+       help
+         TOE (TCP Offload Engine) places the TCP protocol stack in hardware
+         to reduce the burden on the host processor, thereby freeing up CPU
+         cycles to increase applications performance and high-speed data
+         transmission.
+
+         You should say Y here if you have an Ethernet device with TOE
+         hardware, such as Chelsio's 10Gb T110/T210/T204 cards.
+
+         If you don't have TOE hardware, saying Y here will not change the
+         way TCP works, all packets will go through the host TCP stack.
+
 menuconfig NETFILTER
        bool "Network packet filtering (replaces ipchains)"
        ---help---

Reply via email to