diff mbox series

[5/6] RDMA/siw: fix type of CRC field

Message ID 20250127223840.67280-6-ebiggers@kernel.org (mailing list archive)
State New
Headers show
Series RDMA: switch to using CRC32 library functions | expand

Commit Message

Eric Biggers Jan. 27, 2025, 10:38 p.m. UTC
From: Eric Biggers <ebiggers@google.com>

The usual big endian convention of InfiniBand does not apply to the MPA
CRC field, whose transmission is specified in terms of the CRC32
polynomial coefficients.  The coefficients are transmitted in descending
order from the x^31 coefficient to the x^0 one.  When the result is
interpreted as a 32-bit integer using the required reverse mapping
between bits and polynomial coefficients, it's a __le32.

Fix the code to use the correct type.

The endianness conversion to little endian was actually already done in
crypto_shash_final().  Therefore this patch does not change any
behavior, except for adding the missing le32_to_cpu() to the pr_warn()
message in siw_get_trailer() which makes the correct values be printed
on big endian systems.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 drivers/infiniband/sw/siw/iwarp.h     |  2 +-
 drivers/infiniband/sw/siw/siw.h       |  8 ++++----
 drivers/infiniband/sw/siw/siw_qp.c    |  2 +-
 drivers/infiniband/sw/siw/siw_qp_rx.c | 16 +++++++++++-----
 drivers/infiniband/sw/siw/siw_qp_tx.c |  2 +-
 5 files changed, 18 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/drivers/infiniband/sw/siw/iwarp.h b/drivers/infiniband/sw/siw/iwarp.h
index 8cf69309827d6..afebb5d8643e3 100644
--- a/drivers/infiniband/sw/siw/iwarp.h
+++ b/drivers/infiniband/sw/siw/iwarp.h
@@ -79,11 +79,11 @@  struct mpa_marker {
 /*
  * maximum MPA trailer
  */
 struct mpa_trailer {
 	__u8 pad[4];
-	__be32 crc;
+	__le32 crc;
 };
 
 #define MPA_HDR_SIZE 2
 #define MPA_CRC_SIZE 4
 
diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h
index ea5eee50dc39d..50649971f6254 100644
--- a/drivers/infiniband/sw/siw/siw.h
+++ b/drivers/infiniband/sw/siw/siw.h
@@ -336,26 +336,26 @@  struct siw_rx_fpdu {
  * Shorthands for short packets w/o payload
  * to be transmitted more efficient.
  */
 struct siw_send_pkt {
 	struct iwarp_send send;
-	__be32 crc;
+	__le32 crc;
 };
 
 struct siw_write_pkt {
 	struct iwarp_rdma_write write;
-	__be32 crc;
+	__le32 crc;
 };
 
 struct siw_rreq_pkt {
 	struct iwarp_rdma_rreq rreq;
-	__be32 crc;
+	__le32 crc;
 };
 
 struct siw_rresp_pkt {
 	struct iwarp_rdma_rresp rresp;
-	__be32 crc;
+	__le32 crc;
 };
 
 struct siw_iwarp_tx {
 	union {
 		union iwarp_hdr hdr;
diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c
index da92cfa2073d7..ea7d2f5c8b8ee 100644
--- a/drivers/infiniband/sw/siw/siw_qp.c
+++ b/drivers/infiniband/sw/siw/siw_qp.c
@@ -394,11 +394,11 @@  void siw_send_terminate(struct siw_qp *qp)
 	struct iwarp_terminate *term = NULL;
 	union iwarp_hdr *err_hdr = NULL;
 	struct socket *s = qp->attrs.sk;
 	struct siw_rx_stream *srx = &qp->rx_stream;
 	union iwarp_hdr *rx_hdr = &srx->hdr;
-	u32 crc = 0;
+	__le32 crc = 0;
 	int num_frags, len_terminate, rv;
 
 	if (!qp->term_info.valid)
 		return;
 
diff --git a/drivers/infiniband/sw/siw/siw_qp_rx.c b/drivers/infiniband/sw/siw/siw_qp_rx.c
index ed4fc39718b49..098e32fb36fb1 100644
--- a/drivers/infiniband/sw/siw/siw_qp_rx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_rx.c
@@ -951,11 +951,11 @@  int siw_proc_terminate(struct siw_qp *qp)
 static int siw_get_trailer(struct siw_qp *qp, struct siw_rx_stream *srx)
 {
 	struct sk_buff *skb = srx->skb;
 	int avail = min(srx->skb_new, srx->fpdu_part_rem);
 	u8 *tbuf = (u8 *)&srx->trailer.crc - srx->pad;
-	__wsum crc_in, crc_own = 0;
+	__le32 crc_in, crc_own = 0;
 
 	siw_dbg_qp(qp, "expected %d, available %d, pad %u\n",
 		   srx->fpdu_part_rem, srx->skb_new, srx->pad);
 
 	skb_copy_bits(skb, srx->skb_offset, tbuf, avail);
@@ -969,20 +969,26 @@  static int siw_get_trailer(struct siw_qp *qp, struct siw_rx_stream *srx)
 	if (!srx->mpa_crc_hd)
 		return 0;
 
 	if (srx->pad)
 		crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad);
+
 	/*
-	 * CRC32 is computed, transmitted and received directly in NBO,
-	 * so there's never a reason to convert byte order.
+	 * The usual big endian convention of InfiniBand does not apply to the
+	 * CRC field, whose transmission is specified in terms of the CRC32
+	 * polynomial coefficients.  The coefficients are transmitted in
+	 * descending order from the x^31 coefficient to the x^0 one.  When the
+	 * result is interpreted as a 32-bit integer using the required reverse
+	 * mapping between bits and polynomial coefficients, it's a __le32.
 	 */
 	crypto_shash_final(srx->mpa_crc_hd, (u8 *)&crc_own);
-	crc_in = (__force __wsum)srx->trailer.crc;
+	crc_in = srx->trailer.crc;
 
 	if (unlikely(crc_in != crc_own)) {
 		pr_warn("siw: crc error. in: %08x, own %08x, op %u\n",
-			crc_in, crc_own, qp->rx_stream.rdmap_op);
+			le32_to_cpu(crc_in), le32_to_cpu(crc_own),
+			qp->rx_stream.rdmap_op);
 
 		siw_init_terminate(qp, TERM_ERROR_LAYER_LLP,
 				   LLP_ETYPE_MPA,
 				   LLP_ECODE_RECEIVED_CRC, 0);
 		return -EINVAL;
diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
index a034264c56698..f9db69a82cdd5 100644
--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -242,11 +242,11 @@  static int siw_qp_prepare_tx(struct siw_iwarp_tx *c_tx)
 			else
 				c_tx->pkt.c_tagged.ddp_to =
 					cpu_to_be64(wqe->sqe.raddr);
 		}
 
-		*(u32 *)crc = 0;
+		*(__le32 *)crc = 0;
 		/*
 		 * Do complete CRC if enabled and short packet
 		 */
 		if (c_tx->mpa_crc_hd &&
 		    crypto_shash_digest(c_tx->mpa_crc_hd, (u8 *)&c_tx->pkt,