root/include/scsi/fc_frame.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ntoh24
  2. hton24
  3. fcoe_dev_from_skb
  4. fc_frame_init
  5. fc_frame_alloc
  6. fc_frame_free
  7. fc_frame_is_linear
  8. __fc_frame_header_get
  9. fc_frame_header_get
  10. fc_frame_sid
  11. fc_frame_did
  12. fc_frame_payload_get
  13. fc_frame_payload_op
  14. fc_frame_class
  15. fc_frame_rctl
  16. fc_frame_is_cmd

   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 
  26 static inline u32 ntoh24(const u8 *p)
  27 {
  28         return (p[0] << 16) | (p[1] << 8) | p[2];
  29 }
  30 
  31 static 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 
  64 struct fc_frame {
  65         struct sk_buff skb;
  66 };
  67 
  68 struct 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  */
  85 static 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  */
 101 static 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 
 109 struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
 110 struct 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  */
 116 static 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  */
 134 static inline void fc_frame_free(struct fc_frame *fp)
 135 {
 136         kfree_skb(fp_skb(fp));
 137 }
 138 
 139 static 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  */
 148 static inline
 149 struct 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  */
 158 static inline
 159 struct 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  */
 168 static 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  */
 176 static 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  */
 191 static 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  */
 206 static 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  */
 220 static 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  */
 230 u32 fc_frame_crc_check(struct fc_frame *);
 231 
 232 static inline u8 fc_frame_rctl(const struct fc_frame *fp)
 233 {
 234         return fc_frame_header_get(fp)->fh_r_ctl;
 235 }
 236 
 237 static 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  */
 247 void fc_frame_leak_check(void);
 248 
 249 #endif /* _FC_FRAME_H_ */

/* [<][>][^][v][top][bottom][index][help] */