aboutsummaryrefslogtreecommitdiff
path: root/include/scsi/fc_frame.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/scsi/fc_frame.h')
-rw-r--r--include/scsi/fc_frame.h80
1 files changed, 57 insertions, 23 deletions
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index 59511057cee..8225d8063ec 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -28,6 +28,25 @@
#include <scsi/fc/fc_fcp.h>
#include <scsi/fc/fc_encaps.h>
+#include <linux/if_ether.h>
+
+/* some helpful macros */
+
+#define ntohll(x) be64_to_cpu(x)
+#define htonll(x) cpu_to_be64(x)
+
+static inline u32 ntoh24(const u8 *p)
+{
+ return (p[0] << 16) | (p[1] << 8) | p[2];
+}
+
+static inline void hton24(u8 *p, u32 v)
+{
+ p[0] = (v >> 16) & 0xff;
+ p[1] = (v >> 8) & 0xff;
+ p[2] = v & 0xff;
+}
+
/*
* The fc_frame interface is used to pass frame data between functions.
* The frame includes the data buffer, length, and SOF / EOF delimiter types.
@@ -37,12 +56,8 @@
#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */
#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */
-/*
- * Information about an individual fibre channel frame received or to be sent.
- * The buffer may be in up to 4 additional non-contiguous sections,
- * but the linear section must hold the frame header.
- */
-#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */
+/* Max number of skb frags allowed, reserving one for fcoe_crc_eof page */
+#define FC_FRAME_SG_LEN (MAX_SKB_FRAGS - 1)
#define fp_skb(fp) (&((fp)->skb))
#define fr_hdr(fp) ((fp)->skb.data)
@@ -53,6 +68,7 @@
#define fr_sof(fp) (fr_cb(fp)->fr_sof)
#define fr_eof(fp) (fr_cb(fp)->fr_eof)
#define fr_flags(fp) (fr_cb(fp)->fr_flags)
+#define fr_encaps(fp) (fr_cb(fp)->fr_encaps)
#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload)
#define fr_fsp(fp) (fr_cb(fp)->fr_fsp)
#define fr_crc(fp) (fr_cb(fp)->fr_crc)
@@ -62,15 +78,16 @@ struct fc_frame {
};
struct fcoe_rcv_info {
- struct packet_type *ptype;
struct fc_lport *fr_dev; /* transport layer private pointer */
struct fc_seq *fr_seq; /* for use with exchange manager */
struct fc_fcp_pkt *fr_fsp; /* for the corresponding fcp I/O */
u32 fr_crc;
u16 fr_max_payload; /* max FC payload */
- enum fc_sof fr_sof; /* start of frame delimiter */
- enum fc_eof fr_eof; /* end of frame delimiter */
+ u8 fr_sof; /* start of frame delimiter */
+ u8 fr_eof; /* end of frame delimiter */
u8 fr_flags; /* flags - see below */
+ u8 fr_encaps; /* LLD encapsulation info (e.g. FIP) */
+ u8 granted_mac[ETH_ALEN]; /* FCoE MAC address */
};
@@ -98,20 +115,11 @@ static inline void fc_frame_init(struct fc_frame *fp)
fr_dev(fp) = NULL;
fr_seq(fp) = NULL;
fr_flags(fp) = 0;
+ fr_encaps(fp) = 0;
}
struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
-
-struct fc_frame *__fc_frame_alloc(size_t payload_len);
-
-/*
- * Get frame for sending via port.
- */
-static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev,
- size_t payload_len)
-{
- return __fc_frame_alloc(payload_len);
-}
+struct fc_frame *_fc_frame_alloc(size_t payload_len);
/*
* Allocate fc_frame structure and buffer. Set the initial length to
@@ -125,10 +133,10 @@ static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len)
* Note: Since len will often be a constant multiple of 4,
* this check will usually be evaluated and eliminated at compile time.
*/
- if ((len % 4) != 0)
+ if (len && len % 4)
fp = fc_frame_alloc_fill(dev, len);
else
- fp = _fc_frame_alloc(dev, len);
+ fp = _fc_frame_alloc(len);
return fp;
}
@@ -147,13 +155,39 @@ static inline int fc_frame_is_linear(struct fc_frame *fp)
/*
* Get frame header from message in fc_frame structure.
+ * This version doesn't do a length check.
+ */
+static inline
+struct fc_frame_header *__fc_frame_header_get(const struct fc_frame *fp)
+{
+ return (struct fc_frame_header *)fr_hdr(fp);
+}
+
+/*
+ * Get frame header from message in fc_frame structure.
* This hides a cast and provides a place to add some checking.
*/
static inline
struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp)
{
WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header));
- return (struct fc_frame_header *) fr_hdr(fp);
+ return __fc_frame_header_get(fp);
+}
+
+/*
+ * Get source FC_ID (S_ID) from frame header in message.
+ */
+static inline u32 fc_frame_sid(const struct fc_frame *fp)
+{
+ return ntoh24(__fc_frame_header_get(fp)->fh_s_id);
+}
+
+/*
+ * Get destination FC_ID (D_ID) from frame header in message.
+ */
+static inline u32 fc_frame_did(const struct fc_frame *fp)
+{
+ return ntoh24(__fc_frame_header_get(fp)->fh_d_id);
}
/*