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: Eli Cohen <eli@mellnaox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Eli Cohen 2008-04-16 21:01:11 -07:00 committed by Roland Dreier
parent 8ff095ec4b
commit 680b575f6d
6 changed files with 29 additions and 12 deletions

View file

@ -1339,6 +1339,10 @@ int mthca_INIT_HCA(struct mthca_dev *dev,
/* Check port for UD address vector: */
*(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) */
/* QPC/EEC/CQC/EQC/RDB attributes */

View file

@ -103,6 +103,7 @@ enum {
DEV_LIM_FLAG_RAW_IPV6 = 1 << 4,
DEV_LIM_FLAG_RAW_ETHER = 1 << 5,
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_QKEY_CNTR = 1 << 9,
DEV_LIM_FLAG_MW = 1 << 16,

View file

@ -119,7 +119,8 @@ struct mthca_cqe {
__be32 my_qpn;
__be32 my_ee;
__be32 rqpn;
__be16 sl_g_mlpath;
u8 sl_ipok;
u8 g_mlpath;
__be16 rlid;
__be32 imm_etype_pkey_eec;
__be32 byte_cnt;
@ -493,6 +494,7 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
int is_send;
int free_cqe = 1;
int err = 0;
u16 checksum;
cqe = next_cqe_sw(cq);
if (!cqe)
@ -635,12 +637,14 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
break;
}
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->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->wc_flags |= be16_to_cpu(cqe->sl_g_mlpath) & 0x80 ?
IB_WC_GRH : 0;
entry->wc_flags |= cqe->g_mlpath & 0x80 ? 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;

View file

@ -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)
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;
}

View file

@ -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) |
((wr->send_flags & IB_SEND_SOLICITED) ?
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);
if (wr->opcode == IB_WR_SEND_WITH_IMM ||
wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)

View file

@ -38,14 +38,16 @@
#include <linux/types.h>
enum {
MTHCA_NEXT_DBD = 1 << 7,
MTHCA_NEXT_FENCE = 1 << 6,
MTHCA_NEXT_CQ_UPDATE = 1 << 3,
MTHCA_NEXT_EVENT_GEN = 1 << 2,
MTHCA_NEXT_SOLICIT = 1 << 1,
MTHCA_NEXT_DBD = 1 << 7,
MTHCA_NEXT_FENCE = 1 << 6,
MTHCA_NEXT_CQ_UPDATE = 1 << 3,
MTHCA_NEXT_EVENT_GEN = 1 << 2,
MTHCA_NEXT_SOLICIT = 1 << 1,
MTHCA_NEXT_IP_CSUM = 1 << 4,
MTHCA_NEXT_TCP_UDP_CSUM = 1 << 5,
MTHCA_MLX_VL15 = 1 << 17,
MTHCA_MLX_SLR = 1 << 16
MTHCA_MLX_VL15 = 1 << 17,
MTHCA_MLX_SLR = 1 << 16
};
enum {