1 /*- 2 * Copyright (c) 2007-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include "efsys.h" 35 #include "efx.h" 36 #include "efx_types.h" 37 #include "efx_regs.h" 38 #include "efx_impl.h" 39 40 41 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA 42 43 static __checkReturn efx_rc_t 44 falconsiena_intr_init( 45 __in efx_nic_t *enp, 46 __in efx_intr_type_t type, 47 __in efsys_mem_t *esmp); 48 49 static void 50 falconsiena_intr_enable( 51 __in efx_nic_t *enp); 52 53 static void 54 falconsiena_intr_disable( 55 __in efx_nic_t *enp); 56 57 static void 58 falconsiena_intr_disable_unlocked( 59 __in efx_nic_t *enp); 60 61 static __checkReturn efx_rc_t 62 falconsiena_intr_trigger( 63 __in efx_nic_t *enp, 64 __in unsigned int level); 65 66 static void 67 falconsiena_intr_fini( 68 __in efx_nic_t *enp); 69 70 71 static __checkReturn boolean_t 72 falconsiena_intr_check_fatal( 73 __in efx_nic_t *enp); 74 75 static void 76 falconsiena_intr_fatal( 77 __in efx_nic_t *enp); 78 79 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */ 80 81 82 #if EFSYS_OPT_FALCON 83 static efx_intr_ops_t __efx_intr_falcon_ops = { 84 falconsiena_intr_init, /* eio_init */ 85 falconsiena_intr_enable, /* eio_enable */ 86 falconsiena_intr_disable, /* eio_disable */ 87 falconsiena_intr_disable_unlocked, /* eio_disable_unlocked */ 88 falconsiena_intr_trigger, /* eio_trigger */ 89 falconsiena_intr_fini, /* eio_fini */ 90 }; 91 #endif /* EFSYS_OPT_FALCON */ 92 93 #if EFSYS_OPT_SIENA 94 static efx_intr_ops_t __efx_intr_siena_ops = { 95 falconsiena_intr_init, /* eio_init */ 96 falconsiena_intr_enable, /* eio_enable */ 97 falconsiena_intr_disable, /* eio_disable */ 98 falconsiena_intr_disable_unlocked, /* eio_disable_unlocked */ 99 falconsiena_intr_trigger, /* eio_trigger */ 100 falconsiena_intr_fini, /* eio_fini */ 101 }; 102 #endif /* EFSYS_OPT_SIENA */ 103 104 #if EFSYS_OPT_HUNTINGTON 105 static efx_intr_ops_t __efx_intr_hunt_ops = { 106 hunt_intr_init, /* eio_init */ 107 hunt_intr_enable, /* eio_enable */ 108 hunt_intr_disable, /* eio_disable */ 109 hunt_intr_disable_unlocked, /* eio_disable_unlocked */ 110 hunt_intr_trigger, /* eio_trigger */ 111 hunt_intr_fini, /* eio_fini */ 112 }; 113 #endif /* EFSYS_OPT_HUNTINGTON */ 114 115 116 __checkReturn efx_rc_t 117 efx_intr_init( 118 __in efx_nic_t *enp, 119 __in efx_intr_type_t type, 120 __in efsys_mem_t *esmp) 121 { 122 efx_intr_t *eip = &(enp->en_intr); 123 efx_intr_ops_t *eiop; 124 efx_rc_t rc; 125 126 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 127 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 128 129 if (enp->en_mod_flags & EFX_MOD_INTR) { 130 rc = EINVAL; 131 goto fail1; 132 } 133 134 eip->ei_esmp = esmp; 135 eip->ei_type = type; 136 eip->ei_level = 0; 137 138 enp->en_mod_flags |= EFX_MOD_INTR; 139 140 switch (enp->en_family) { 141 #if EFSYS_OPT_FALCON 142 case EFX_FAMILY_FALCON: 143 eiop = (efx_intr_ops_t *)&__efx_intr_falcon_ops; 144 break; 145 #endif /* EFSYS_OPT_FALCON */ 146 147 #if EFSYS_OPT_SIENA 148 case EFX_FAMILY_SIENA: 149 eiop = (efx_intr_ops_t *)&__efx_intr_siena_ops; 150 break; 151 #endif /* EFSYS_OPT_SIENA */ 152 153 #if EFSYS_OPT_HUNTINGTON 154 case EFX_FAMILY_HUNTINGTON: 155 eiop = (efx_intr_ops_t *)&__efx_intr_hunt_ops; 156 break; 157 #endif /* EFSYS_OPT_HUNTINGTON */ 158 159 default: 160 EFSYS_ASSERT(B_FALSE); 161 rc = ENOTSUP; 162 goto fail2; 163 } 164 165 if ((rc = eiop->eio_init(enp, type, esmp)) != 0) 166 goto fail3; 167 168 eip->ei_eiop = eiop; 169 170 return (0); 171 172 fail3: 173 EFSYS_PROBE(fail3); 174 fail2: 175 EFSYS_PROBE(fail2); 176 fail1: 177 EFSYS_PROBE1(fail1, efx_rc_t, rc); 178 179 return (rc); 180 } 181 182 void 183 efx_intr_fini( 184 __in efx_nic_t *enp) 185 { 186 efx_intr_t *eip = &(enp->en_intr); 187 efx_intr_ops_t *eiop = eip->ei_eiop; 188 189 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 190 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 191 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 192 193 eiop->eio_fini(enp); 194 195 enp->en_mod_flags &= ~EFX_MOD_INTR; 196 } 197 198 void 199 efx_intr_enable( 200 __in efx_nic_t *enp) 201 { 202 efx_intr_t *eip = &(enp->en_intr); 203 efx_intr_ops_t *eiop = eip->ei_eiop; 204 205 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 206 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 207 208 eiop->eio_enable(enp); 209 } 210 211 void 212 efx_intr_disable( 213 __in efx_nic_t *enp) 214 { 215 efx_intr_t *eip = &(enp->en_intr); 216 efx_intr_ops_t *eiop = eip->ei_eiop; 217 218 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 219 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 220 221 eiop->eio_disable(enp); 222 } 223 224 void 225 efx_intr_disable_unlocked( 226 __in efx_nic_t *enp) 227 { 228 efx_intr_t *eip = &(enp->en_intr); 229 efx_intr_ops_t *eiop = eip->ei_eiop; 230 231 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 232 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 233 234 eiop->eio_disable_unlocked(enp); 235 } 236 237 238 __checkReturn efx_rc_t 239 efx_intr_trigger( 240 __in efx_nic_t *enp, 241 __in unsigned int level) 242 { 243 efx_intr_t *eip = &(enp->en_intr); 244 efx_intr_ops_t *eiop = eip->ei_eiop; 245 246 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 247 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 248 249 return (eiop->eio_trigger(enp, level)); 250 } 251 252 void 253 efx_intr_status_line( 254 __in efx_nic_t *enp, 255 __out boolean_t *fatalp, 256 __out uint32_t *qmaskp) 257 { 258 efx_intr_t *eip = &(enp->en_intr); 259 efx_dword_t dword; 260 261 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 262 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 263 264 /* Ensure Huntington and Falcon/Siena ISR at same location */ 265 EFX_STATIC_ASSERT(FR_BZ_INT_ISR0_REG_OFST == 266 ER_DZ_BIU_INT_ISR_REG_OFST); 267 268 /* 269 * Read the queue mask and implicitly acknowledge the 270 * interrupt. 271 */ 272 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE); 273 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 274 275 EFSYS_PROBE1(qmask, uint32_t, *qmaskp); 276 277 #if EFSYS_OPT_HUNTINGTON 278 if (enp->en_family == EFX_FAMILY_HUNTINGTON) { 279 /* Huntington reports fatal errors via events */ 280 *fatalp = B_FALSE; 281 return; 282 } 283 #endif 284 if (*qmaskp & (1U << eip->ei_level)) 285 *fatalp = falconsiena_intr_check_fatal(enp); 286 else 287 *fatalp = B_FALSE; 288 } 289 290 void 291 efx_intr_status_message( 292 __in efx_nic_t *enp, 293 __in unsigned int message, 294 __out boolean_t *fatalp) 295 { 296 efx_intr_t *eip = &(enp->en_intr); 297 298 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 299 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 300 301 #if EFSYS_OPT_HUNTINGTON 302 if (enp->en_family == EFX_FAMILY_HUNTINGTON) { 303 /* Huntington reports fatal errors via events */ 304 *fatalp = B_FALSE; 305 return; 306 } 307 #endif 308 if (message == eip->ei_level) 309 *fatalp = falconsiena_intr_check_fatal(enp); 310 else 311 *fatalp = B_FALSE; 312 } 313 314 void 315 efx_intr_fatal( 316 __in efx_nic_t *enp) 317 { 318 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 319 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 320 321 #if EFSYS_OPT_HUNTINGTON 322 if (enp->en_family == EFX_FAMILY_HUNTINGTON) { 323 /* Huntington reports fatal errors via events */ 324 return; 325 } 326 #endif 327 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA 328 falconsiena_intr_fatal(enp); 329 #endif 330 } 331 332 333 /* ************************************************************************* */ 334 /* ************************************************************************* */ 335 /* ************************************************************************* */ 336 337 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA 338 339 static __checkReturn efx_rc_t 340 falconsiena_intr_init( 341 __in efx_nic_t *enp, 342 __in efx_intr_type_t type, 343 __in efsys_mem_t *esmp) 344 { 345 efx_intr_t *eip = &(enp->en_intr); 346 efx_oword_t oword; 347 348 /* 349 * bug17213 workaround. 350 * 351 * Under legacy interrupts, don't share a level between fatal 352 * interrupts and event queue interrupts. Under MSI-X, they 353 * must share, or we won't get an interrupt. 354 */ 355 if (enp->en_family == EFX_FAMILY_SIENA && 356 eip->ei_type == EFX_INTR_LINE) 357 eip->ei_level = 0x1f; 358 else 359 eip->ei_level = 0; 360 361 /* Enable all the genuinely fatal interrupts */ 362 EFX_SET_OWORD(oword); 363 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0); 364 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0); 365 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0); 366 if (enp->en_family >= EFX_FAMILY_SIENA) 367 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0); 368 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword); 369 370 /* Set up the interrupt address register */ 371 EFX_POPULATE_OWORD_3(oword, 372 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0, 373 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff, 374 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32); 375 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 376 377 return (0); 378 } 379 380 static void 381 falconsiena_intr_enable( 382 __in efx_nic_t *enp) 383 { 384 efx_intr_t *eip = &(enp->en_intr); 385 efx_oword_t oword; 386 387 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 388 389 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 390 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1); 391 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 392 } 393 394 static void 395 falconsiena_intr_disable( 396 __in efx_nic_t *enp) 397 { 398 efx_oword_t oword; 399 400 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 401 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 402 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 403 404 EFSYS_SPIN(10); 405 } 406 407 static void 408 falconsiena_intr_disable_unlocked( 409 __in efx_nic_t *enp) 410 { 411 efx_oword_t oword; 412 413 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 414 &oword, B_FALSE); 415 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 416 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 417 &oword, B_FALSE); 418 } 419 420 static __checkReturn efx_rc_t 421 falconsiena_intr_trigger( 422 __in efx_nic_t *enp, 423 __in unsigned int level) 424 { 425 efx_intr_t *eip = &(enp->en_intr); 426 efx_oword_t oword; 427 unsigned int count; 428 uint32_t sel; 429 efx_rc_t rc; 430 431 /* bug16757: No event queues can be initialized */ 432 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 433 434 switch (enp->en_family) { 435 case EFX_FAMILY_FALCON: 436 if (level >= EFX_NINTR_FALCON) { 437 rc = EINVAL; 438 goto fail1; 439 } 440 break; 441 442 case EFX_FAMILY_SIENA: 443 if (level >= EFX_NINTR_SIENA) { 444 rc = EINVAL; 445 goto fail1; 446 } 447 break; 448 449 default: 450 EFSYS_ASSERT(B_FALSE); 451 break; 452 } 453 454 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL)) 455 return (ENOTSUP); /* avoid EFSYS_PROBE() */ 456 457 sel = level; 458 459 /* Trigger a test interrupt */ 460 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 461 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel); 462 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1); 463 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 464 465 /* 466 * Wait up to 100ms for the interrupt to be raised before restoring 467 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will 468 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL 469 */ 470 count = 0; 471 do { 472 EFSYS_SPIN(100); /* 100us */ 473 474 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 475 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000); 476 477 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 478 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 479 480 return (0); 481 482 fail1: 483 EFSYS_PROBE1(fail1, efx_rc_t, rc); 484 485 return (rc); 486 } 487 488 static __checkReturn boolean_t 489 falconsiena_intr_check_fatal( 490 __in efx_nic_t *enp) 491 { 492 efx_intr_t *eip = &(enp->en_intr); 493 efsys_mem_t *esmp = eip->ei_esmp; 494 efx_oword_t oword; 495 496 /* Read the syndrome */ 497 EFSYS_MEM_READO(esmp, 0, &oword); 498 499 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) { 500 EFSYS_PROBE(fatal); 501 502 /* Clear the fatal interrupt condition */ 503 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0); 504 EFSYS_MEM_WRITEO(esmp, 0, &oword); 505 506 return (B_TRUE); 507 } 508 509 return (B_FALSE); 510 } 511 512 static void 513 falconsiena_intr_fatal( 514 __in efx_nic_t *enp) 515 { 516 #if EFSYS_OPT_DECODE_INTR_FATAL 517 efx_oword_t fatal; 518 efx_oword_t mem_per; 519 520 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal); 521 EFX_ZERO_OWORD(mem_per); 522 523 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 || 524 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 525 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per); 526 527 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0) 528 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0); 529 530 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0) 531 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0); 532 533 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 534 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR, 535 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 536 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 537 538 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0) 539 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0); 540 541 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0) 542 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0); 543 544 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0) 545 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0); 546 547 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0) 548 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0); 549 550 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0) 551 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0); 552 553 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0) 554 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0); 555 556 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0) 557 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0); 558 559 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0) 560 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR, 561 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 562 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 563 #else 564 EFSYS_ASSERT(0); 565 #endif 566 } 567 568 static void 569 falconsiena_intr_fini( 570 __in efx_nic_t *enp) 571 { 572 efx_oword_t oword; 573 574 /* Clear the interrupt address register */ 575 EFX_ZERO_OWORD(oword); 576 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 577 } 578 579 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */ 580