[ofw] [mthca/mlx4] ChkSum bitfields mismatch?
Fab Tillier
ftillier at windows.microsoft.com
Tue Sep 9 10:52:08 PDT 2008
Hi Xalex,
>
> You are right. This caused to IP checksum to be recalculated again in
> SW
> stack, in spite of the HW offload.
> Bellow is the patch that fixes this problem and persuade IPoIB to
> recalculate csum even if HW returns good value in a case of
> CSUM_DISABLED.
> Tzachi, please apply it
>
> Index: core/al/al_av.c
> ===================================================================
> --- core/al/al_av.c (revision 3107)
> +++ core/al/al_av.c (working copy)
> @@ -153,12 +153,12 @@
> return IB_INVALID_PD_HANDLE;
> }
>
> - status = __check_av_port(h_pd->obj.p_ci_ca, p_av_attr);
> + /*status = __check_av_port(h_pd->obj.p_ci_ca, p_av_attr);
> if( status != IB_SUCCESS )
> {
> AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
> ("IB_INVALID_PORT\n") );
> return status;
> - }
> + }*/
I'm confused by this change - maybe it doesn't belong in this patch?
>
> /* Get an AV tracking structure. */
> h_av = alloc_av();
> Index: hw/mlx4/kernel/bus/inc/cq.h
> ===================================================================
> --- hw/mlx4/kernel/bus/inc/cq.h (revision 3107)
> +++ hw/mlx4/kernel/bus/inc/cq.h (working copy)
> @@ -115,12 +115,12 @@
> };
>
> 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
> + MLX4_NdisPacketTcpChecksumFailed = 1 << 0,
> + MLX4_NdisPacketUdpChecksumFailed = 1 << 1,
> + MLX4_NdisPacketIpChecksumFailed = 1 << 2,
> + MLX4_NdisPacketTcpChecksumSucceeded = 1 << 3,
> + MLX4_NdisPacketUdpChecksumSucceeded = 1 << 4,
> + MLX4_NdisPacketIpChecksumSucceeded = 1 << 5
> };
>
> static inline void mlx4_cq_arm(struct mlx4_cq *cq, u32 cmd,
> Index: hw/mthca/kernel/mthca_cq.c
> ===================================================================
> --- hw/mthca/kernel/mthca_cq.c (revision 3108)
> +++ hw/mthca/kernel/mthca_cq.c (working copy)
> @@ -118,12 +118,12 @@
> };
>
> enum {
> - MTHCA_NdisPacketTcpChecksumFailed = 1 << 1,
> - MTHCA_NdisPacketUdpChecksumFailed = 1 << 2,
> - MTHCA_NdisPacketIpChecksumFailed = 1 << 3,
> - MTHCA_NdisPacketTcpChecksumSucceeded = 1 << 4,
> - MTHCA_NdisPacketUdpChecksumSucceeded = 1 << 5,
> - MTHCA_NdisPacketIpChecksumSucceeded = 1 << 6
> + MTHCA_NdisPacketTcpChecksumFailed = 1 << 0,
> + MTHCA_NdisPacketUdpChecksumFailed = 1 << 1,
> + MTHCA_NdisPacketIpChecksumFailed = 1 << 2,
> + MTHCA_NdisPacketTcpChecksumSucceeded = 1 << 3,
> + MTHCA_NdisPacketUdpChecksumSucceeded = 1 << 4,
> + MTHCA_NdisPacketIpChecksumSucceeded = 1 << 5
> };
For the HCA driver fields, why not just use the NDIS_TCP_IP_CHECKSUM_PACKET_INFO rather than making your own enum? Is there an issue including ndis.h in the HCA driver?
> struct mthca_cqe {
> Index: inc/iba/ib_types.h
> ===================================================================
> --- inc/iba/ib_types.h (revision 3107)
> +++ inc/iba/ib_types.h (working copy)
> @@ -11395,3 +11395,4 @@
>
>
>
> +
This change probably doesn't belong in this patch.
> Index: ulp/ipoib/kernel/ipoib_port.c
> ===================================================================
> --- ulp/ipoib/kernel/ipoib_port.c (revision 3107)
> +++ ulp/ipoib/kernel/ipoib_port.c (working copy)
> @@ -2542,6 +2542,8 @@
> NDIS_STATUS
> status;
> uint32_t
> pkt_filter;
> ip_stat_sel_t type;
> + NDIS_TCP_IP_CHECKSUM_PACKET_INFO chksum;
> +
> PERF_DECLARE( GetNdisPkt );
>
> IPOIB_ENTER( IPOIB_DBG_RECV );
> @@ -2621,21 +2623,30 @@
> ("__buf_mgr_get_ndis_pkt failed\n") );
> return IB_INSUFFICIENT_RESOURCES;
> }
> - if (p_port->p_adapter->params.recv_chksum_offload !=
> CSUM_BYPASS) {
> - /* Get the checksums directly from packet information. */
> - /* In this case, no one of cheksum's cat get false value */
> - /* If hardware checksum failed or wasn't calculated, NDIS will
> recalculate it again */
> +
> + chksum.Value = 0;
> + switch (p_port->p_adapter->params.recv_chksum_offload) {
> + case CSUM_DISABLED:
> + NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet,
> TcpIpChecksumPacketInfo ) =
> + (void*)(uintn_t)chksum.Value;
> + break;
> + case CSUM_ENABLED:
> + /* Get the checksums directly from packet information.
> */
> + /* In this case, no one of cheksum's cat get false
> value
> */
> + /* If hardware checksum failed or wasn't calculated,
> NDIS will recalculate it again */
> NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet,
> TcpIpChecksumPacketInfo ) =
> - (PVOID) (uintn_t) (p_desc->ndis_csum.Value);
> - } else {
> - NDIS_TCP_IP_CHECKSUM_PACKET_INFO chksum;
> + (void*)(uintn_t)(p_desc->ndis_csum.Value);
> + break;
> + case CSUM_BYPASS:
> /* Flag the checksums as having been calculated. */
> - chksum.Value = 0;
> chksum.Receive.NdisPacketTcpChecksumSucceeded = TRUE;
> chksum.Receive.NdisPacketUdpChecksumSucceeded = TRUE;
> chksum.Receive.NdisPacketIpChecksumSucceeded = TRUE;
> NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet,
> TcpIpChecksumPacketInfo ) =
> (void*)(uintn_t)chksum.Value;
> + break;
> + default:
> + ASSERT(FALSE);
Why not do this check when you store p_desc->ndis_csum? Also, the default case should probably fall through to the CSUM_DISABLED case after asserting so that a release build at least gets the correct behavior.
> }
> ipoib_inc_recv_stat( p_port->p_adapter, type, p_desc->len );
More information about the ofw
mailing list