aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2008-04-17 00:01:10 -0400
committerRoland Dreier <rolandd@cisco.com>2008-04-17 00:01:10 -0400
commit6046136c742e32d5e6431cdcd8957638d1816821 (patch)
tree512a0165e982e5bdf93ba0732c4a52b01c84317b /drivers
parent3371836383d63b627b228875f5ac63023cbf11d2 (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')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c9
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c24
4 files changed, 41 insertions, 1 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 054fab8e27a0..08930ca41a30 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 2490b2d79dbb..edf63dc0afe0 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 08c4396cf418..d13f4fb3853f 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
236repost: 240repost:
@@ -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 57282048865c..329b4675aec0 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",