Linux Audio

Check our new training course

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