0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _FC_FRAME_H_
0009 #define _FC_FRAME_H_
0010
0011 #include <linux/scatterlist.h>
0012 #include <linux/skbuff.h>
0013 #include <scsi/scsi_cmnd.h>
0014
0015 #include <scsi/fc/fc_fs.h>
0016 #include <scsi/fc/fc_fcp.h>
0017 #include <scsi/fc/fc_encaps.h>
0018
0019 #include <linux/if_ether.h>
0020
0021
0022
0023 #define ntohll(x) be64_to_cpu(x)
0024 #define htonll(x) cpu_to_be64(x)
0025
0026 static inline u32 ntoh24(const u8 *p)
0027 {
0028 return (p[0] << 16) | (p[1] << 8) | p[2];
0029 }
0030
0031 static inline void hton24(u8 *p, u32 v)
0032 {
0033 p[0] = (v >> 16) & 0xff;
0034 p[1] = (v >> 8) & 0xff;
0035 p[2] = v & 0xff;
0036 }
0037
0038
0039
0040
0041
0042
0043
0044 #define FC_FRAME_HEADROOM 32
0045 #define FC_FRAME_TAILROOM 8
0046
0047
0048 #define FC_FRAME_SG_LEN (MAX_SKB_FRAGS - 1)
0049
0050 #define fp_skb(fp) (&((fp)->skb))
0051 #define fr_hdr(fp) ((fp)->skb.data)
0052 #define fr_len(fp) ((fp)->skb.len)
0053 #define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0]))
0054 #define fr_dev(fp) (fr_cb(fp)->fr_dev)
0055 #define fr_seq(fp) (fr_cb(fp)->fr_seq)
0056 #define fr_sof(fp) (fr_cb(fp)->fr_sof)
0057 #define fr_eof(fp) (fr_cb(fp)->fr_eof)
0058 #define fr_flags(fp) (fr_cb(fp)->fr_flags)
0059 #define fr_encaps(fp) (fr_cb(fp)->fr_encaps)
0060 #define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload)
0061 #define fr_fsp(fp) (fr_cb(fp)->fr_fsp)
0062 #define fr_crc(fp) (fr_cb(fp)->fr_crc)
0063
0064 struct fc_frame {
0065 struct sk_buff skb;
0066 };
0067
0068 struct fcoe_rcv_info {
0069 struct fc_lport *fr_dev;
0070 struct fc_seq *fr_seq;
0071 struct fc_fcp_pkt *fr_fsp;
0072 u32 fr_crc;
0073 u16 fr_max_payload;
0074 u8 fr_sof;
0075 u8 fr_eof;
0076 u8 fr_flags;
0077 u8 fr_encaps;
0078 u8 granted_mac[ETH_ALEN];
0079 };
0080
0081
0082
0083
0084
0085 static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb)
0086 {
0087 BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb));
0088 return (struct fcoe_rcv_info *) skb->cb;
0089 }
0090
0091
0092
0093
0094 #define FCPHF_CRC_UNCHECKED 0x01
0095
0096
0097
0098
0099
0100
0101 static inline void fc_frame_init(struct fc_frame *fp)
0102 {
0103 fr_dev(fp) = NULL;
0104 fr_seq(fp) = NULL;
0105 fr_flags(fp) = 0;
0106 fr_encaps(fp) = 0;
0107 }
0108
0109 struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
0110 struct fc_frame *_fc_frame_alloc(size_t payload_len);
0111
0112
0113
0114
0115
0116 static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len)
0117 {
0118 struct fc_frame *fp;
0119
0120
0121
0122
0123
0124 if (len && len % 4)
0125 fp = fc_frame_alloc_fill(dev, len);
0126 else
0127 fp = _fc_frame_alloc(len);
0128 return fp;
0129 }
0130
0131
0132
0133
0134 static inline void fc_frame_free(struct fc_frame *fp)
0135 {
0136 kfree_skb(fp_skb(fp));
0137 }
0138
0139 static inline int fc_frame_is_linear(struct fc_frame *fp)
0140 {
0141 return !skb_is_nonlinear(fp_skb(fp));
0142 }
0143
0144
0145
0146
0147
0148 static inline
0149 struct fc_frame_header *__fc_frame_header_get(const struct fc_frame *fp)
0150 {
0151 return (struct fc_frame_header *)fr_hdr(fp);
0152 }
0153
0154
0155
0156
0157
0158 static inline
0159 struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp)
0160 {
0161 WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header));
0162 return __fc_frame_header_get(fp);
0163 }
0164
0165
0166
0167
0168 static inline u32 fc_frame_sid(const struct fc_frame *fp)
0169 {
0170 return ntoh24(__fc_frame_header_get(fp)->fh_s_id);
0171 }
0172
0173
0174
0175
0176 static inline u32 fc_frame_did(const struct fc_frame *fp)
0177 {
0178 return ntoh24(__fc_frame_header_get(fp)->fh_d_id);
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 static inline void *fc_frame_payload_get(const struct fc_frame *fp,
0192 size_t len)
0193 {
0194 void *pp = NULL;
0195
0196 if (fr_len(fp) >= sizeof(struct fc_frame_header) + len)
0197 pp = fc_frame_header_get(fp) + 1;
0198 return pp;
0199 }
0200
0201
0202
0203
0204
0205
0206 static inline u8 fc_frame_payload_op(const struct fc_frame *fp)
0207 {
0208 u8 *cp;
0209
0210 cp = fc_frame_payload_get(fp, sizeof(u8));
0211 if (!cp)
0212 return 0;
0213 return *cp;
0214
0215 }
0216
0217
0218
0219
0220 static inline enum fc_class fc_frame_class(const struct fc_frame *fp)
0221 {
0222 return fc_sof_class(fr_sof(fp));
0223 }
0224
0225
0226
0227
0228
0229
0230 u32 fc_frame_crc_check(struct fc_frame *);
0231
0232 static inline u8 fc_frame_rctl(const struct fc_frame *fp)
0233 {
0234 return fc_frame_header_get(fp)->fh_r_ctl;
0235 }
0236
0237 static inline bool fc_frame_is_cmd(const struct fc_frame *fp)
0238 {
0239 return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD;
0240 }
0241
0242
0243
0244
0245
0246
0247 void fc_frame_leak_check(void);
0248
0249 static inline void __fc_fill_fc_hdr(struct fc_frame_header *fh,
0250 enum fc_rctl r_ctl,
0251 u32 did, u32 sid, enum fc_fh_type type,
0252 u32 f_ctl, u32 parm_offset)
0253 {
0254 WARN_ON(r_ctl == 0);
0255 fh->fh_r_ctl = r_ctl;
0256 hton24(fh->fh_d_id, did);
0257 hton24(fh->fh_s_id, sid);
0258 fh->fh_type = type;
0259 hton24(fh->fh_f_ctl, f_ctl);
0260 fh->fh_cs_ctl = 0;
0261 fh->fh_df_ctl = 0;
0262 fh->fh_parm_offset = htonl(parm_offset);
0263 }
0264
0265
0266
0267
0268 static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
0269 u32 did, u32 sid, enum fc_fh_type type,
0270 u32 f_ctl, u32 parm_offset)
0271 {
0272 struct fc_frame_header *fh;
0273
0274 fh = fc_frame_header_get(fp);
0275 __fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset);
0276 }
0277
0278
0279 #endif