1 #ifndef _IPXE_FIP_H
2 #define _IPXE_FIP_H
3 
4 /*
5  * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  */
22 
23 #include <stdint.h>
24 #include <ipxe/fc.h>
25 #include <ipxe/fcels.h>
26 #include <ipxe/fcoe.h>
27 
28 /** A FIP frame header */
29 struct fip_header {
30 	/** Frame version */
31 	uint8_t version;
32 	/** Reserved */
33 	uint8_t reserved_a;
34 	/** Protocol code */
35 	uint16_t code;
36 	/** Reserved */
37 	uint8_t reserved_b;
38 	/** Subcode */
39 	uint8_t subcode;
40 	/** Descriptor list length in 32-bit words */
41 	uint16_t len;
42 	/** Flags */
43 	uint16_t flags;
44 } __attribute__ (( packed ));
45 
46 /** FIP frame version */
47 #define FIP_VERSION 0x10
48 
49 /** FIP protocol code */
50 enum fip_code {
51 	FIP_CODE_DISCOVERY = 0x0001,	/**< Discovery */
52 	FIP_CODE_ELS = 0x0002,		/**< Extended link services */
53 	FIP_CODE_MAINTAIN = 0x0003,	/**< Maintain virtual links */
54 	FIP_CODE_VLAN = 0x0004,		/**< VLAN */
55 };
56 
57 /** FIP protocol subcode for discovery */
58 enum fip_discovery_subcode {
59 	FIP_DISCOVERY_SOLICIT = 0x01,	/**< Discovery solicitation */
60 	FIP_DISCOVERY_ADVERTISE = 0x02,	/**< Discovery advertisement */
61 };
62 
63 /** FIP protocol subcode for extended link services */
64 enum fip_els_subcode {
65 	FIP_ELS_REQUEST = 0x01,		/**< ELS request */
66 	FIP_ELS_RESPONSE = 0x02,	/**< ELS response */
67 };
68 
69 /** FIP protocol subcode for keep alive / clear links */
70 enum fip_vitality_subcode {
71 	FIP_MAINTAIN_KEEP_ALIVE = 0x01,	/**< Keep alive */
72 	FIP_MAINTAIN_CLEAR_LINKS = 0x02,/**< Clear virtual links */
73 };
74 
75 /** FIP protocol subcode for VLAN */
76 enum fip_vlan_subcode {
77 	FIP_VLAN_REQUEST = 0x01,	/**< VLAN request */
78 	FIP_VLAN_NOTIFY = 0x02,		/**< VLAN notification */
79 };
80 
81 /** FIP flags */
82 enum fip_flags {
83 	FIP_FP	= 0x8000,		/**< Fabric-provided MAC address */
84 	FIP_SP	= 0x4000,		/**< Server-provided MAC address */
85 	FIP_A	= 0x0004,		/**< Available for login */
86 	FIP_S	= 0x0002,		/**< Solicited */
87 	FIP_F	= 0x0001,		/**< Forwarder */
88 };
89 
90 /** FIP descriptor common fields */
91 struct fip_common {
92 	/** Type */
93 	uint8_t type;
94 	/** Length in 32-bit words */
95 	uint8_t len;
96 	/** Reserved */
97 	uint8_t reserved[2];
98 } __attribute__ (( packed ));
99 
100 /** FIP descriptor types */
101 enum fip_type {
102 	FIP_RESERVED = 0x00,		/**< Reserved */
103 	FIP_PRIORITY = 0x01,		/**< Priority */
104 	FIP_MAC_ADDRESS = 0x02,		/**< MAC address */
105 	FIP_FC_MAP = 0x03,		/**< FC-MAP */
106 	FIP_NAME_ID = 0x04,		/**< Name identifier */
107 	FIP_FABRIC = 0x05,		/**< Fabric */
108 	FIP_MAX_FCOE_SIZE = 0x06,	/**< Max FCoE size */
109 	FIP_FLOGI = 0x07,		/**< FLOGI */
110 	FIP_NPIV_FDISC = 0x08,		/**< NPIV FDISC */
111 	FIP_LOGO = 0x09,		/**< LOGO */
112 	FIP_ELP = 0x0a,			/**< ELP */
113 	FIP_VX_PORT_ID = 0x0b,		/**< Vx port identification */
114 	FIP_FKA_ADV_P = 0x0c,		/**< FKA ADV period */
115 	FIP_VENDOR_ID = 0x0d,		/**< Vendor ID */
116 	FIP_VLAN = 0x0e,		/**< VLAN */
117 	FIP_NUM_DESCRIPTOR_TYPES
118 };
119 
120 /** FIP descriptor type is critical */
121 #define FIP_IS_CRITICAL( type ) ( (type) <= 0x7f )
122 
123 /** A FIP priority descriptor */
124 struct fip_priority {
125 	/** Type */
126 	uint8_t type;
127 	/** Length in 32-bit words */
128 	uint8_t len;
129 	/** Reserved */
130 	uint8_t reserved;
131 	/** Priority
132 	 *
133 	 * A higher value indicates a lower priority.
134 	 */
135 	uint8_t priority;
136 } __attribute__ (( packed ));
137 
138 /** Default FIP priority */
139 #define FIP_DEFAULT_PRIORITY 128
140 
141 /** Lowest FIP priority */
142 #define FIP_LOWEST_PRIORITY 255
143 
144 /** A FIP MAC address descriptor */
145 struct fip_mac_address {
146 	/** Type */
147 	uint8_t type;
148 	/** Length in 32-bit words */
149 	uint8_t len;
150 	/** MAC address */
151 	uint8_t mac[ETH_ALEN];
152 } __attribute__ (( packed ));
153 
154 /** A FIP FC-MAP descriptor */
155 struct fip_fc_map {
156 	/** Type */
157 	uint8_t type;
158 	/** Length in 32-bit words */
159 	uint8_t len;
160 	/** Reserved */
161 	uint8_t reserved[3];
162 	/** FC-MAP */
163 	struct fcoe_map map;
164 } __attribute__ (( packed ));
165 
166 /** A FIP name identifier descriptor */
167 struct fip_name_id {
168 	/** Type */
169 	uint8_t type;
170 	/** Length in 32-bit words */
171 	uint8_t len;
172 	/** Reserved */
173 	uint8_t reserved[2];
174 	/** Name identifier */
175 	struct fc_name name;
176 } __attribute__ (( packed ));
177 
178 /** A FIP fabric descriptor */
179 struct fip_fabric {
180 	/** Type */
181 	uint8_t type;
182 	/** Length in 32-bit words */
183 	uint8_t len;
184 	/** Virtual Fabric ID, if any */
185 	uint16_t vf_id;
186 	/** Reserved */
187 	uint8_t reserved;
188 	/** FC-MAP */
189 	struct fcoe_map map;
190 	/** Fabric name */
191 	struct fc_name name;
192 } __attribute__ (( packed ));
193 
194 /** A FIP max FCoE size descriptor */
195 struct fip_max_fcoe_size {
196 	/** Type */
197 	uint8_t type;
198 	/** Length in 32-bit words */
199 	uint8_t len;
200 	/** Maximum FCoE size */
201 	uint16_t mtu;
202 } __attribute__ (( packed ));
203 
204 /** A FIP descriptor containing an encapsulated ELS frame */
205 struct fip_els {
206 	/** Type */
207 	uint8_t type;
208 	/** Length in 32-bit words */
209 	uint8_t len;
210 	/** Reserved */
211 	uint8_t reserved[2];
212 	/** Fibre Channel frame header */
213 	struct fc_frame_header fc;
214 	/** ELS frame */
215 	struct fc_els_frame_common els;
216 } __attribute__ (( packed ));
217 
218 /** A FIP descriptor containing an encapsulated login frame */
219 struct fip_login {
220 	/** Type */
221 	uint8_t type;
222 	/** Length in 32-bit words */
223 	uint8_t len;
224 	/** Reserved */
225 	uint8_t reserved[2];
226 	/** Fibre Channel frame header */
227 	struct fc_frame_header fc;
228 	/** ELS frame */
229 	struct fc_login_frame els;
230 } __attribute__ (( packed ));
231 
232 /** A FIP descriptor containing an encapsulated LOGO request frame */
233 struct fip_logo_request {
234 	/** Type */
235 	uint8_t type;
236 	/** Length in 32-bit words */
237 	uint8_t len;
238 	/** Reserved */
239 	uint8_t reserved[2];
240 	/** Fibre Channel frame header */
241 	struct fc_frame_header fc;
242 	/** ELS frame */
243 	struct fc_logout_request_frame els;
244 } __attribute__ (( packed ));
245 
246 /** A FIP descriptor containing an encapsulated LOGO response frame */
247 struct fip_logo_response {
248 	/** Type */
249 	uint8_t type;
250 	/** Length in 32-bit words */
251 	uint8_t len;
252 	/** Reserved */
253 	uint8_t reserved[2];
254 	/** Fibre Channel frame header */
255 	struct fc_frame_header fc;
256 	/** ELS frame */
257 	struct fc_logout_response_frame els;
258 } __attribute__ (( packed ));
259 
260 /** A FIP descriptor containing an encapsulated ELP frame */
261 struct fip_elp {
262 	/** Type */
263 	uint8_t type;
264 	/** Length in 32-bit words */
265 	uint8_t len;
266 	/** Reserved */
267 	uint8_t reserved[2];
268 	/** Fibre Channel frame header */
269 	struct fc_frame_header fc;
270 	/** ELS frame */
271 	struct fc_els_frame_common els;
272 	/** Uninteresting content */
273 	uint32_t dull[25];
274 } __attribute__ (( packed ));
275 
276 /** A FIP descriptor containing an encapsulated LS_RJT frame */
277 struct fip_ls_rjt {
278 	/** Type */
279 	uint8_t type;
280 	/** Length in 32-bit words */
281 	uint8_t len;
282 	/** Reserved */
283 	uint8_t reserved[2];
284 	/** Fibre Channel frame header */
285 	struct fc_frame_header fc;
286 	/** ELS frame */
287 	struct fc_ls_rjt_frame els;
288 } __attribute__ (( packed ));
289 
290 /** A FIP Vx port identification descriptor */
291 struct fip_vx_port_id {
292 	/** Type */
293 	uint8_t type;
294 	/** Length in 32-bit words */
295 	uint8_t len;
296 	/** MAC address */
297 	uint8_t mac[ETH_ALEN];
298 	/** Reserved */
299 	uint8_t reserved;
300 	/** Address identifier */
301 	struct fc_port_id id;
302 	/** Port name */
303 	struct fc_name name;
304 } __attribute__ (( packed ));
305 
306 /** A FIP FKA ADV period descriptor */
307 struct fip_fka_adv_p {
308 	/** Type */
309 	uint8_t type;
310 	/** Length in 32-bit words */
311 	uint8_t len;
312 	/** Reserved */
313 	uint8_t reserved;
314 	/** Flags */
315 	uint8_t flags;
316 	/** Keep alive advertisement period in milliseconds */
317 	uint32_t period;
318 } __attribute__ (( packed ));
319 
320 /** FIP FKA ADV period flags */
321 enum fip_fka_adv_p_flags {
322 	FIP_NO_KEEPALIVE = 0x01,	/**< Do not send keepalives */
323 };
324 
325 /** A FIP vendor ID descriptor */
326 struct fip_vendor_id {
327 	/** Type */
328 	uint8_t type;
329 	/** Length in 32-bit words */
330 	uint8_t len;
331 	/** Reserved */
332 	uint8_t reserved[2];
333 	/** Vendor ID */
334 	uint8_t vendor[8];
335 } __attribute__ (( packed ));
336 
337 /** A FIP VLAN descriptor */
338 struct fip_vlan {
339 	/** Type */
340 	uint8_t type;
341 	/** Length in 32-bit words */
342 	uint8_t len;
343 	/** VLAN ID */
344 	uint16_t vlan;
345 } __attribute__ (( packed ));
346 
347 /** A FIP descriptor */
348 union fip_descriptor {
349 	/** Common fields */
350 	struct fip_common common;
351 	/** Priority descriptor */
352 	struct fip_priority priority;
353 	/** MAC address descriptor */
354 	struct fip_mac_address mac_address;
355 	/** FC-MAP descriptor */
356 	struct fip_fc_map fc_map;
357 	/** Name identifier descriptor */
358 	struct fip_name_id name_id;
359 	/** Fabric descriptor */
360 	struct fip_fabric fabric;
361 	/** Max FCoE size descriptor */
362 	struct fip_max_fcoe_size max_fcoe_size;
363 	/** FLOGI descriptor */
364 	struct fip_els flogi;
365 	/** FLOGI request descriptor */
366 	struct fip_login flogi_request;
367 	/** FLOGI LS_ACC descriptor */
368 	struct fip_login flogi_ls_acc;
369 	/** FLOGI LS_RJT descriptor */
370 	struct fip_ls_rjt flogi_ls_rjt;
371 	/** NPIV FDISC descriptor */
372 	struct fip_els npiv_fdisc;
373 	/** NPIV FDISC request descriptor */
374 	struct fip_login npiv_fdisc_request;
375 	/** NPIV FDISC LS_ACC descriptor */
376 	struct fip_login npiv_fdisc_ls_acc;
377 	/** NPIV FDISC LS_RJT descriptor */
378 	struct fip_ls_rjt npiv_fdisc_ls_rjt;
379 	/** LOGO descriptor */
380 	struct fip_els logo;
381 	/** LOGO request descriptor */
382 	struct fip_logo_request logo_request;
383 	/** LOGO LS_ACC descriptor */
384 	struct fip_logo_response logo_ls_acc;
385 	/** LOGO LS_RJT descriptor */
386 	struct fip_ls_rjt logo_ls_rjt;
387 	/** ELS descriptor */
388 	struct fip_els elp;
389 	/** ELP request descriptor */
390 	struct fip_elp elp_request;
391 	/** ELP LS_ACC descriptor */
392 	struct fip_elp elp_ls_acc;
393 	/** ELP LS_RJT descriptor */
394 	struct fip_ls_rjt elp_ls_rjt;
395 	/** Vx port identification descriptor */
396 	struct fip_vx_port_id vx_port_id;
397 	/** FKA ADV period descriptor */
398 	struct fip_fka_adv_p fka_adv_p;
399 	/** Vendor ID descriptor */
400 	struct fip_vendor_id vendor_id;
401 	/** VLAN descriptor */
402 	struct fip_vlan vlan;
403 } __attribute__ (( packed ));
404 
405 /** A FIP descriptor set */
406 struct fip_descriptors {
407 	/** Descriptors, indexed by type */
408 	union fip_descriptor *desc[FIP_NUM_DESCRIPTOR_TYPES];
409 };
410 
411 /**
412  * Define a function to extract a specific FIP descriptor type from a list
413  *
414  * @v type		Descriptor type
415  * @v name		Descriptor name
416  * @v finder		Descriptor finder
417  */
418 #define FIP_DESCRIPTOR( type, name )					\
419 	static inline __attribute__ (( always_inline ))			\
420 	typeof ( ( ( union fip_descriptor * ) NULL )->name ) *		\
421 	fip_ ## name ( struct fip_descriptors *descs ) {		\
422 		return &(descs->desc[type]->name);			\
423 	}
424 FIP_DESCRIPTOR ( FIP_PRIORITY, priority );
425 FIP_DESCRIPTOR ( FIP_MAC_ADDRESS, mac_address );
426 FIP_DESCRIPTOR ( FIP_FC_MAP, fc_map );
427 FIP_DESCRIPTOR ( FIP_NAME_ID, name_id );
428 FIP_DESCRIPTOR ( FIP_FABRIC, fabric );
429 FIP_DESCRIPTOR ( FIP_MAX_FCOE_SIZE, max_fcoe_size );
430 FIP_DESCRIPTOR ( FIP_FLOGI, flogi );
431 FIP_DESCRIPTOR ( FIP_FLOGI, flogi_request );
432 FIP_DESCRIPTOR ( FIP_FLOGI, flogi_ls_acc );
433 FIP_DESCRIPTOR ( FIP_FLOGI, flogi_ls_rjt );
434 FIP_DESCRIPTOR ( FIP_NPIV_FDISC, npiv_fdisc );
435 FIP_DESCRIPTOR ( FIP_NPIV_FDISC, npiv_fdisc_request );
436 FIP_DESCRIPTOR ( FIP_NPIV_FDISC, npiv_fdisc_ls_acc );
437 FIP_DESCRIPTOR ( FIP_NPIV_FDISC, npiv_fdisc_ls_rjt );
438 FIP_DESCRIPTOR ( FIP_LOGO, logo );
439 FIP_DESCRIPTOR ( FIP_LOGO, logo_request );
440 FIP_DESCRIPTOR ( FIP_LOGO, logo_ls_acc );
441 FIP_DESCRIPTOR ( FIP_LOGO, logo_ls_rjt );
442 FIP_DESCRIPTOR ( FIP_ELP, elp );
443 FIP_DESCRIPTOR ( FIP_ELP, elp_request );
444 FIP_DESCRIPTOR ( FIP_ELP, elp_ls_acc );
445 FIP_DESCRIPTOR ( FIP_ELP, elp_ls_rjt );
446 FIP_DESCRIPTOR ( FIP_VX_PORT_ID, vx_port_id );
447 FIP_DESCRIPTOR ( FIP_FKA_ADV_P, fka_adv_p );
448 FIP_DESCRIPTOR ( FIP_VENDOR_ID, vendor_id );
449 FIP_DESCRIPTOR ( FIP_VLAN, vlan );
450 
451 #endif /* _IPXE_FIP_H */
452