Commit 680b575f authored by Eli Cohen's avatar Eli Cohen Committed by Roland Dreier

IB/mthca: Add IPoIB checksum offload support

Arbel and Sinai 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: default avatarEli Cohen <eli@mellnaox.co.il>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 8ff095ec
...@@ -1339,6 +1339,10 @@ int mthca_INIT_HCA(struct mthca_dev *dev, ...@@ -1339,6 +1339,10 @@ int mthca_INIT_HCA(struct mthca_dev *dev,
/* Check port for UD address vector: */ /* Check port for UD address vector: */
*(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1); *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1);
/* Enable IPoIB checksumming if we can: */
if (dev->device_cap_flags & IB_DEVICE_UD_IP_CSUM)
*(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(7 << 3);
/* We leave wqe_quota, responder_exu, etc as 0 (default) */ /* We leave wqe_quota, responder_exu, etc as 0 (default) */
/* QPC/EEC/CQC/EQC/RDB attributes */ /* QPC/EEC/CQC/EQC/RDB attributes */
......
...@@ -103,6 +103,7 @@ enum { ...@@ -103,6 +103,7 @@ enum {
DEV_LIM_FLAG_RAW_IPV6 = 1 << 4, DEV_LIM_FLAG_RAW_IPV6 = 1 << 4,
DEV_LIM_FLAG_RAW_ETHER = 1 << 5, DEV_LIM_FLAG_RAW_ETHER = 1 << 5,
DEV_LIM_FLAG_SRQ = 1 << 6, DEV_LIM_FLAG_SRQ = 1 << 6,
DEV_LIM_FLAG_IPOIB_CSUM = 1 << 7,
DEV_LIM_FLAG_BAD_PKEY_CNTR = 1 << 8, DEV_LIM_FLAG_BAD_PKEY_CNTR = 1 << 8,
DEV_LIM_FLAG_BAD_QKEY_CNTR = 1 << 9, DEV_LIM_FLAG_BAD_QKEY_CNTR = 1 << 9,
DEV_LIM_FLAG_MW = 1 << 16, DEV_LIM_FLAG_MW = 1 << 16,
......
...@@ -119,7 +119,8 @@ struct mthca_cqe { ...@@ -119,7 +119,8 @@ struct mthca_cqe {
__be32 my_qpn; __be32 my_qpn;
__be32 my_ee; __be32 my_ee;
__be32 rqpn; __be32 rqpn;
__be16 sl_g_mlpath; u8 sl_ipok;
u8 g_mlpath;
__be16 rlid; __be16 rlid;
__be32 imm_etype_pkey_eec; __be32 imm_etype_pkey_eec;
__be32 byte_cnt; __be32 byte_cnt;
...@@ -493,6 +494,7 @@ static inline int mthca_poll_one(struct mthca_dev *dev, ...@@ -493,6 +494,7 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
int is_send; int is_send;
int free_cqe = 1; int free_cqe = 1;
int err = 0; int err = 0;
u16 checksum;
cqe = next_cqe_sw(cq); cqe = next_cqe_sw(cq);
if (!cqe) if (!cqe)
...@@ -635,12 +637,14 @@ static inline int mthca_poll_one(struct mthca_dev *dev, ...@@ -635,12 +637,14 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
break; break;
} }
entry->slid = be16_to_cpu(cqe->rlid); entry->slid = be16_to_cpu(cqe->rlid);
entry->sl = be16_to_cpu(cqe->sl_g_mlpath) >> 12; entry->sl = cqe->sl_ipok >> 4;
entry->src_qp = be32_to_cpu(cqe->rqpn) & 0xffffff; entry->src_qp = be32_to_cpu(cqe->rqpn) & 0xffffff;
entry->dlid_path_bits = be16_to_cpu(cqe->sl_g_mlpath) & 0x7f; entry->dlid_path_bits = cqe->g_mlpath & 0x7f;
entry->pkey_index = be32_to_cpu(cqe->imm_etype_pkey_eec) >> 16; entry->pkey_index = be32_to_cpu(cqe->imm_etype_pkey_eec) >> 16;
entry->wc_flags |= be16_to_cpu(cqe->sl_g_mlpath) & 0x80 ? entry->wc_flags |= cqe->g_mlpath & 0x80 ? IB_WC_GRH : 0;
IB_WC_GRH : 0; checksum = (be32_to_cpu(cqe->rqpn) >> 24) |
((be32_to_cpu(cqe->my_ee) >> 16) & 0xff00);
entry->csum_ok = (cqe->sl_ipok & 1 && checksum == 0xffff);
} }
entry->status = IB_WC_SUCCESS; entry->status = IB_WC_SUCCESS;
......
...@@ -267,6 +267,10 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim) ...@@ -267,6 +267,10 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim)
if (dev_lim->flags & DEV_LIM_FLAG_SRQ) if (dev_lim->flags & DEV_LIM_FLAG_SRQ)
mdev->mthca_flags |= MTHCA_FLAG_SRQ; mdev->mthca_flags |= MTHCA_FLAG_SRQ;
if (mthca_is_memfree(mdev))
if (dev_lim->flags & DEV_LIM_FLAG_IPOIB_CSUM)
mdev->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
return 0; return 0;
} }
......
...@@ -2015,6 +2015,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, ...@@ -2015,6 +2015,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0) | cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0) |
((wr->send_flags & IB_SEND_SOLICITED) ? ((wr->send_flags & IB_SEND_SOLICITED) ?
cpu_to_be32(MTHCA_NEXT_SOLICIT) : 0) | cpu_to_be32(MTHCA_NEXT_SOLICIT) : 0) |
((wr->send_flags & IB_SEND_IP_CSUM) ?
cpu_to_be32(MTHCA_NEXT_IP_CSUM | MTHCA_NEXT_TCP_UDP_CSUM) : 0) |
cpu_to_be32(1); cpu_to_be32(1);
if (wr->opcode == IB_WR_SEND_WITH_IMM || if (wr->opcode == IB_WR_SEND_WITH_IMM ||
wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
......
...@@ -38,14 +38,16 @@ ...@@ -38,14 +38,16 @@
#include <linux/types.h> #include <linux/types.h>
enum { enum {
MTHCA_NEXT_DBD = 1 << 7, MTHCA_NEXT_DBD = 1 << 7,
MTHCA_NEXT_FENCE = 1 << 6, MTHCA_NEXT_FENCE = 1 << 6,
MTHCA_NEXT_CQ_UPDATE = 1 << 3, MTHCA_NEXT_CQ_UPDATE = 1 << 3,
MTHCA_NEXT_EVENT_GEN = 1 << 2, MTHCA_NEXT_EVENT_GEN = 1 << 2,
MTHCA_NEXT_SOLICIT = 1 << 1, MTHCA_NEXT_SOLICIT = 1 << 1,
MTHCA_NEXT_IP_CSUM = 1 << 4,
MTHCA_MLX_VL15 = 1 << 17, MTHCA_NEXT_TCP_UDP_CSUM = 1 << 5,
MTHCA_MLX_SLR = 1 << 16
MTHCA_MLX_VL15 = 1 << 17,
MTHCA_MLX_SLR = 1 << 16
}; };
enum { enum {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment