]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
RDMA/mlx4: Redo TX checksum offload in line with docs
authorEugene Crosser <evgenii.cherkashin@profitbricks.com>
Thu, 19 Dec 2019 13:48:47 +0000 (15:48 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 3 Jan 2020 20:37:58 +0000 (16:37 -0400)
Ingress checksum offload was not working for IPv6 frames because the
conditional expression that checks validation status passed from the
hardware was not matching the algorithm described in the documentation.

This patch defines L4_CSUM flag (which falls inside the badfcs_enc field
in the existing definition of the CQE layout) and replaces the conditional
expression with the one defined in the "ConnectX(r) Family Programmer's
Manual" document.

Link: https://lore.kernel.org/r/20191219134847.413582-1-leon@kernel.org
Signed-off-by: Eugene Crosser <evgenii.cherkashin@profitbricks.com>
Reviewed-by: Jack Wang <jinpu.wang@profitbricks.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/mlx4/cq.c
include/linux/mlx4/cq.h

index 306b21281fa2ac4c29dc5bc9554c6bde9590d876..72eeb9a85bc50da9994edc853fe9871842647abc 100644 (file)
@@ -568,18 +568,13 @@ static void mlx4_ib_handle_error_cqe(struct mlx4_err_cqe *cqe,
        wc->vendor_err = cqe->vendor_err_syndrome;
 }
 
-static int mlx4_ib_ipoib_csum_ok(__be16 status, __be16 checksum)
+static int mlx4_ib_ipoib_csum_ok(__be16 status, u8 badfcs_enc, __be16 checksum)
 {
-       return ((status & cpu_to_be16(MLX4_CQE_STATUS_IPV4      |
-                                     MLX4_CQE_STATUS_IPV4F     |
-                                     MLX4_CQE_STATUS_IPV4OPT   |
-                                     MLX4_CQE_STATUS_IPV6      |
-                                     MLX4_CQE_STATUS_IPOK)) ==
-               cpu_to_be16(MLX4_CQE_STATUS_IPV4        |
-                           MLX4_CQE_STATUS_IPOK))              &&
-               (status & cpu_to_be16(MLX4_CQE_STATUS_UDP       |
-                                     MLX4_CQE_STATUS_TCP))     &&
-               checksum == cpu_to_be16(0xffff);
+       return ((badfcs_enc & MLX4_CQE_STATUS_L4_CSUM) ||
+               ((status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
+                (status & cpu_to_be16(MLX4_CQE_STATUS_TCP |
+                                      MLX4_CQE_STATUS_UDP)) &&
+                (checksum == cpu_to_be16(0xffff))));
 }
 
 static void use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc,
@@ -855,6 +850,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                wc->wc_flags      |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0;
                wc->pkey_index     = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f;
                wc->wc_flags      |= mlx4_ib_ipoib_csum_ok(cqe->status,
+                                       cqe->badfcs_enc,
                                        cqe->checksum) ? IB_WC_IP_CSUM_OK : 0;
                if (is_eth) {
                        wc->slid = 0;
index 508e8cc5ee860b67d4025d378ce4eba886f215c4..653d2a0aa44cca6ee872dd38cecb9f2222d5a537 100644 (file)
@@ -130,6 +130,11 @@ enum {
        MLX4_CQE_STATUS_IPOK            = 1 << 12,
 };
 
+/* L4_CSUM is logically part of status, but has to checked against badfcs_enc */
+enum {
+       MLX4_CQE_STATUS_L4_CSUM         = 1 << 2,
+};
+
 enum {
        MLX4_CQE_LLC                     = 1,
        MLX4_CQE_SNAP                    = 1 << 1,