[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [4/4] [NET] front: Transmit TSO packets if supported
Hi: [NET] front: Transmit TSO packets if supported This patch adds TSO transmission support to the frontend. This also fixes a bug where SG may not be turned off correctly when migrating to an old host. 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 fb922826baef -r ea33ffdb9973 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Jun 30 22:28:09 2006 +1000 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Jun 30 22:44:18 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)) { @@ -719,6 +725,7 @@ static int network_start_xmit(struct sk_ unsigned short id; struct netfront_info *np = netdev_priv(dev); struct netif_tx_request *tx; + struct netif_tx_extra *txtra; char *data = skb->data; RING_IDX i; grant_ref_t ref; @@ -739,7 +746,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,10 +770,30 @@ static int network_start_xmit(struct sk_ tx->size = len; tx->flags = 0; + txtra = NULL; + if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ tx->flags |= NETTXF_csum_blank | NETTXF_data_validated; if (skb->proto_data_valid) /* remote but checksummed? */ tx->flags |= NETTXF_data_validated; + + if (skb_shinfo(skb)->gso_size) { + struct netif_tx_extra *gso = + (struct netif_tx_extra *)RING_GET_REQUEST(&np->tx, ++i); + + if (txtra) + txtra->flags |= XEN_NETIF_TXTRA_MORE; + else + tx->flags |= NETTXF_extra_info; + + gso->gso.size = skb_shinfo(skb)->gso_size; + gso->gso.type = + xen_gso_type_linux2xen(skb_shinfo(skb)->gso_type); + + gso->type = XEN_NETIF_TXTRA_TYPE_GSO; + gso->flags = 0; + txtra = gso; + } np->tx.req_prod_pvt = i + 1; @@ -1065,9 +1093,47 @@ 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-gso", + "%d", &val) < 0) + val = 0; + if (!(val & XEN_GSO_TCPV4)) + return -ENOSYS; + } + + return ethtool_op_set_tso(dev, data); +} + +static void xennet_set_gso(struct net_device *dev) +{ + struct netfront_info *np = netdev_priv(dev); + int allowed_types = SKB_GSO_TCPV4 | SKB_GSO_DODGY; + int val; + + if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-gso", + "%d", &val) < 0) + return; + + /* Filter out things we don't understand. */ + val = xen_gso_type_xen2linux(val) & allowed_types; + + /* Turn on the advertised bits. */ + dev->features |= val << NETIF_F_GSO_SHIFT; +} + static void xennet_set_features(struct net_device *dev) { - xennet_set_sg(dev, 1); + /* Turn off all negotiated bits. */ + dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1; + xennet_set_sg(dev, 0); + + if (!xennet_set_sg(dev, 1)) + xennet_set_gso(dev); } static void network_connect(struct net_device *dev) @@ -1148,6 +1214,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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |