^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) #ifndef _FC_ENCAPS_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define _FC_ENCAPS_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Protocol definitions from RFC 3643 - Fibre Channel Frame Encapsulation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Note: The frame length field is the number of 32-bit words in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * the encapsulation including the fcip_encaps_header, CRC and EOF words.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * The minimum frame length value in bytes is (32 + 24 + 4 + 4) * 4 = 64.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * The maximum frame length value in bytes is (32 + 24 + 2112 + 4 + 4) = 2172.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define FC_ENCAPS_MIN_FRAME_LEN 64 /* min frame len (bytes) (see above) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define FC_ENCAPS_MAX_FRAME_LEN (FC_ENCAPS_MIN_FRAME_LEN + FC_MAX_PAYLOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define FC_ENCAPS_VER 1 /* current version number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct fc_encaps_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) __u8 fc_proto; /* protocol number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) __u8 fc_ver; /* version of encapsulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) __u8 fc_proto_n; /* ones complement of protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __u8 fc_ver_n; /* ones complement of version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned char fc_proto_data[8]; /* protocol specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) __be16 fc_len_flags; /* 10-bit length/4 w/ 6 flag bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) __be16 fc_len_flags_n; /* ones complement of length / flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * Offset 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) __be32 fc_time[2]; /* time stamp: seconds and fraction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) __be32 fc_crc; /* CRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) __be32 fc_sof; /* start of frame (see FC_SOF below) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* 0x20 - FC frame content followed by EOF word */
^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 FCIP_ENCAPS_HDR_LEN 0x20 /* expected length for asserts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Macro's for making redundant copies of EOF and SOF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define FC_XY(x, y) ((((x) & 0xff) << 8) | ((y) & 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define FC_XYXY(x, y) ((FCIP_XY(x, y) << 16) | FCIP_XY(x, y))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define FC_XYNN(x, y) (FCIP_XYXY(x, y) ^ 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define FC_SOF_ENCODE(n) FC_XYNN(n, n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define FC_EOF_ENCODE(n) FC_XYNN(n, n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * SOF / EOF bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) enum fc_sof {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) FC_SOF_F = 0x28, /* fabric */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) FC_SOF_I4 = 0x29, /* initiate class 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) FC_SOF_I2 = 0x2d, /* initiate class 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) FC_SOF_I3 = 0x2e, /* initiate class 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) FC_SOF_N4 = 0x31, /* normal class 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) FC_SOF_N2 = 0x35, /* normal class 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) FC_SOF_N3 = 0x36, /* normal class 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) FC_SOF_C4 = 0x39, /* activate class 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) enum fc_eof {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) FC_EOF_N = 0x41, /* normal (not last frame of seq) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) FC_EOF_T = 0x42, /* terminate (last frame of sequence) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) FC_EOF_RT = 0x44,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) FC_EOF_DT = 0x46, /* disconnect-terminate class-1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) FC_EOF_NI = 0x49, /* normal-invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) FC_EOF_DTI = 0x4e, /* disconnect-terminate-invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) FC_EOF_RTI = 0x4f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) FC_EOF_A = 0x50, /* abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define FC_SOF_CLASS_MASK 0x06 /* mask for class of service in SOF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Define classes in terms of the SOF code (initial).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) enum fc_class {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) FC_CLASS_NONE = 0, /* software value indicating no class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) FC_CLASS_2 = FC_SOF_I2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) FC_CLASS_3 = FC_SOF_I3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) FC_CLASS_4 = FC_SOF_I4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) FC_CLASS_F = FC_SOF_F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Determine whether SOF code indicates the need for a BLS ACK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static inline int fc_sof_needs_ack(enum fc_sof sof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return (~sof) & 0x02; /* true for class 1, 2, 4, 6, or F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Given an fc_class, return the normal (non-initial) SOF value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static inline enum fc_sof fc_sof_normal(enum fc_class class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return class + FC_SOF_N3 - FC_SOF_I3; /* diff is always 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Compute class from SOF value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static inline enum fc_class fc_sof_class(enum fc_sof sof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return (sof & 0x7) | FC_SOF_F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Determine whether SOF is for the initial frame of a sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline int fc_sof_is_init(enum fc_sof sof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return sof < 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #endif /* _FC_ENCAPS_H_ */