[IPOIB, MLX4] Checksum offload (mlnx: 2828)
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 22 Jul 2008 06:48:18 +0000 (06:48 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 22 Jul 2008 06:48:18 +0000 (06:48 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@1430 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

12 files changed:
hw/mlx4/kernel/bus/ib/cq.c
hw/mlx4/kernel/bus/ib/main.c
hw/mlx4/kernel/bus/ib/qp.c
hw/mlx4/kernel/bus/inc/cq.h
hw/mlx4/kernel/bus/inc/ib_verbs.h
hw/mlx4/kernel/bus/inc/qp.h
hw/mlx4/kernel/bus/net/fw.c
hw/mlx4/kernel/hca/data.c
inc/iba/ib_types.h
ulp/ipoib/kernel/ipoib_port.c
ulp/ipoib/kernel/ipoib_port.h
ulp/opensm/user/include/iba/ib_types_extended.h

index 23985b3..b13d596 100644 (file)
@@ -334,6 +334,32 @@ static void mlx4_ib_handle_error_cqe(struct mlx4_err_cqe *cqe,
        wc->vendor_specific = cqe->vendor_err_syndrome;
 }
 
+static uint8_t mlx4_ib_ipoib_csum_ok(__be32 status, __be16 checksum) {
+       
+       #define CSUM_VALID_NUM 0xffff
+       uint8_t res = 0;
+
+       // Verify that IP_OK bit is set and the packet is pure IPv4 packet
+       if ((status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4            |
+                                                       MLX4_CQE_IPOIB_STATUS_IPV4              |
+                                                       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))
+       {
+               // IP checksum calculated by MLX4 matched the checksum in the receive packet's 
+               res |= MLX4_NdisPacketIpChecksumSucceeded;
+               if (checksum == CSUM_VALID_NUM) {
+                               // TCP or UDP checksum calculated by MLX4 matched the checksum in the receive packet's 
+                               res |= (MLX4_NdisPacketUdpChecksumSucceeded |
+                                               MLX4_NdisPacketTcpChecksumSucceeded );
+                               ASSERT( status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_TCP | MLX4_CQE_IPOIB_STATUS_UDP));
+               }
+       }
+       return res;
+}
+
 static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                            struct mlx4_ib_qp **cur_qp,
                            ib_wc_t *wc)
@@ -465,6 +491,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                wc->recv.ud.path_bits           = (u8)(cqe->g_mlpath_rqpn & 0x7f);
                wc->recv.ud.recv_opt            |= cqe->g_mlpath_rqpn & 0x080 ? IB_RECV_OPT_GRH_VALID : 0;
                wc->recv.ud.pkey_index  = (u16)(be32_to_cpu(cqe->immed_rss_invalid)  & 0x7f);
+               wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->ipoib_status,cqe->checksum);
        }
        if (!is_send && cqe->rlid == 0){
                MLX4_PRINT(TRACE_LEVEL_INFORMATION,MLX4_DBG_CQ,("found rlid == 0 \n "));
index d90aaad..e5115ec 100644 (file)
@@ -82,7 +82,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_IPOIB_CSUM;
        props->vendor_id           = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
                0xffffff;
        props->vendor_part_id      = be16_to_cpup((__be16 *) (out_mad->data + 30));
index 6ab2e28..06f2985 100644 (file)
@@ -1362,6 +1362,10 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, ib_send_wr_t *wr,
                         cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE) : 0) |
                        (wr->send_opt & IB_SEND_OPT_SOLICITED ?
                         cpu_to_be32(MLX4_WQE_CTRL_SOLICITED) : 0) |
