Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright(c) 2007 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Maintained at www.Open-FCoE.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #ifndef _FC_FRAME_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #define _FC_FRAME_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <scsi/fc/fc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <scsi/fc/fc_fcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <scsi/fc/fc_encaps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /* some helpful macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define ntohll(x) be64_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define htonll(x) cpu_to_be64(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static inline u32 ntoh24(const u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	return (p[0] << 16) | (p[1] << 8) | p[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static inline void hton24(u8 *p, u32 v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	p[0] = (v >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	p[1] = (v >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	p[2] = v & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * The fc_frame interface is used to pass frame data between functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * The frame includes the data buffer, length, and SOF / EOF delimiter types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * A pointer to the port structure of the receiving port is also includeded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define	FC_FRAME_HEADROOM	32	/* headroom for VLAN + FCoE headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define	FC_FRAME_TAILROOM	8	/* trailer space for FCoE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /* Max number of skb frags allowed, reserving one for fcoe_crc_eof page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define FC_FRAME_SG_LEN		(MAX_SKB_FRAGS - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define fp_skb(fp)	(&((fp)->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define fr_hdr(fp)	((fp)->skb.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define fr_len(fp)	((fp)->skb.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define fr_cb(fp)	((struct fcoe_rcv_info *)&((fp)->skb.cb[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define fr_dev(fp)	(fr_cb(fp)->fr_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define fr_seq(fp)	(fr_cb(fp)->fr_seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define fr_sof(fp)	(fr_cb(fp)->fr_sof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define fr_eof(fp)	(fr_cb(fp)->fr_eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define fr_flags(fp)	(fr_cb(fp)->fr_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define fr_encaps(fp)	(fr_cb(fp)->fr_encaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define fr_max_payload(fp)	(fr_cb(fp)->fr_max_payload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define fr_fsp(fp)	(fr_cb(fp)->fr_fsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define fr_crc(fp)	(fr_cb(fp)->fr_crc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) struct fc_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct sk_buff skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) struct fcoe_rcv_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct fc_lport	*fr_dev;	/* transport layer private pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct fc_seq	*fr_seq;	/* for use with exchange manager */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct fc_fcp_pkt *fr_fsp;	/* for the corresponding fcp I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	u32		fr_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	u16		fr_max_payload;	/* max FC payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	u8		fr_sof;		/* start of frame delimiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	u8		fr_eof;		/* end of frame delimiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	u8		fr_flags;	/* flags - see below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u8		fr_encaps;	/* LLD encapsulation info (e.g. FIP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	u8		granted_mac[ETH_ALEN]; /* FCoE MAC address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * Get fc_frame pointer for an skb that's already been imported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	return (struct fcoe_rcv_info *) skb->cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * fr_flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define	FCPHF_CRC_UNCHECKED	0x01	/* CRC not computed, still appended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * Initialize a frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * We don't do a complete memset here for performance reasons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline void fc_frame_init(struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	fr_dev(fp) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	fr_seq(fp) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	fr_flags(fp) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	fr_encaps(fp) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct fc_frame *_fc_frame_alloc(size_t payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * Allocate fc_frame structure and buffer.  Set the initial length to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * payload_size + sizeof (struct fc_frame_header).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct fc_frame *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 * Note: Since len will often be a constant multiple of 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 * this check will usually be evaluated and eliminated at compile time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (len && len % 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		fp = fc_frame_alloc_fill(dev, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		fp = _fc_frame_alloc(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	return fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * Free the fc_frame structure and buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static inline void fc_frame_free(struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	kfree_skb(fp_skb(fp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline int fc_frame_is_linear(struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return !skb_is_nonlinear(fp_skb(fp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * Get frame header from message in fc_frame structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * This version doesn't do a length check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct fc_frame_header *__fc_frame_header_get(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return (struct fc_frame_header *)fr_hdr(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * Get frame header from message in fc_frame structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * This hides a cast and provides a place to add some checking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	return __fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * Get source FC_ID (S_ID) from frame header in message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static inline u32 fc_frame_sid(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return ntoh24(__fc_frame_header_get(fp)->fh_s_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * Get destination FC_ID (D_ID) from frame header in message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static inline u32 fc_frame_did(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	return ntoh24(__fc_frame_header_get(fp)->fh_d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * Get frame payload from message in fc_frame structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * This hides a cast and provides a place to add some checking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * The len parameter is the minimum length for the payload portion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * Returns NULL if the frame is too short.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * This assumes the interesting part of the payload is in the first part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * of the buffer for received data.  This may not be appropriate to use for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * buffers being transmitted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static inline void *fc_frame_payload_get(const struct fc_frame *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 					 size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	void *pp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (fr_len(fp) >= sizeof(struct fc_frame_header) + len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		pp = fc_frame_header_get(fp) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	return pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * Get frame payload opcode (first byte) from message in fc_frame structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * This hides a cast and provides a place to add some checking. Return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * if the frame has no payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static inline u8 fc_frame_payload_op(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	u8 *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	cp = fc_frame_payload_get(fp, sizeof(u8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (!cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	return *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  * Get FC class from frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static inline enum fc_class fc_frame_class(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return fc_sof_class(fr_sof(fp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * Check the CRC in a frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * The CRC immediately follows the last data item *AFTER* the length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * The return value is zero if the CRC matches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u32 fc_frame_crc_check(struct fc_frame *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static inline u8 fc_frame_rctl(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	return fc_frame_header_get(fp)->fh_r_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static inline bool fc_frame_is_cmd(const struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * Check for leaks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  * Print the frame header of any currently allocated frame, assuming there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  * should be none at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) void fc_frame_leak_check(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #endif /* _FC_FRAME_H_ */