# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxxxx
# Node ID de263308be3b05ac7a4ccc7d852df03756233830
# Parent 3dfc2583a4f161a81ee0dcbba8e23e328577f687
[NET] More net protocol and GSO changes.
From: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 64 ++++++++++++++++-----
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 2
xen/include/public/io/netif.h | 57 ++++++++++++++----
3 files changed, 96 insertions(+), 27 deletions(-)
diff -r 3dfc2583a4f1 -r de263308be3b
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Jun 29
16:59:47 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Jun 29
19:02:45 2006 +0100
@@ -663,6 +663,34 @@ static void netbk_fill_frags(struct sk_b
}
}
+int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
+ int work_to_do)
+{
+ struct netif_extra_info *extra;
+ RING_IDX cons = netif->tx.req_cons;
+
+ do {
+ if (unlikely(work_to_do-- <= 0)) {
+ DPRINTK("Missing extra info\n");
+ return -EBADR;
+ }
+
+ extra = (struct netif_extra_info *)
+ RING_GET_REQUEST(&netif->tx, cons);
+ if (unlikely(!extra->type ||
+ extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+ netif->tx.req_cons = ++cons;
+ DPRINTK("Invalid extra type: %d\n", extra->type);
+ return -EINVAL;
+ }
+
+ memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+ netif->tx.req_cons = ++cons;
+ } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+
+ return work_to_do;
+}
+
/* Called after netfront has transmitted */
static void net_tx_action(unsigned long unused)
{
@@ -670,7 +698,7 @@ static void net_tx_action(unsigned long
struct sk_buff *skb;
netif_t *netif;
netif_tx_request_t txreq;
- struct netif_tx_extra txtra;
+ struct netif_tx_extra extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
u16 pending_idx;
RING_IDX i;
gnttab_map_grant_ref_t *mop;
@@ -732,16 +760,15 @@ static void net_tx_action(unsigned long
work_to_do--;
netif->tx.req_cons = ++i;
+ memset(extras, 0, sizeof(extras));
if (txreq.flags & NETTXF_extra_info) {
- if (work_to_do-- <= 0) {
- DPRINTK("Missing extra info\n");
- netbk_tx_err(netif, &txreq, i);
+ work_to_do = netbk_get_extras(netif, extras,
+ work_to_do);
+ if (unlikely(work_to_do < 0)) {
+ netbk_tx_err(netif, &txreq, 0);
continue;
}
-
- memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
- sizeof(txtra));
- netif->tx.req_cons = ++i;
+ i = netif->tx.req_cons;
}
ret = netbk_count_requests(netif, &txreq, work_to_do);
@@ -751,7 +778,7 @@ static void net_tx_action(unsigned long
}
i += ret;
- if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
+ if (unlikely(ret > MAX_SKB_FRAGS)) {
DPRINTK("Too many frags\n");
netbk_tx_err(netif, &txreq, i);
continue;
@@ -788,10 +815,21 @@ static void net_tx_action(unsigned long
/* Packets passed to netif_rx() must have some headroom. */
skb_reserve(skb, 16);
- if (txreq.flags & NETTXF_gso) {
- skb_shinfo(skb)->gso_size = txtra.u.gso.size;
- skb_shinfo(skb)->gso_segs = txtra.u.gso.segs;
- skb_shinfo(skb)->gso_type = txtra.u.gso.type;
+ if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
+ struct netif_tx_extra *gso;
+ gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
+
+ if (gso->u.gso.type != XEN_NETIF_GSO_TCPV4) {
+ DPRINTK("Bad GSO type.\n");
+ kfree_skb(skb);
+ netbk_tx_err(netif, &txreq, i);
+ break;
+ }
+
+ skb_shinfo(skb)->gso_size = gso->u.gso.size;
+ skb_shinfo(skb)->gso_segs = gso->u.gso.segs;
+ skb_shinfo(skb)->gso_type =
+ SKB_GSP_TCPV4 | SKB_GSO_DOSGY;
}
gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
diff -r 3dfc2583a4f1 -r de263308be3b
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Jun 29 16:59:47
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Jun 29 19:02:45
2006 +0100
@@ -101,11 +101,13 @@ static int netback_probe(struct xenbus_d
goto abort_transaction;
}
+#if 0 /* KAF: After the protocol is finalised. */
err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
if (err) {
message = "writing feature-tso";
goto abort_transaction;
}
+#endif
err = xenbus_transaction_end(xbt, 0);
} while (err == -EAGAIN);
diff -r 3dfc2583a4f1 -r de263308be3b xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h Thu Jun 29 16:59:47 2006 +0100
+++ b/xen/include/public/io/netif.h Thu Jun 29 19:02:45 2006 +0100
@@ -23,8 +23,9 @@
* This is the 'wire' format for packets:
* Request 1: netif_tx_request -- NETTXF_* (any flags)
* [Request 2: netif_tx_extra] (only if request 1 has NETTXF_extra_info)
- * Request 3: netif_tx_request -- NETTXF_more_data
+ * [Request 3: netif_tx_extra] (only if request 2 has XEN_NETIF_EXTRA_MORE)
* Request 4: netif_tx_request -- NETTXF_more_data
+ * Request 5: netif_tx_request -- NETTXF_more_data
* ...
* Request N: netif_tx_request -- 0
*/
@@ -41,12 +42,9 @@
#define _NETTXF_more_data (2)
#define NETTXF_more_data (1U<<_NETTXF_more_data)
-/* Packet has GSO fields in the following descriptor (netif_tx_extra.u.gso). */
-#define _NETTXF_gso (3)
-#define NETTXF_gso (1U<<_NETTXF_gso)
-
-/* This descriptor is followed by an extra-info descriptor (netif_tx_extra). */
-#define NETTXF_extra_info (NETTXF_gso)
+/* Packet to be followed by extra descriptor(s). */
+#define _NETTXF_extra_info (3)
+#define NETTXF_extra_info (1U<<_NETTXF_extra_info)
struct netif_tx_request {
grant_ref_t gref; /* Reference to buffer page */
@@ -57,14 +55,45 @@ struct netif_tx_request {
};
typedef struct netif_tx_request netif_tx_request_t;
-/* This structure needs to fit within netif_tx_request for compatibility. */
-struct netif_tx_extra {
+/* Types of netif_extra_info descriptors. */
+#define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */
+#define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */
+#define XEN_NETIF_EXTRA_TYPE_MAX (2)
+
+/* netif_extra_info flags. */
+#define _XEN_NETIF_EXTRA_FLAG_MORE (0)
+#define XEN_NETIF_EXTRA_FLAG_MORE (1U<<_XEN_NETIF_EXTRA_MORE)
+
+/* GSO types - only TCPv4 currently supported. */
+#define XEN_NETIF_GSO_TCPV4 (1)
+
+/*
+ * This structure needs to fit within both netif_tx_request and
+ * netif_rx_response for compatibility.
+ */
+struct netif_extra_info {
+ uint8_t type; /* XEN_NETIF_EXTRA_TYPE_* */
+ uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
+
union {
- /* NETTXF_gso: Generic Segmentation Offload. */
- struct netif_tx_gso {
- uint16_t size; /* GSO MSS. */
- uint16_t segs; /* GSO segment count. */
- uint16_t type; /* GSO type. */
+ struct {
+ /*
+ * Maximum payload size of each segment. For example, for TCP this
+ * is just the path MSS.
+ */
+ uint16_t size;
+
+ /*
+ * Number of GSO segments. This is the number of segments that
+ * have to be generated for this packet given the MSS.
+ */
+ uint16_t segs;
+
+ /*
+ * GSO type. This determines the protocol of the packet and any
+ * extra features required to segment the packet properly.
+ */
+ uint16_t type; /* XEN_NETIF_GSO_* */
} gso;
} u;
};
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|