diff options
author | Eli Cohen <eli@dev.mellanox.co.il> | 2008-04-17 00:01:10 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-04-17 00:01:10 -0400 |
commit | 6046136c742e32d5e6431cdcd8957638d1816821 (patch) | |
tree | 512a0165e982e5bdf93ba0732c4a52b01c84317b /drivers/infiniband/ulp | |
parent | 3371836383d63b627b228875f5ac63023cbf11d2 (diff) |
IPoIB: Use checksum offload support if available
For HCAs that support checksum offload (ie that set IB_DEVICE_UD_IP_CSUM
in the device capabilities flags), have IPoIB set NETIF_F_IP_CSUM and
use the HCA to generate and verify IP checksums.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_cm.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 9 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 24 |
4 files changed, 41 insertions, 1 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 054fab8e27a..08930ca41a3 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -87,6 +87,7 @@ enum { | |||
87 | IPOIB_MCAST_STARTED = 8, | 87 | IPOIB_MCAST_STARTED = 8, |
88 | IPOIB_FLAG_ADMIN_CM = 9, | 88 | IPOIB_FLAG_ADMIN_CM = 9, |
89 | IPOIB_FLAG_UMCAST = 10, | 89 | IPOIB_FLAG_UMCAST = 10, |
90 | IPOIB_FLAG_CSUM = 11, | ||
90 | 91 | ||
91 | IPOIB_MAX_BACKOFF_SECONDS = 16, | 92 | IPOIB_MAX_BACKOFF_SECONDS = 16, |
92 | 93 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 2490b2d79db..edf63dc0afe 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -1383,6 +1383,10 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, | |||
1383 | set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); | 1383 | set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); |
1384 | ipoib_warn(priv, "enabling connected mode " | 1384 | ipoib_warn(priv, "enabling connected mode " |
1385 | "will cause multicast packet drops\n"); | 1385 | "will cause multicast packet drops\n"); |
1386 | |||
1387 | dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG); | ||
1388 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; | ||
1389 | |||
1386 | ipoib_flush_paths(dev); | 1390 | ipoib_flush_paths(dev); |
1387 | return count; | 1391 | return count; |
1388 | } | 1392 | } |
@@ -1391,6 +1395,10 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, | |||
1391 | clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); | 1395 | clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); |
1392 | dev->mtu = min(priv->mcast_mtu, dev->mtu); | 1396 | dev->mtu = min(priv->mcast_mtu, dev->mtu); |
1393 | ipoib_flush_paths(dev); | 1397 | ipoib_flush_paths(dev); |
1398 | |||
1399 | if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) | ||
1400 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | ||
1401 | |||
1394 | return count; | 1402 | return count; |
1395 | } | 1403 | } |
1396 | 1404 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 08c4396cf41..d13f4fb3853 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -231,6 +231,10 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
231 | skb->dev = dev; | 231 | skb->dev = dev; |
232 | /* XXX get correct PACKET_ type here */ | 232 | /* XXX get correct PACKET_ type here */ |
233 | skb->pkt_type = PACKET_HOST; | 233 | skb->pkt_type = PACKET_HOST; |
234 | |||
235 | if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok)) | ||
236 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
237 | |||
234 | netif_receive_skb(skb); | 238 | netif_receive_skb(skb); |
235 | 239 | ||
236 | repost: | 240 | repost: |
@@ -442,6 +446,11 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
442 | return; | 446 | return; |
443 | } | 447 | } |
444 | 448 | ||
449 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
450 | priv->tx_wr.send_flags |= IB_SEND_IP_CSUM; | ||
451 | else | ||
452 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; | ||
453 | |||
445 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), | 454 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
446 | address->ah, qpn, | 455 | address->ah, qpn, |
447 | tx_req->mapping, skb_headlen(skb), | 456 | tx_req->mapping, skb_headlen(skb), |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 57282048865..329b4675aec 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -1105,6 +1105,7 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1105 | struct ib_device *hca, u8 port) | 1105 | struct ib_device *hca, u8 port) |
1106 | { | 1106 | { |
1107 | struct ipoib_dev_priv *priv; | 1107 | struct ipoib_dev_priv *priv; |
1108 | struct ib_device_attr *device_attr; | ||
1108 | int result = -ENOMEM; | 1109 | int result = -ENOMEM; |
1109 | 1110 | ||
1110 | priv = ipoib_intf_alloc(format); | 1111 | priv = ipoib_intf_alloc(format); |
@@ -1120,6 +1121,28 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1120 | goto device_init_failed; | 1121 | goto device_init_failed; |
1121 | } | 1122 | } |
1122 | 1123 | ||
1124 | device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); | ||
1125 | if (!device_attr) { | ||
1126 | printk(KERN_WARNING "%s: allocation of %zu bytes failed\n", | ||
1127 | hca->name, sizeof *device_attr); | ||
1128 | goto device_init_failed; | ||
1129 | } | ||
1130 | |||
1131 | result = ib_query_device(hca, device_attr); | ||
1132 | if (result) { | ||
1133 | printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n", | ||
1134 | hca->name, result); | ||
1135 | kfree(device_attr); | ||
1136 | goto device_init_failed; | ||
1137 | } | ||
1138 | |||
1139 | if (device_attr->device_cap_flags & IB_DEVICE_UD_IP_CSUM) { | ||
1140 | set_bit(IPOIB_FLAG_CSUM, &priv->flags); | ||
1141 | priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | ||
1142 | } | ||
1143 | |||
1144 | kfree(device_attr); | ||
1145 | |||
1123 | /* | 1146 | /* |
1124 | * Set the full membership bit, so that we join the right | 1147 | * Set the full membership bit, so that we join the right |
1125 | * broadcast group, etc. | 1148 | * broadcast group, etc. |
@@ -1137,7 +1160,6 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1137 | } else | 1160 | } else |
1138 | memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid)); | 1161 | memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid)); |
1139 | 1162 | ||
1140 | |||
1141 | result = ipoib_dev_init(priv->dev, hca, port); | 1163 | result = ipoib_dev_init(priv->dev, hca, port); |
1142 | if (result < 0) { | 1164 | if (result < 0) { |
1143 | printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n", | 1165 | printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n", |