aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2008-04-17 00:01:11 -0400
committerRoland Dreier <rolandd@cisco.com>2008-04-17 00:01:11 -0400
commit680b575f6d1ae8aa39c4d7ee7e40b749d277fa9f (patch)
tree202da857b6205b699bd189b63e483387f1c58d94
parent8ff095ec4bce7be943beff3b330562e2f0e42167 (diff)
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>
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c14
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h18
6 files changed, 30 insertions, 13 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 667c35ddb7ce..54d230ee7d63 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1339,6 +1339,10 @@ int mthca_INIT_HCA(struct mthca_dev *dev,
1339 /* Check port for UD address vector: */ 1339 /* Check port for UD address vector: */
1340 *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1); 1340 *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1);
1341 1341
1342 /* Enable IPoIB checksumming if we can: */
1343 if (dev->device_cap_flags & IB_DEVICE_UD_IP_CSUM)
1344 *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(7 << 3);
1345
1342 /* We leave wqe_quota, responder_exu, etc as 0 (default) */ 1346 /* We leave wqe_quota, responder_exu, etc as 0 (default) */
1343 1347
1344 /* QPC/EEC/CQC/EQC/RDB attributes */ 1348 /* QPC/EEC/CQC/EQC/RDB attributes */
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
index 2f976f2051d6..8928ca4a9325 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
@@ -103,6 +103,7 @@ enum {
103 DEV_LIM_FLAG_RAW_IPV6 = 1 << 4, 103 DEV_LIM_FLAG_RAW_IPV6 = 1 << 4,
104 DEV_LIM_FLAG_RAW_ETHER = 1 << 5, 104 DEV_LIM_FLAG_RAW_ETHER = 1 << 5,
105 DEV_LIM_FLAG_SRQ = 1 << 6, 105 DEV_LIM_FLAG_SRQ = 1 << 6,
106 DEV_LIM_FLAG_IPOIB_CSUM = 1 << 7,
106 DEV_LIM_FLAG_BAD_PKEY_CNTR = 1 << 8, 107 DEV_LIM_FLAG_BAD_PKEY_CNTR = 1 << 8,
107 DEV_LIM_FLAG_BAD_QKEY_CNTR = 1 << 9, 108 DEV_LIM_FLAG_BAD_QKEY_CNTR = 1 << 9,
108 DEV_LIM_FLAG_MW = 1 << 16, 109 DEV_LIM_FLAG_MW = 1 << 16,
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 1e1e336d3ef9..20401d2ba6b2 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -119,7 +119,8 @@ struct mthca_cqe {
119 __be32 my_qpn; 119 __be32 my_qpn;
120 __be32 my_ee; 120 __be32 my_ee;
121 __be32 rqpn; 121 __be32 rqpn;
122 __be16 sl_g_mlpath; 122 u8 sl_ipok;
123 u8 g_mlpath;
123 __be16 rlid; 124 __be16 rlid;
124 __be32 imm_etype_pkey_eec; 125 __be32 imm_etype_pkey_eec;
125 __be32 byte_cnt; 126 __be32 byte_cnt;
@@ -493,6 +494,7 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
493 int is_send; 494 int is_send;
494 int free_cqe = 1; 495 int free_cqe = 1;
495 int err = 0; 496 int err = 0;
497 u16 checksum;
496 498
497 cqe = next_cqe_sw(cq); 499 cqe = next_cqe_sw(cq);
498 if (!cqe) 500 if (!cqe)
@@ -635,12 +637,14 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
635 break; 637 break;
636 } 638 }
637 entry->slid = be16_to_cpu(cqe->rlid); 639 entry->slid = be16_to_cpu(cqe->rlid);
638 entry->sl = be16_to_cpu(cqe->sl_g_mlpath) >> 12; 640 entry->sl = cqe->sl_ipok >> 4;
639 entry->src_qp = be32_to_cpu(cqe->rqpn) & 0xffffff; 641 entry->src_qp = be32_to_cpu(cqe->rqpn) & 0xffffff;
640 entry->dlid_path_bits = be16_to_cpu(cqe->sl_g_mlpath) & 0x7f; 642 entry->dlid_path_bits = cqe->g_mlpath & 0x7f;
641 entry->pkey_index = be32_to_cpu(cqe->imm_etype_pkey_eec) >> 16; 643 entry->pkey_index = be32_to_cpu(cqe->imm_etype_pkey_eec) >> 16;
642 entry->wc_flags |= be16_to_cpu(cqe->sl_g_mlpath) & 0x80 ? 644 entry->wc_flags |= cqe->g_mlpath & 0x80 ? IB_WC_GRH : 0;
643 IB_WC_GRH : 0; 645 checksum = (be32_to_cpu(cqe->rqpn) >> 24) |
646 ((be32_to_cpu(cqe->my_ee) >> 16) & 0xff00);
647 entry->csum_ok = (cqe->sl_ipok & 1 && checksum == 0xffff);
644 } 648 }
645 649
646 entry->status = IB_WC_SUCCESS; 650 entry->status = IB_WC_SUCCESS;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index cd3d8adbef9f..3889ae859f51 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -267,6 +267,10 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim)
267 if (dev_lim->flags & DEV_LIM_FLAG_SRQ) 267 if (dev_lim->flags & DEV_LIM_FLAG_SRQ)
268 mdev->mthca_flags |= MTHCA_FLAG_SRQ; 268 mdev->mthca_flags |= MTHCA_FLAG_SRQ;
269 269
270 if (mthca_is_memfree(mdev))
271 if (dev_lim->flags & DEV_LIM_FLAG_IPOIB_CSUM)
272 mdev->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
273
270 return 0; 274 return 0;
271} 275}
272 276
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index db5595bbf7f0..8433897624bc 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -2015,6 +2015,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2015 cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0) | 2015 cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0) |
2016 ((wr->send_flags & IB_SEND_SOLICITED) ? 2016 ((wr->send_flags & IB_SEND_SOLICITED) ?
2017 cpu_to_be32(MTHCA_NEXT_SOLICIT) : 0) | 2017 cpu_to_be32(MTHCA_NEXT_SOLICIT) : 0) |
2018 ((wr->send_flags & IB_SEND_IP_CSUM) ?
2019 cpu_to_be32(MTHCA_NEXT_IP_CSUM | MTHCA_NEXT_TCP_UDP_CSUM) : 0) |
2018 cpu_to_be32(1); 2020 cpu_to_be32(1);
2019 if (wr->opcode == IB_WR_SEND_WITH_IMM || 2021 if (wr->opcode == IB_WR_SEND_WITH_IMM ||
2020 wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) 2022 wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
index f6a66fe78e48..b3551a8dea1d 100644
--- a/drivers/infiniband/hw/mthca/mthca_wqe.h
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -38,14 +38,16 @@
38#include <linux/types.h> 38#include <linux/types.h>
39 39
40enum { 40enum {
41 MTHCA_NEXT_DBD = 1 << 7, 41 MTHCA_NEXT_DBD = 1 << 7,
42 MTHCA_NEXT_FENCE = 1 << 6, 42 MTHCA_NEXT_FENCE = 1 << 6,
43 MTHCA_NEXT_CQ_UPDATE = 1 << 3, 43 MTHCA_NEXT_CQ_UPDATE = 1 << 3,
44 MTHCA_NEXT_EVENT_GEN = 1 << 2, 44 MTHCA_NEXT_EVENT_GEN = 1 << 2,
45 MTHCA_NEXT_SOLICIT = 1 << 1, 45 MTHCA_NEXT_SOLICIT = 1 << 1,
46 46 MTHCA_NEXT_IP_CSUM = 1 << 4,
47 MTHCA_MLX_VL15 = 1 << 17, 47 MTHCA_NEXT_TCP_UDP_CSUM = 1 << 5,
48 MTHCA_MLX_SLR = 1 << 16 48
49 MTHCA_MLX_VL15 = 1 << 17,
50 MTHCA_MLX_SLR = 1 << 16
49}; 51};
50 52
51enum { 53enum {