[IPOIB, MLX4] Improving checksum mechanism (mlnx: 3107)
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 8 Sep 2008 07:34:32 +0000 (07:34 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 8 Sep 2008 07:34:32 +0000 (07:34 +0000)
Signed off by:xalex

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@1566 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

hw/mlx4/kernel/bus/ib/cq.c
ulp/ipoib/kernel/ipoib_adapter.h
ulp/ipoib/kernel/ipoib_driver.c
ulp/ipoib/kernel/ipoib_port.c
ulp/ipoib/kernel/netipoib.inx

index 3b80a83..4c504bc 100644 (file)
@@ -498,7 +498,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                wc->recv.ud.path_bits           = (u8)(cqe->g_mlpath_rqpn & 0x7f);\r
                wc->recv.ud.recv_opt            |= cqe->g_mlpath_rqpn & 0x080 ? IB_RECV_OPT_GRH_VALID : 0;\r
                wc->recv.ud.pkey_index  = (u16)(be32_to_cpu(cqe->immed_rss_invalid)  & 0x7f);\r
-               wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->ipoib_status,cqe->checksum);\r
+               wc->recv.ud.csum_ok = mlx4_ib_ipoib_csum_ok(cqe->ipoib_status,cqe->checksum);\r
        }\r
        if (!is_send && cqe->rlid == 0){\r
                MLX4_PRINT(TRACE_LEVEL_INFORMATION,MLX4_DBG_CQ,("found rlid == 0 \n "));\r
index d59e958..72597fd 100644 (file)
 /*\r
  * Macros\r
  */\r
-\r
+typedef enum {CSUM_DISABLED = 0, CSUM_ENABLED, CSUM_BYPASS} tCsumTypeEn;\r
 \r
 typedef struct _ipoib_params\r
 {\r
        int32_t         rq_depth;\r
        int32_t         rq_low_watermark;\r
        int32_t         sq_depth;\r
-       boolean_t       send_chksum_offload;\r
-       boolean_t       recv_chksum_offload;\r
+       int32_t         send_chksum_offload;  //is actually of type tCsumTypeEn\r
+       int32_t         recv_chksum_offload; //is actually of type tCsumTypeEn\r
        uint32_t        sa_timeout;\r
        uint32_t        sa_retry_cnt;\r
        uint32_t        recv_pool_ratio;\r
@@ -91,12 +91,11 @@ typedef struct _ipoib_params
 *              Number of send WQEs to allocate.\r
 *\r
 *      send_chksum_offload\r
-*              Flag to indicate whether to offload send checksums.  This will make it\r
-*              so that IPoIB packets should never be forwarded out of the IB subnet\r
-*              without recalculating the checksum.\r
-*\r
 *      recv_chksum_offload\r
-*              Flag to indicate whether to offload recv checksums.\r
+*              Flags to indicate whether to offload send/recv checksums.\r
+*              0 - No hardware cheksum\r
+*              1 - Try to offload if the device support it\r
+*              2 - Always report success (checksum bypass)\r
 *\r
 *      wsdp_enabled\r
 *              Flag to indicate whether WSDP is enabled for an adapter adapter.\r
index 0cbf283..cf28f65 100644 (file)
@@ -150,8 +150,8 @@ IPOIB_REG_ENTRY HCARegTable[] = {
        {NDIS_STRING_CONST("RqDepth"),          1, IPOIB_OFFSET(rq_depth),              IPOIB_SIZE(rq_depth),           512,        128,    1024},\r
        {NDIS_STRING_CONST("RqLowWatermark"),   0, IPOIB_OFFSET(rq_low_watermark),      IPOIB_SIZE(rq_low_watermark),   4,          2,      8},\r
        {NDIS_STRING_CONST("SqDepth"),          1, IPOIB_OFFSET(sq_depth),              IPOIB_SIZE(sq_depth),           512,        128,    1024},\r
-       {NDIS_STRING_CONST("SendChksum"),       1, IPOIB_OFFSET(send_chksum_offload),   IPOIB_SIZE(send_chksum_offload),0,          0,      1},\r
-       {NDIS_STRING_CONST("RecvChksum"),       1, IPOIB_OFFSET(recv_chksum_offload),   IPOIB_SIZE(recv_chksum_offload),0,          0,      1},\r
+       {NDIS_STRING_CONST("SendChksum"),       1, IPOIB_OFFSET(send_chksum_offload),   IPOIB_SIZE(send_chksum_offload),CSUM_ENABLED,CSUM_DISABLED,CSUM_BYPASS},\r
+       {NDIS_STRING_CONST("RecvChksum"),       1, IPOIB_OFFSET(recv_chksum_offload),   IPOIB_SIZE(recv_chksum_offload),CSUM_ENABLED,CSUM_DISABLED,CSUM_BYPASS},\r
        {NDIS_STRING_CONST("SaTimeout"),        1, IPOIB_OFFSET(sa_timeout),            IPOIB_SIZE(sa_timeout),         1000,       250,    UINT_MAX},\r
        {NDIS_STRING_CONST("SaRetries"),        1, IPOIB_OFFSET(sa_retry_cnt),          IPOIB_SIZE(sa_retry_cnt),       10,         1,      UINT_MAX},\r
        {NDIS_STRING_CONST("RecvRatio"),        1, IPOIB_OFFSET(recv_pool_ratio),       IPOIB_SIZE(recv_pool_ratio),    1,          1,      10},\r
@@ -1450,28 +1450,20 @@ __ipoib_get_tcp_task_offload(
        p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);\r
        p_offload_chksum =\r
                (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
-\r
+       \r
        p_offload_chksum->V4Transmit.IpOptionsSupported =\r
-               p_adapter->params.send_chksum_offload;\r
        p_offload_chksum->V4Transmit.TcpOptionsSupported =\r
-               p_adapter->params.send_chksum_offload;\r
        p_offload_chksum->V4Transmit.TcpChecksum =\r
-               p_adapter->params.send_chksum_offload;\r
        p_offload_chksum->V4Transmit.UdpChecksum =\r
-               p_adapter->params.send_chksum_offload;\r
        p_offload_chksum->V4Transmit.IpChecksum =\r
-               p_adapter->params.send_chksum_offload;\r
+               !!(p_adapter->params.send_chksum_offload);\r
 \r
        p_offload_chksum->V4Receive.IpOptionsSupported =\r
-               p_adapter->params.recv_chksum_offload;\r
        p_offload_chksum->V4Receive.TcpOptionsSupported =\r
-               p_adapter->params.recv_chksum_offload;\r
        p_offload_chksum->V4Receive.TcpChecksum =\r
-                       p_adapter->params.recv_chksum_offload;\r
        p_offload_chksum->V4Receive.UdpChecksum =\r
-               p_adapter->params.recv_chksum_offload;\r
        p_offload_chksum->V4Receive.IpChecksum =\r
-               p_adapter->params.recv_chksum_offload;\r
+               !!(p_adapter->params.recv_chksum_offload);\r
 \r
        p_offload_chksum->V6Transmit.IpOptionsSupported = FALSE;\r
        p_offload_chksum->V6Transmit.TcpOptionsSupported = FALSE;\r
index 51502fa..dbc7c01 100644 (file)
@@ -825,6 +825,8 @@ __ib_mgr_init(
        uint64_t                        vaddr;\r
        net32_t                         rkey;\r
        ib_qp_attr_t            qp_attr;\r
+       ib_ca_attr_t *          p_ca_attr;\r
+       uint32_t                        attr_size;\r
 \r
        IPOIB_ENTER( IPOIB_DBG_INIT );\r
 \r
@@ -889,7 +891,7 @@ __ib_mgr_init(
                        p_port->p_adapter->p_ifc->get_err_str( status )) );\r
                return status;\r
        }\r
-\r
+       \r
        /* Allocate the QP. */\r
        cl_memclr( &qp_create, sizeof(qp_create) );\r
        qp_create.qp_type = IB_QPT_UNRELIABLE_DGRM;\r
@@ -897,8 +899,47 @@ __ib_mgr_init(
        qp_create.rq_sge = 2;   /* To support buffers spanning pages. */\r
        qp_create.h_rq_cq = p_port->ib_mgr.h_recv_cq;\r
        qp_create.sq_depth = p_port->p_adapter->params.sq_depth;\r
-       //TODO: Figure out the right number of SGE entries for sends.\r
-       qp_create.sq_sge = MAX_SEND_SGE;\r
+       \r
+       //Figure out the right number of SGE entries for sends.\r
+       /* Get the size of the CA attribute structure. */\r
+       status = p_port->p_adapter->p_ifc->query_ca( p_port->ib_mgr.h_ca, NULL, &attr_size );\r
+       if( status != IB_INSUFFICIENT_MEMORY )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ib_query_ca failed with status %s.\n", p_port->p_adapter->p_ifc->get_err_str(status)) );\r
+               return status;\r
+       }\r
+\r
+       /* Allocate enough space to store the attribute structure. */\r
+       p_ca_attr = cl_malloc( attr_size );\r
+       if( !p_ca_attr )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_malloc failed to allocate p_ca_attr!\n") );\r
+               return IB_INSUFFICIENT_RESOURCES;\r
+       }\r
+\r
+       /* Query the CA attributes. */\r
+       status = p_port->p_adapter->p_ifc->query_ca(p_port->ib_mgr.h_ca, p_ca_attr, &attr_size );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               cl_free( p_ca_attr );\r
+\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ib_query_ca failed with status %s.\n", p_port->p_adapter->p_ifc->get_err_str(status)) );\r
+               return status;\r
+       }\r
+#define UD_QP_USED_SGE 3\r
+       qp_create.sq_sge = MAX_SEND_SGE < p_ca_attr->max_sges ? MAX_SEND_SGE  : (p_ca_attr->max_sges - UD_QP_USED_SGE);\r
+       if (!p_ca_attr->ipoib_csum) { \r
+               //checksum is not supported by device\r
+               //user must specify BYPASS to explicitly cancel checksum calculation\r
+               if (p_port->p_adapter->params.send_chksum_offload == CSUM_ENABLED)\r
+                       p_port->p_adapter->params.send_chksum_offload = CSUM_DISABLED;\r
+               if (p_port->p_adapter->params.recv_chksum_offload == CSUM_ENABLED)\r
+                       p_port->p_adapter->params.recv_chksum_offload = CSUM_DISABLED;\r
+       }\r
+       \r
        qp_create.h_sq_cq = p_port->ib_mgr.h_send_cq;\r
        qp_create.sq_signaled = TRUE;\r
        status = p_port->p_adapter->p_ifc->create_qp(\r
@@ -1937,7 +1978,7 @@ __recv_mgr_filter(
                        \r
                }\r
                /* Successful completion.  Get the receive information. */\r
-               p_desc->ndis_csum.Value = (ULONG) p_wc->csum_ok;\r
+               p_desc->ndis_csum.Value = (ULONG) p_wc->recv.ud.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
@@ -2580,10 +2621,22 @@ __recv_mgr_prepare_pkt(
                        ("__buf_mgr_get_ndis_pkt failed\n") );\r
                return IB_INSUFFICIENT_RESOURCES;\r
        }\r
-\r
+       if (p_port->p_adapter->params.recv_chksum_offload != CSUM_BYPASS) {\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
+       /* In this case, no one of cheksum's cat get false value */\r
+       /* If hardware checksum failed or wasn't calculated, NDIS will recalculate it again */\r
+               NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) = \r
+                       (PVOID) (uintn_t) (p_desc->ndis_csum.Value);\r
+       } else {\r
+               NDIS_TCP_IP_CHECKSUM_PACKET_INFO        chksum;\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
        ipoib_inc_recv_stat( p_port->p_adapter, type, p_desc->len );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_RECV );\r
