From 205c192e44fdeed973c77e06f66abee4121624b4 Mon Sep 17 00:00:00 2001 From: t_jeang Date: Tue, 6 Jan 2009 12:06:02 +0000 Subject: [PATCH] imported patch netback-watch-csum-offload --- drivers/xen/netback/common.h | 8 ++++ drivers/xen/netback/interface.c | 9 +++- drivers/xen/netback/xenbus.c | 78 ++++++++++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/drivers/xen/netback/common.h b/drivers/xen/netback/common.h index 44d1dbf1..84c5033c 100644 --- a/drivers/xen/netback/common.h +++ b/drivers/xen/netback/common.h @@ -55,6 +55,8 @@ #define WPRINTK(fmt, args...) \ printk(KERN_WARNING "xen_net: " fmt, ##args) +struct backend_info; + typedef struct netif_st { /* Unique identifier for this interface. */ domid_t domid; @@ -100,6 +102,7 @@ typedef struct netif_st { atomic_t refcnt; struct net_device *dev; struct net_device_stats stats; + struct backend_info *be; unsigned int carrier; @@ -144,6 +147,9 @@ struct backend_info { struct xenbus_device *dev; netif_t *netif; enum xenbus_state frontend_state; + struct xenbus_watch csum_offload_watch; + int have_csum_offload:1; + int have_csum_offload_watch:1; /* State relating to the netback accelerator */ void *netback_accel_priv; @@ -203,6 +209,8 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev); struct net_device_stats *netif_be_get_stats(struct net_device *dev); irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs); +void netif_set_tx_csum(struct backend_info *, u32); + static inline int netbk_can_queue(struct net_device *dev) { netif_t *netif = netdev_priv(dev); diff --git a/drivers/xen/netback/interface.c b/drivers/xen/netback/interface.c index 610891fc..3633351d 100644 --- a/drivers/xen/netback/interface.c +++ b/drivers/xen/netback/interface.c @@ -116,10 +116,17 @@ static int netbk_set_tso(struct net_device *dev, u32 data) return ethtool_op_set_tso(dev, data); } +static int netbk_set_tx_csum(struct net_device *dev, u32 data) +{ + netif_t *netif = netdev_priv(dev); + netif_set_tx_csum(netif->be, data); + return ethtool_op_set_tx_csum(dev, data); +} + static struct ethtool_ops network_ethtool_ops = { .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .set_tx_csum = netbk_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = netbk_set_sg, .get_tso = ethtool_op_get_tso, diff --git a/drivers/xen/netback/xenbus.c b/drivers/xen/netback/xenbus.c index 668fecf1..d30230cb 100644 --- a/drivers/xen/netback/xenbus.c +++ b/drivers/xen/netback/xenbus.c @@ -32,6 +32,8 @@ static int connect_rings(struct backend_info *); static void connect(struct backend_info *); static void backend_create_netif(struct backend_info *be); +static int register_csum_offload_watch(struct backend_info *be); +static void unregister_csum_offload_watch(struct backend_info *be); static int netback_remove(struct xenbus_device *dev) { @@ -39,6 +41,7 @@ static int netback_remove(struct xenbus_device *dev) netback_remove_accelerators(be, dev); + unregister_csum_offload_watch(be); if (be->netif) { kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); netif_disconnect(be->netif); @@ -72,6 +75,8 @@ static int netback_probe(struct xenbus_device *dev, be->dev = dev; dev->dev.driver_data = be; + be->have_csum_offload = 1; + sg = 1; if (netbk_copy_skb_mode == NETBK_ALWAYS_COPY_SKB) sg = 0; @@ -220,6 +225,7 @@ static void backend_create_netif(struct backend_info *be) xenbus_dev_fatal(dev, err, "creating interface"); return; } + be->netif->be = be; kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); } @@ -230,6 +236,7 @@ static void disconnect_backend(struct xenbus_device *dev) struct backend_info *be = dev->dev.driver_data; if (be->netif) { + unregister_csum_offload_watch(be); netif_disconnect(be->netif); be->netif = NULL; } @@ -374,6 +381,66 @@ static void connect(struct backend_info *be) netif_wake_queue(be->netif->dev); } +static void feature_csum_offload_changed(struct xenbus_watch *watch, + const char **vec, + unsigned int vec_size) +{ + int val; + struct backend_info *be = container_of(watch, + struct backend_info, + csum_offload_watch); + + if (xenbus_scanf(XBT_NIL, be->dev->otherend, "feature-no-csum-offload", + "%d", &val) < 0) + val = 0; + + if (val) { + be->netif->features &= ~NETIF_F_IP_CSUM; + be->netif->dev->features &= ~NETIF_F_IP_CSUM; + } else { + be->netif->features |= NETIF_F_IP_CSUM; + be->netif->dev->features |= NETIF_F_IP_CSUM; + } +} +static int register_csum_offload_watch(struct backend_info *be) +{ + struct xenbus_device *dev = be->dev; + int err; + + if (!be->have_csum_offload || be->have_csum_offload_watch) + return 0; + + err = xenbus_watch_path2(dev, dev->otherend, "feature-no-csum-offload", + &be->csum_offload_watch, + feature_csum_offload_changed); + if (err) { + xenbus_dev_fatal(dev, err, + "watching %s/feature-no-csum-offload", + dev->otherend); + return err; + } + be->have_csum_offload_watch = 1; + return 0; + +} + +static void unregister_csum_offload_watch(struct backend_info *be) +{ + if (be->have_csum_offload_watch) { + unregister_xenbus_watch(&be->csum_offload_watch); + kfree(be->csum_offload_watch.node); + } + be->have_csum_offload_watch = 0; +} + +void netif_set_tx_csum(struct backend_info *be, u32 data) +{ + be->have_csum_offload = data; + if (data) + register_csum_offload_watch(be); + else + unregister_csum_offload_watch(be); +} static int connect_rings(struct backend_info *be) { @@ -448,13 +515,10 @@ static int connect_rings(struct backend_info *be) be->netif->dev->features |= NETIF_F_TSO; } - if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload", - "%d", &val) < 0) - val = 0; - if (val) { - be->netif->features &= ~NETIF_F_IP_CSUM; - be->netif->dev->features &= ~NETIF_F_IP_CSUM; - } + unregister_csum_offload_watch(be); + err = register_csum_offload_watch(be); + if (err) + return err; /* Map the shared frame, irq etc. */ err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn); -- 2.39.5