1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright(c) 2007 Intel Corporation. All rights reserved.
5 * Maintained at www.Open-FCoE.org
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/skbuff.h>
14 #include <linux/crc32.h>
15 #include <linux/gfp.h>
17 #include <scsi/fc_frame.h>
20 * Check the CRC in a frame.
22 u32
fc_frame_crc_check(struct fc_frame
*fp
)
29 WARN_ON(!fc_frame_is_linear(fp
));
30 fr_flags(fp
) &= ~FCPHF_CRC_UNCHECKED
;
31 len
= (fr_len(fp
) + 3) & ~3; /* round up length to include fill */
32 bp
= (const u8
*) fr_hdr(fp
);
33 crc
= ~crc32(~0, bp
, len
);
34 error
= crc
^ fr_crc(fp
);
37 EXPORT_SYMBOL(fc_frame_crc_check
);
40 * Allocate a frame intended to be sent.
41 * Get an sk_buff for the frame and set the length.
43 struct fc_frame
*_fc_frame_alloc(size_t len
)
48 WARN_ON((len
% sizeof(u32
)) != 0);
49 len
+= sizeof(struct fc_frame_header
);
50 skb
= alloc_skb_fclone(len
+ FC_FRAME_HEADROOM
+ FC_FRAME_TAILROOM
+
51 NET_SKB_PAD
, GFP_ATOMIC
);
54 skb_reserve(skb
, NET_SKB_PAD
+ FC_FRAME_HEADROOM
);
55 fp
= (struct fc_frame
*) skb
;
60 EXPORT_SYMBOL(_fc_frame_alloc
);
62 struct fc_frame
*fc_frame_alloc_fill(struct fc_lport
*lp
, size_t payload_len
)
67 fill
= payload_len
% 4;
70 fp
= _fc_frame_alloc(payload_len
+ fill
);
72 memset((char *) fr_hdr(fp
) + payload_len
, 0, fill
);
73 /* trim is OK, we just allocated it so there are no fragments */
75 payload_len
+ sizeof(struct fc_frame_header
));
79 EXPORT_SYMBOL(fc_frame_alloc_fill
);