[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [5/5] [NET] front: Transmit TSO packets if supported



Hi:

[NET] front: Transmit TSO packets if supported

This patch adds TSO transmission support to the frontend.

Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff -r 9853b45712e8 -r 9f4e79081e4a 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Jun 28 
13:55:13 2006 +1000
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Jun 28 
13:55:32 2006 +1000
@@ -463,7 +463,7 @@ static int network_open(struct net_devic
 
 static inline int netfront_tx_slot_available(struct netfront_info *np)
 {
-       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
+       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
 }
 
 static inline void network_maybe_wake_tx(struct net_device *dev)
@@ -491,7 +491,13 @@ static void network_tx_buf_gc(struct net
                rmb(); /* Ensure we see responses up to 'rp'. */
 
                for (cons = np->tx.rsp_cons; cons != prod; cons++) {
-                       id  = RING_GET_RESPONSE(&np->tx, cons)->id;
+                       struct netif_tx_response *txrsp;
+
+                       txrsp = RING_GET_RESPONSE(&np->tx, cons);
+                       if (txrsp->status == NETIF_RSP_NULL)
+                               continue;
+
+                       id  = txrsp->id;
                        skb = np->tx_skbs[id];
                        if (unlikely(gnttab_query_foreign_access(
                                np->grant_tx_ref[id]) != 0)) {
@@ -739,7 +745,8 @@ static int network_start_xmit(struct sk_
        spin_lock_irq(&np->tx_lock);
 
        if (unlikely(!netif_carrier_ok(dev) ||
-                    (frags > 1 && !xennet_can_sg(dev)))) {
+                    (frags > 1 && !xennet_can_sg(dev)) ||
+                    netif_needs_gso(dev, skb))) {
                spin_unlock_irq(&np->tx_lock);
                goto drop;
        }
@@ -762,9 +769,21 @@ static int network_start_xmit(struct sk_
        tx->size = len;
 
        tx->flags = 0;
-       if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
+       if (skb->ip_summed == CHECKSUM_HW) {
+               /* local packet? */
                tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
-       if (skb->proto_data_valid) /* remote but checksummed? */
+
+               if (skb_shinfo(skb)->gso_size) {
+                       struct netif_tx_extra *txtra =
+                               (struct netif_tx_extra *)
+                               RING_GET_REQUEST(&np->tx, ++i);
+
+                       tx->flags |= NETTXF_gso;
+                       txtra->gso_size = skb_shinfo(skb)->gso_size;
+                       txtra->gso_segs = skb_shinfo(skb)->gso_segs;
+                       txtra->gso_type = skb_shinfo(skb)->gso_type;
+               }
+       } else if (skb->proto_data_valid) /* remote but checksummed? */
                tx->flags |= NETTXF_data_validated;
 
        np->tx.req_prod_pvt = i + 1;
@@ -1065,9 +1084,26 @@ static int xennet_set_sg(struct net_devi
        return ethtool_op_set_sg(dev, data);
 }
 
+static int xennet_set_tso(struct net_device *dev, u32 data)
+{
+       if (data) {
+               struct netfront_info *np = netdev_priv(dev);
+               int val;
+
+               if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-tso",
+                                "%d", &val) < 0)
+                       val = 0;
+               if (!val)
+                       return -ENOSYS;
+       }
+
+       return ethtool_op_set_tso(dev, data);
+}
+
 static void xennet_set_features(struct net_device *dev)
 {
-       xennet_set_sg(dev, 1);
+       if (!xennet_set_sg(dev, 1))
+               xennet_set_tso(dev, 1);
 }
 
 static void network_connect(struct net_device *dev)
@@ -1148,6 +1184,8 @@ static struct ethtool_ops network_ethtoo
        .set_tx_csum = ethtool_op_set_tx_csum,
        .get_sg = ethtool_op_get_sg,
        .set_sg = xennet_set_sg,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = xennet_set_tso,
 };
 
 #ifdef CONFIG_SYSFS

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.