aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2008-04-16 21:01:10 -0700
committerRoland Dreier <rolandd@cisco.com>2008-04-16 21:01:10 -0700
commit8ff095ec4bce7be943beff3b330562e2f0e42167 (patch)
treed0643b575033a033a072c2c0687be7e57d183d99 /drivers/infiniband
parent6046136c742e32d5e6431cdcd8957638d1816821 (diff)
downloadkernel_samsung_smdk4412-8ff095ec4bce7be943beff3b330562e2f0e42167.zip
kernel_samsung_smdk4412-8ff095ec4bce7be943beff3b330562e2f0e42167.tar.gz
kernel_samsung_smdk4412-8ff095ec4bce7be943beff3b330562e2f0e42167.tar.bz2
IB/mlx4: Add IPoIB checksum offload support
ConnectX devices support checksum generation and verification of TCP and UDP packets for UD IPoIB messages. This patch checks if the HCA supports this and sets the IB_DEVICE_UD_IP_CSUM capability flag if it does. It implements support for handling the IB_SEND_IP_CSUM send flag and setting the csum_ok field in receive work completions. Signed-off-by: Eli Cohen <eli@mellanox.co.il> Signed-off-by: Ali Ayub <ali@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c16
-rw-r--r--drivers/infiniband/hw/mlx4/main.c2
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c3
3 files changed, 21 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 7360bba..d2e32b0 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -297,6 +297,20 @@ static void mlx4_ib_handle_error_cqe(struct mlx4_err_cqe *cqe,
wc->vendor_err = cqe->vendor_err_syndrome;
}
+static int mlx4_ib_ipoib_csum_ok(__be32 status, __be16 checksum)
+{
+ return ((status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4 |
+ MLX4_CQE_IPOIB_STATUS_IPV4F |
+ MLX4_CQE_IPOIB_STATUS_IPV4OPT |
+ MLX4_CQE_IPOIB_STATUS_IPV6 |
+ MLX4_CQE_IPOIB_STATUS_IPOK)) ==
+ cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4 |
+ MLX4_CQE_IPOIB_STATUS_IPOK)) &&
+ (status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_UDP |
+ MLX4_CQE_IPOIB_STATUS_TCP)) &&
+ checksum == cpu_to_be16(0xffff);
+}
+
static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
struct mlx4_ib_qp **cur_qp,
struct ib_wc *wc)
@@ -434,6 +448,8 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f;
wc->wc_flags |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0;
wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f;
+ wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->ipoib_status,
+ cqe->checksum);
}
return 0;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index d551201..6ea4746 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -99,6 +99,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
props->device_cap_flags |= IB_DEVICE_AUTO_PATH_MIG;
if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UD_AV_PORT)
props->device_cap_flags |= IB_DEVICE_UD_AV_PORT_ENFORCE;
+ if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_IPOIB_CSUM)
+ props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
0xffffff;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index ac965ab..31b2b5b 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1436,6 +1436,9 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE) : 0) |
(wr->send_flags & IB_SEND_SOLICITED ?
cpu_to_be32(MLX4_WQE_CTRL_SOLICITED) : 0) |
+ ((wr->send_flags & IB_SEND_IP_CSUM) ?
+ cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
+ MLX4_WQE_CTRL_TCP_UDP_CSUM) : 0) |
qp->sq_signal_bits;
if (wr->opcode == IB_WR_SEND_WITH_IMM ||