On Wed, Jan 29, 2025 at 10:21:47PM +0000, Eric Biggers wrote: > > To be most clear this should be written as: > > > > u32 ibta_crc = swab32(~crc32_le(..)) // Gives you the IBTA defined value > > *packet = cpu_to_be32(ibta_crc); // Puts it in the packet > > > > It follows the spec clearly and exactly. > > > > Yes, you can get the same net effect using le: > > > > u32 not_ibta_crc = ~crc32_le(..) > > *packet = cpu_to_le32(not_ibta_crc) > > > > It does work, but it is very hard to follow how that relates to the > > specification when the u32 is not in the spec's format anymore. > > > > What matters here, in rxe, is how to use the Linux crc32 library to > > get exactly the value written down in the spec. > > > > IMHO the le approach is an optimization to avoid the dobule swap, and > > it should simply be described as such in a comment: > > > > The crc32 library gives a byte swapped result compared to the IBTA > > specification. swab32(~crc32_le(..)) will give values that match > > IBTA. > > > > To avoid double swapping we can instead write: > > *icrc = cpu_to_le32(~crc32_le(..)) > > The value will still be big endian on the network. > > > > No need to talk about coefficients. > > We are looking at the same spec, right? The following is the specification for > the ICRC field: > > The resulting bits are sent in order from the bit representing the > coefficient of the highest term of the remainder polynomial. The least > significant bit, most significant byte first ordering of the packet does not > apply to the ICRC field. > > So it does talk about the polynomial coefficients. Of course it does, it is defining a CRC. The above text is reflected in Figure 57 which shows the Remainder being swapped all around to produce the ICRC. The spec goes on to say: CRC Field is obtained from the Remainder as shown in Figure 57. ICRC Field is transmitted using Big Endian byte ordering like every field of an InfiniBand packet.