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