+                       (wr->send_opt & IB_SEND_OPT_TX_IP_CSUM ?
+                        cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM) : 0) |
+                       (wr->send_opt & IB_SEND_OPT_TX_TCP_UDP_CSUM ?
+                        cpu_to_be32(MLX4_WQE_CTRL_TCP_UDP_CSUM) : 0) |
                        qp->sq_signal_bits;
 
                if (opcode == IB_WR_SEND_WITH_IMM ||
index 5d25370..bef17d5 100644 (file)
@@ -58,20 +58,20 @@ struct mlx4_cq_context {
 };
 
 struct mlx4_cqe {
-       __be32                  my_qpn;
-       __be32                  immed_rss_invalid;
-       __be32                  g_mlpath_rqpn;
+       __be32          my_qpn;
+       __be32          immed_rss_invalid;
+       __be32          g_mlpath_rqpn;
        u8                      sl;
        u8                      reserved1;
-       __be16                  rlid;
-       u32                     reserved2;
-       __be32                  byte_cnt;
-       __be16                  wqe_index;
-       __be16                  checksum;
-       u8                      reserved3[3];
+       __be16          rlid;
+       __be32          ipoib_status;
+       __be32          byte_cnt;
+       __be16          wqe_index;
+       __be16          checksum;
+       u8                      reserved2[3];
        u8                      owner_sr_opcode;
 };
-
+       
 struct mlx4_err_cqe {
        __be32                  my_qpn;
        u32                     reserved1[5];
@@ -104,6 +104,25 @@ enum {
        MLX4_CQE_SYNDROME_REMOTE_ABORTED_ERR            = 0x22,
 };
 
+enum {
+       MLX4_CQE_IPOIB_STATUS_IPV4              = 1 << 22,
+       MLX4_CQE_IPOIB_STATUS_IPV4F             = 1 << 23,
+       MLX4_CQE_IPOIB_STATUS_IPV6              = 1 << 24,
+       MLX4_CQE_IPOIB_STATUS_IPV4OPT   = 1 << 25,
+       MLX4_CQE_IPOIB_STATUS_TCP               = 1 << 26,
+       MLX4_CQE_IPOIB_STATUS_UDP               = 1 << 27,
+       MLX4_CQE_IPOIB_STATUS_IPOK              = 1 << 28
+};
+
+enum { 
+       MLX4_NdisPacketTcpChecksumFailed        = 1 << 1,
+       MLX4_NdisPacketUdpChecksumFailed        = 1 << 2,
+       MLX4_NdisPacketIpChecksumFailed         = 1 << 3,
+       MLX4_NdisPacketTcpChecksumSucceeded = 1 << 4,
+       MLX4_NdisPacketUdpChecksumSucceeded = 1 << 5,
+       MLX4_NdisPacketIpChecksumSucceeded      = 1 << 6
+};
+
 static inline void mlx4_cq_arm(struct mlx4_cq *cq, u32 cmd,
                               void __iomem *uar_page,
                               spinlock_t *doorbell_lock)
index 990740a..3dc8441 100644 (file)
@@ -85,9 +85,10 @@ enum ib_device_cap_flags {
        IB_DEVICE_RC_RNR_NAK_GEN        = (1<<12),
        IB_DEVICE_SRQ_RESIZE            = (1<<13),
        IB_DEVICE_N_NOTIFY_CQ           = (1<<14),
-       IB_DEVICE_ZERO_STAG             = (1<<15),
+       IB_DEVICE_ZERO_STAG                     = (1<<15),
        IB_DEVICE_SEND_W_INV            = (1<<16),
-       IB_DEVICE_MEM_WINDOW            = (1<<17)
+       IB_DEVICE_MEM_WINDOW            = (1<<17),
+       IB_DEVICE_IPOIB_CSUM            = (1<<18)
 };
 
 enum ib_atomic_cap {
index cfb65f2..fb662c4 100644 (file)
@@ -159,6 +159,8 @@ enum {
        MLX4_WQE_CTRL_FENCE     = 1 << 6,
        MLX4_WQE_CTRL_CQ_UPDATE = 3 << 2,
        MLX4_WQE_CTRL_SOLICITED = 1 << 1,
+       MLX4_WQE_CTRL_IP_CSUM           = 1 << 4,
+       MLX4_WQE_CTRL_TCP_UDP_CSUM      = 1 << 5
 };
 
 struct mlx4_wqe_ctrl_seg {
index b18c9b7..ac61f25 100644 (file)
@@ -725,6 +725,10 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
        if (g.mod_enable_qos)
                *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 2);
 
+       /* Enable IPoIB checksumming if we can: */
+       if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IPOIB_CSUM)
+               *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 3);
+
        /* QPC/EEC/CQC/EQC/RDMARC attributes */
 
        MLX4_PUT(inbox, param->qpc_base,      INIT_HCA_QPC_BASE_OFFSET);
index 46e8d17..f4f0492 100644 (file)
@@ -258,6 +258,7 @@ from_hca_cap(
        ca_attr_p->modify_srq_depth      = hca_info_p->device_cap_flags & IB_DEVICE_SRQ_RESIZE;\r
        ca_attr_p->system_image_guid_support = hca_info_p->device_cap_flags & IB_DEVICE_SYS_IMAGE_GUID;\r
        ca_attr_p->hw_agents            = FALSE; // in the context of IBAL then agent is implemented on the host\r
+       ca_attr_p->ipoib_csum           = hca_info_p->device_cap_flags & IB_DEVICE_IPOIB_CSUM;\r
 \r
        ca_attr_p->num_page_sizes = 1;\r
        ca_attr_p->p_page_size[0] = PAGE_SIZE; // TBD: extract an array of page sizes from HCA cap\r
index 8d64c7b..49b9d4d 100644 (file)
@@ -9255,7 +9255,8 @@ typedef struct _ib_ca_attr
        boolean_t                               port_active_event_support;\r
        boolean_t                               system_image_guid_support;\r
        boolean_t                               hw_agents;\r
-\r
+       boolean_t                               ipoib_csum;\r
+       \r
        ib_net64_t                              system_image_guid;\r
 \r
        uint32_t                                num_page_sizes;\r
@@ -10105,7 +10106,11 @@ typedef uint32_t                                       ib_send_opt_t;
 #define IB_SEND_OPT_SOLICITED          0x00000008\r
 #define IB_SEND_OPT_INLINE                     0x00000010\r
 #define IB_SEND_OPT_LOCAL                      0x00000020\r
+#define IB_SEND_OPT_TX_IP_CSUM         0x00000040\r
+#define IB_SEND_OPT_TX_TCP_UDP_CSUM    0x00000080\r
+\r
 #define IB_SEND_OPT_VEND_MASK          0xFFFF0000\r
+\r
 /*\r
 * VALUES\r
 *      The following flags determine the behavior of a work request when\r
@@ -10659,7 +10664,12 @@ typedef struct _ib_wc
 \r
        uint32_t                                length;\r
        ib_wc_status_t                  status;\r
-       uint64_t                                vendor_specific;\r
+       struct {\r
+               uint8_t                         vendor_specific;\r
+               uint8_t                         csum_ok;\r
+               uint16_t                        vendor_specific2;\r
+               uint32_t                        vendor_specific3;\r
+       };\r
 \r
        union _wc_recv\r
        {\r
index bff78c3..75031bd 100644 (file)
@@ -1954,6 +1954,7 @@ __recv_mgr_filter(
                        \r
                }\r
                /* Successful completion.  Get the receive information. */\r
+               p_desc->ndis_csum.Value = (ULONG) p_wc->csum_ok;\r
                cl_perf_start( GetRecvEndpts );\r
                __recv_get_endpts( p_port, p_desc, p_wc, &p_src, &p_dst );\r
                cl_perf_stop( &p_port->p_adapter->perf, GetRecvEndpts );\r
@@ -2501,7 +2502,6 @@ __recv_mgr_prepare_pkt(
        NDIS_STATUS                                                     status;\r
        uint32_t                                                        pkt_filter;\r
        ip_stat_sel_t                                           type;\r
-       NDIS_TCP_IP_CHECKSUM_PACKET_INFO        chksum;\r
        PERF_DECLARE( GetNdisPkt );\r
 \r
        IPOIB_ENTER( IPOIB_DBG_RECV );\r
@@ -2582,14 +2582,9 @@ __recv_mgr_prepare_pkt(
                return IB_INSUFFICIENT_RESOURCES;\r
        }\r
 \r
-       /* Flag the checksums as having been calculated. */\r
-       chksum.Value = 0;\r
-       chksum.Receive.NdisPacketTcpChecksumSucceeded = TRUE;\r
-       chksum.Receive.NdisPacketUdpChecksumSucceeded = TRUE;\r
-       chksum.Receive.NdisPacketIpChecksumSucceeded = TRUE;\r
-       NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) =\r
-               (void*)(uintn_t)chksum.Value;\r
-\r
+       /* Get the checksums directly from packet information. */\r
+       NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) = \r
+               (PVOID) (uintn_t) (p_desc->ndis_csum.Value);\r
        ipoib_inc_recv_stat( p_port->p_adapter, type, p_desc->len );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_RECV );\r
