diff options
author | Paul Durrant <Paul.Durrant@citrix.com> | 2014-01-15 12:30:33 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-16 19:22:54 -0500 |
commit | 2c0057dec90bf65618c5e8f97e9193ff756ee2fb (patch) | |
tree | f56095abb803f61304ce0d0f854b6df45614b4a3 /drivers/net/xen-netfront.c | |
parent | 0b4cec8c2e872a6bc9146a001d7532f31023aed5 (diff) |
xen-netfront: add support for IPv6 offloads
This patch adds support for IPv6 checksum offload and GSO when those
features are available in the backend.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r-- | drivers/net/xen-netfront.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index c41537b577a4..d7bee8a5308e 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -617,7 +617,9 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
617 | tx->flags |= XEN_NETTXF_extra_info; | 617 | tx->flags |= XEN_NETTXF_extra_info; |
618 | 618 | ||
619 | gso->u.gso.size = skb_shinfo(skb)->gso_size; | 619 | gso->u.gso.size = skb_shinfo(skb)->gso_size; |
620 | gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; | 620 | gso->u.gso.type = (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) ? |
621 | XEN_NETIF_GSO_TYPE_TCPV6 : | ||
622 | XEN_NETIF_GSO_TYPE_TCPV4; | ||
621 | gso->u.gso.pad = 0; | 623 | gso->u.gso.pad = 0; |
622 | gso->u.gso.features = 0; | 624 | gso->u.gso.features = 0; |
623 | 625 | ||
@@ -809,15 +811,18 @@ static int xennet_set_skb_gso(struct sk_buff *skb, | |||
809 | return -EINVAL; | 811 | return -EINVAL; |
810 | } | 812 | } |
811 | 813 | ||
812 | /* Currently only TCPv4 S.O. is supported. */ | 814 | if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4 && |
813 | if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { | 815 | gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV6) { |
814 | if (net_ratelimit()) | 816 | if (net_ratelimit()) |
815 | pr_warn("Bad GSO type %d\n", gso->u.gso.type); | 817 | pr_warn("Bad GSO type %d\n", gso->u.gso.type); |
816 | return -EINVAL; | 818 | return -EINVAL; |
817 | } | 819 | } |
818 | 820 | ||
819 | skb_shinfo(skb)->gso_size = gso->u.gso.size; | 821 | skb_shinfo(skb)->gso_size = gso->u.gso.size; |
820 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | 822 | skb_shinfo(skb)->gso_type = |
823 | (gso->u.gso.type == XEN_NETIF_GSO_TYPE_TCPV4) ? | ||
824 | SKB_GSO_TCPV4 : | ||
825 | SKB_GSO_TCPV6; | ||
821 | 826 | ||
822 | /* Header must be checked, and gso_segs computed. */ | 827 | /* Header must be checked, and gso_segs computed. */ |
823 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; | 828 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; |
@@ -1191,6 +1196,15 @@ static netdev_features_t xennet_fix_features(struct net_device *dev, | |||
1191 | features &= ~NETIF_F_SG; | 1196 | features &= ~NETIF_F_SG; |
1192 | } | 1197 | } |
1193 | 1198 | ||
1199 | if (features & NETIF_F_IPV6_CSUM) { | ||
1200 | if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, | ||
1201 | "feature-ipv6-csum-offload", "%d", &val) < 0) | ||
1202 | val = 0; | ||
1203 | |||
1204 | if (!val) | ||
1205 | features &= ~NETIF_F_IPV6_CSUM; | ||
1206 | } | ||
1207 | |||
1194 | if (features & NETIF_F_TSO) { | 1208 | if (features & NETIF_F_TSO) { |
1195 | if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, | 1209 | if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, |
1196 | "feature-gso-tcpv4", "%d", &val) < 0) | 1210 | "feature-gso-tcpv4", "%d", &val) < 0) |
@@ -1200,6 +1214,15 @@ static netdev_features_t xennet_fix_features(struct net_device *dev, | |||
1200 | features &= ~NETIF_F_TSO; | 1214 | features &= ~NETIF_F_TSO; |
1201 | } | 1215 | } |
1202 | 1216 | ||
1217 | if (features & NETIF_F_TSO6) { | ||
1218 | if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, | ||
1219 | "feature-gso-tcpv6", "%d", &val) < 0) | ||
1220 | val = 0; | ||
1221 | |||
1222 | if (!val) | ||
1223 | features &= ~NETIF_F_TSO6; | ||
1224 | } | ||
1225 | |||
1203 | return features; | 1226 | return features; |
1204 | } | 1227 | } |
1205 | 1228 | ||
@@ -1338,7 +1361,9 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1338 | netif_napi_add(netdev, &np->napi, xennet_poll, 64); | 1361 | netif_napi_add(netdev, &np->napi, xennet_poll, 64); |
1339 | netdev->features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | | 1362 | netdev->features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | |
1340 | NETIF_F_GSO_ROBUST; | 1363 | NETIF_F_GSO_ROBUST; |
1341 | netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO; | 1364 | netdev->hw_features = NETIF_F_SG | |
1365 | NETIF_F_IPV6_CSUM | | ||
1366 | NETIF_F_TSO | NETIF_F_TSO6; | ||
1342 | 1367 | ||
1343 | /* | 1368 | /* |
1344 | * Assume that all hw features are available for now. This set | 1369 | * Assume that all hw features are available for now. This set |
@@ -1716,6 +1741,19 @@ again: | |||
1716 | goto abort_transaction; | 1741 | goto abort_transaction; |
1717 | } | 1742 | } |
1718 | 1743 | ||
1744 | err = xenbus_write(xbt, dev->nodename, "feature-gso-tcpv6", "1"); | ||
1745 | if (err) { | ||
1746 | message = "writing feature-gso-tcpv6"; | ||
1747 | goto abort_transaction; | ||
1748 | } | ||
1749 | |||
1750 | err = xenbus_write(xbt, dev->nodename, "feature-ipv6-csum-offload", | ||
1751 | "1"); | ||
1752 | if (err) { | ||
1753 | message = "writing feature-ipv6-csum-offload"; | ||
1754 | goto abort_transaction; | ||
1755 | } | ||
1756 | |||
1719 | err = xenbus_transaction_end(xbt, 0); | 1757 | err = xenbus_transaction_end(xbt, 0); |
1720 | if (err) { | 1758 | if (err) { |
1721 | if (err == -EAGAIN) | 1759 | if (err == -EAGAIN) |