ia64/xen-unstable

changeset 10605:5e30ef3e541d

[NET] front: Transmit TSO packets if supported

This patch adds TSO transmission support to the frontend.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@dhcp93.uk.xensource.com
date Thu Jun 29 19:34:16 2006 +0100 (2006-06-29)
parents 7a11e60d2f42
children 5d622ded9efe
files linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Thu Jun 29 19:33:53 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Thu Jun 29 19:34:16 2006 +0100
     1.3 @@ -463,7 +463,7 @@ static int network_open(struct net_devic
     1.4  
     1.5  static inline int netfront_tx_slot_available(struct netfront_info *np)
     1.6  {
     1.7 -	return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
     1.8 +	return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
     1.9  }
    1.10  
    1.11  static inline void network_maybe_wake_tx(struct net_device *dev)
    1.12 @@ -491,7 +491,13 @@ static void network_tx_buf_gc(struct net
    1.13  		rmb(); /* Ensure we see responses up to 'rp'. */
    1.14  
    1.15  		for (cons = np->tx.rsp_cons; cons != prod; cons++) {
    1.16 -			id  = RING_GET_RESPONSE(&np->tx, cons)->id;
    1.17 +			struct netif_tx_response *txrsp;
    1.18 +
    1.19 +			txrsp = RING_GET_RESPONSE(&np->tx, cons);
    1.20 +			if (txrsp->status == NETIF_RSP_NULL)
    1.21 +				continue;
    1.22 +
    1.23 +			id  = txrsp->id;
    1.24  			skb = np->tx_skbs[id];
    1.25  			if (unlikely(gnttab_query_foreign_access(
    1.26  				np->grant_tx_ref[id]) != 0)) {
    1.27 @@ -719,6 +725,7 @@ static int network_start_xmit(struct sk_
    1.28  	unsigned short id;
    1.29  	struct netfront_info *np = netdev_priv(dev);
    1.30  	struct netif_tx_request *tx;
    1.31 +	struct netif_extra_info *extra;
    1.32  	char *data = skb->data;
    1.33  	RING_IDX i;
    1.34  	grant_ref_t ref;
    1.35 @@ -739,7 +746,8 @@ static int network_start_xmit(struct sk_
    1.36  	spin_lock_irq(&np->tx_lock);
    1.37  
    1.38  	if (unlikely(!netif_carrier_ok(dev) ||
    1.39 -		     (frags > 1 && !xennet_can_sg(dev)))) {
    1.40 +		     (frags > 1 && !xennet_can_sg(dev)) ||
    1.41 +		     netif_needs_gso(dev, skb))) {
    1.42  		spin_unlock_irq(&np->tx_lock);
    1.43  		goto drop;
    1.44  	}
    1.45 @@ -762,11 +770,31 @@ static int network_start_xmit(struct sk_
    1.46  	tx->size = len;
    1.47  
    1.48  	tx->flags = 0;
    1.49 +	extra = NULL;
    1.50 +
    1.51  	if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
    1.52  		tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
    1.53  	if (skb->proto_data_valid) /* remote but checksummed? */
    1.54  		tx->flags |= NETTXF_data_validated;
    1.55  
    1.56 +	if (skb_shinfo(skb)->gso_size) {
    1.57 +		struct netif_extra_info *gso = (struct netif_extra_info *)
    1.58 +			RING_GET_REQUEST(&np->tx, ++i);
    1.59 +
    1.60 +		if (extra)
    1.61 +			extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
    1.62 +		else
    1.63 +			tx->flags |= NETTXF_extra_info;
    1.64 +
    1.65 +		gso->u.gso.size = skb_shinfo(skb)->gso_size;
    1.66 +		gso->u.gso.segs = skb_shinfo(skb)->gso_segs;
    1.67 +		gso->u.gso.type = XEN_NETIF_GSO_TCPV4;
    1.68 +
    1.69 +		gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
    1.70 +		gso->flags = 0;
    1.71 +		extra = gso;
    1.72 +	}
    1.73 +
    1.74  	np->tx.req_prod_pvt = i + 1;
    1.75  
    1.76  	xennet_make_frags(skb, dev, tx);
    1.77 @@ -1065,9 +1093,28 @@ static int xennet_set_sg(struct net_devi
    1.78  	return ethtool_op_set_sg(dev, data);
    1.79  }
    1.80  
    1.81 +static int xennet_set_tso(struct net_device *dev, u32 data)
    1.82 +{
    1.83 +	if (data) {
    1.84 +		struct netfront_info *np = netdev_priv(dev);
    1.85 +		int val;
    1.86 +
    1.87 +		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-tso",
    1.88 +				 "%d", &val) < 0)
    1.89 +			val = 0;
    1.90 +#if 0 /* KAF: After the protocol is finalised. */
    1.91 +		if (!val)
    1.92 +#endif
    1.93 +			return -ENOSYS;
    1.94 +	}
    1.95 +
    1.96 +	return ethtool_op_set_tso(dev, data);
    1.97 +}
    1.98 +
    1.99  static void xennet_set_features(struct net_device *dev)
   1.100  {
   1.101 -	xennet_set_sg(dev, 1);
   1.102 +	if (!xennet_set_sg(dev, 1))
   1.103 +		xennet_set_tso(dev, 1);
   1.104  }
   1.105  
   1.106  static void network_connect(struct net_device *dev)
   1.107 @@ -1148,6 +1195,8 @@ static struct ethtool_ops network_ethtoo
   1.108  	.set_tx_csum = ethtool_op_set_tx_csum,
   1.109  	.get_sg = ethtool_op_get_sg,
   1.110  	.set_sg = xennet_set_sg,
   1.111 +	.get_tso = ethtool_op_get_tso,
   1.112 +	.set_tso = xennet_set_tso,
   1.113  };
   1.114  
   1.115  #ifdef CONFIG_SYSFS