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;
 
        siw_dbg_qp(qp, "expected %d, available %d, pad %u\n",
                   srx->fpdu_part_rem, srx->skb_new, srx->pad);
 
-       if (srx->skb_new < srx->fpdu_part_rem)
-               return -EAGAIN;
-
-       skb_copy_bits(skb, srx->skb_offset, tbuf, srx->fpdu_part_rem);
+       skb_copy_bits(skb, srx->skb_offset, tbuf, avail);
 
-       if (srx->mpa_crc_hd && srx->pad)
-               crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad);
+       srx->skb_new -= avail;
+       srx->skb_offset += avail;
+       srx->skb_copied += avail;
+       srx->fpdu_part_rem -= avail;
 
-       srx->skb_new -= srx->fpdu_part_rem;
-       srx->skb_offset += srx->fpdu_part_rem;
-       srx->skb_copied += srx->fpdu_part_rem;
+       if (srx->fpdu_part_rem)
+               return -EAGAIN;
 
        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.
         * completely received.
         */
        if (iwarp_pktinfo[opcode].hdr_len > sizeof(struct iwarp_ctrl_tagged)) {
-               bytes = iwarp_pktinfo[opcode].hdr_len - MIN_DDP_HDR;
+               int hdrlen = iwarp_pktinfo[opcode].hdr_len;
 
-               if (srx->skb_new < bytes)
-                       return -EAGAIN;
+               bytes = min_t(int, hdrlen - MIN_DDP_HDR, srx->skb_new);
 
                skb_copy_bits(skb, srx->skb_offset,
                              (char *)c_hdr + srx->fpdu_part_rcvd, bytes);
                srx->skb_new -= bytes;
                srx->skb_offset += bytes;
                srx->skb_copied += bytes;
+
+               if (srx->fpdu_part_rcvd < hdrlen)
+                       return -EAGAIN;
        }
 
        /*