@@ -3618,6 +3613,8 @@ __build_send_desc(
 {\r
        NDIS_STATUS                     status;\r
        int32_t                         hdr_idx;\r
+       PNDIS_PACKET_EXTENSION                          PktExt;\r
+       PNDIS_TCP_IP_CHECKSUM_PACKET_INFO       pChecksumPktInfo; //NDIS 5.1\r
 \r
        PERF_DECLARE( SendMgrFilter );\r
 \r
@@ -3652,6 +3649,23 @@ __build_send_desc(
        p_desc->wr.wr_id = (uintn_t)p_desc->p_pkt;\r
        p_desc->wr.wr_type = WR_SEND;\r
        p_desc->wr.send_opt = IB_SEND_OPT_SIGNALED;\r
+       \r
+       PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET(p_desc->p_pkt);\r
+       pChecksumPktInfo = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo];\r
+       if(p_port->p_adapter->params.send_chksum_offload & \r
+               (pChecksumPktInfo->Transmit.NdisPacketChecksumV4 || pChecksumPktInfo->Transmit.NdisPacketChecksumV6))\r
+       {\r
+               // Set transimition checksum offloading \r
+               if (pChecksumPktInfo->Transmit.NdisPacketIpChecksum) \r
+               {\r
+                       p_desc->wr.send_opt |= IB_SEND_OPT_TX_IP_CSUM;\r
+               }\r
+               if(pChecksumPktInfo->Transmit.NdisPacketTcpChecksum  ) \r
+               {\r
+                       p_desc->wr.send_opt |= IB_SEND_OPT_TX_TCP_UDP_CSUM;\r
+               }\r
+       }\r
+       \r
        p_desc->wr.ds_array = p_desc->local_ds;\r
 \r
        p_desc->wr.dgrm.ud.remote_qp = p_desc->p_endpt->qpn;\r
index 04ecd1c..b312210 100644 (file)
@@ -333,6 +333,7 @@ typedef struct _ipoib_recv_desc
        ipoib_pkt_type_t        type;\r
        ib_recv_wr_t            wr;\r
        ib_local_ds_t           local_ds[2];\r
+       NDIS_TCP_IP_CHECKSUM_PACKET_INFO        ndis_csum;\r
 #if IPOIB_INLINE_RECV\r
        recv_buf_t                      buf;\r
 #else\r
index f3af31a..464ba95 100644 (file)
@@ -697,7 +697,7 @@ typedef struct _ib_ca_attr
        boolean_t                               port_active_event_support;\r
        boolean_t                               system_image_guid_support;\r
        boolean_t                               hw_agents;\r
-\r
+       boolean_t                               ipoib_csum;\r
        ib_net64_t                              system_image_guid;\r
 \r
        uint32_t                                num_page_sizes;\r
@@ -2018,7 +2018,12 @@ typedef struct _ib_wc
 \r
        uint32_t                                length;\r
        ib_wc_status_t                  status;\r
-       uint64_t                                vendor_specific;\r
+       struct {\r
+               uint8_t                         vendor_specific;\r
+               uint8_t                         csum_ok;\r
+               uint16_t                        vendor_specific2;\r
+               uint32_t                        vendor_specific3;\r
+       };\r
 \r
        union _wc_recv\r
        {\r