@@ -3833,9 +3886,9 @@ __build_send_desc(
                p_desc->wr.dgrm.ud.hlen = lso_header_size; \r
                // Tell NDIS how much we will send.\r
                PktExt->NdisPacketInfo[TcpLargeSendPacketInfo] = UlongToPtr(PacketLength);\r
-               p_desc->wr.send_opt |= (IB_SEND_OPT_TX_IP_CSUM | IB_SEND_OPT_TX_TCP_UDP_CSUM);\r
+               p_desc->wr.send_opt |= (IB_SEND_OPT_TX_IP_CSUM | IB_SEND_OPT_TX_TCP_UDP_CSUM) | IB_SEND_OPT_SIGNALED;\r
                __send_gen(p_port, p_desc, IndexOfData);\r
-               p_desc->wr.wr_type = ( WR_LSO | IB_SEND_OPT_SIGNALED);\r
+               p_desc->wr.wr_type = WR_LSO;\r
        } else {\r
 \r
                /* Setup the first local data segment (used for the IPoIB header). */\r
index 1c30b55..75ff385 100644 (file)
@@ -95,17 +95,27 @@ HKR, Ndi\Params\SqDepth,            Step,           0, "128"
 \r
 HKR, Ndi\Params\SendChksum,            ParamDesc,      0, "Send Checksum Offload"\r
 HKR, Ndi\Params\SendChksum,            Type,           0, "enum"\r
-HKR, Ndi\Params\SendChksum,            Default,        0, "0"\r
+HKR, Ndi\Params\SendChksum,            Default,        0, "1"\r
 HKR, Ndi\Params\SendChksum,            Optional,       0, "0"\r
 HKR, Ndi\Params\SendChksum\enum,       "0",    0, "Disabled"\r
-HKR, Ndi\Params\SendChksum\enum,       "1",    0, "Enabled"\r
+HKR, Ndi\Params\SendChksum\enum,       "1",    0, "Enabled (if supported by HW)"\r
+HKR, Ndi\Params\SendChksum\enum,       "2",    0, "Bypass"\r
 \r
 HKR, Ndi\Params\RecvChksum,            ParamDesc,      0, "Recv Checksum Offload"\r
 HKR, Ndi\Params\RecvChksum,            Type,           0, "enum"\r
-HKR, Ndi\Params\RecvChksum,            Default,        0, "0"\r
+HKR, Ndi\Params\RecvChksum,            Default,        0, "1"\r
 HKR, Ndi\Params\RecvChksum,            Optional,       0, "0"\r
 HKR, Ndi\Params\RecvChksum\enum,       "0",    0, "Disabled"\r
-HKR, Ndi\Params\RecvChksum\enum,       "1",    0, "Enabled"\r
+HKR, Ndi\Params\RecvChksum\enum,       "1",    0, "Enabled (if supported by HW)"\r
+HKR, Ndi\Params\RecvChksum\enum,       "2",    0, "Bypass"\r
+\r
+HKR, Ndi\Params\lso,           ParamDesc,      0, "Large Send Offload"\r
+HKR, Ndi\Params\lso,           Type,           0, "enum"\r
+HKR, Ndi\Params\lso,           Default,        0, "0"\r
+HKR, Ndi\Params\lso,           Optional,       0, "0"\r
+HKR, Ndi\Params\lso\enum,      "0",    0, "Disabled"\r
+HKR, Ndi\Params\lso\enum,      "1",    0, "Enabled"\r
+\r
 \r
 HKR, Ndi\Params\SaTimeout,             ParamDesc,      0, "SA Query Timeout (ms)"\r
 HKR, Ndi\Params\SaTimeout,             Type,           0, "dword"\r