IB/mthca: Add IPoIB checksum offload support
authorEli Cohen <eli@dev.mellanox.co.il>
Thu, 17 Apr 2008 04:01:11 +0000 (21:01 -0700)
committerRoland Dreier <rolandd@cisco.com>
Thu, 17 Apr 2008 04:01:11 +0000 (21:01 -0700)
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>
drivers/infiniband/hw/mthca/mthca_cmd.c
drivers/infiniband/hw/mthca/mthca_cmd.h
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_wqe.h

index 667c35ddb7ceab7dbea9a66562f837143ff5dcfc..54d230ee7d63aca7ef0d023cc52789244834541b 100644 (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 */
index 2f976f2051d6a1dbc9c39bc0046305d8a72fae66..8928ca4a932569d78ee1b75c122790f4a696408d 100644 (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,
index 1e1e336d3ef9715897088322e3452d5dd366379f..20401d2ba6b2cdd3ee961ecd4963f8043f96117e 100644 (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;
index cd3d8adbef9ffe6a5f6d8d152ad9b5b8aa20c155..3889ae859f51096142d789e37336142a11fccd78 100644 (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;
 }
 
index db5595bbf7f08fb30e5993a301e063b2df21ee05..8433897624bc79f5a7733dc2e3f81bd28719a3da 100644 (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)
index f6a66fe78e486d38dfb6bd453c1d389de31263df..b3551a8dea1d691388a694ffe97cff117060b31e 100644 (file)
 #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_MLX_VL15       = 1 << 17,
-       MTHCA_MLX_SLR        = 1 << 16
+       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
 };
 
 enum {