1 /*- 2 * Copyright (c) 2009-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_impl.h" 37 #include "mcdi_mon.h" 38 39 #if EFSYS_OPT_SIENA 40 41 static __checkReturn int 42 siena_nic_get_partn_mask( 43 __in efx_nic_t *enp, 44 __out unsigned int *maskp) 45 { 46 efx_mcdi_req_t req; 47 uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN, 48 MC_CMD_NVRAM_TYPES_OUT_LEN)]; 49 int rc; 50 51 (void) memset(payload, 0, sizeof (payload)); 52 req.emr_cmd = MC_CMD_NVRAM_TYPES; 53 req.emr_in_buf = payload; 54 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN; 55 req.emr_out_buf = payload; 56 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN; 57 58 efx_mcdi_execute(enp, &req); 59 60 if (req.emr_rc != 0) { 61 rc = req.emr_rc; 62 goto fail1; 63 } 64 65 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) { 66 rc = EMSGSIZE; 67 goto fail2; 68 } 69 70 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES); 71 72 return (0); 73 74 fail2: 75 EFSYS_PROBE(fail2); 76 fail1: 77 EFSYS_PROBE1(fail1, int, rc); 78 79 return (rc); 80 } 81 82 #if EFSYS_OPT_PCIE_TUNE 83 84 __checkReturn int 85 siena_nic_pcie_extended_sync( 86 __in efx_nic_t *enp) 87 { 88 int rc; 89 90 if ((rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG17230, 91 B_TRUE, NULL) != 0)) 92 goto fail1; 93 94 return (0); 95 96 fail1: 97 EFSYS_PROBE1(fail1, int, rc); 98 99 return (rc); 100 } 101 102 #endif /* EFSYS_OPT_PCIE_TUNE */ 103 104 static __checkReturn int 105 siena_board_cfg( 106 __in efx_nic_t *enp) 107 { 108 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 109 uint8_t mac_addr[6]; 110 efx_dword_t capabilities; 111 uint32_t board_type; 112 uint32_t nevq, nrxq, ntxq; 113 int rc; 114 115 /* External port identifier using one-based port numbering */ 116 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port; 117 118 /* Board configuration */ 119 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type, 120 &capabilities, mac_addr)) != 0) 121 goto fail1; 122 123 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 124 125 encp->enc_board_type = board_type; 126 127 /* Additional capabilities */ 128 encp->enc_clk_mult = 1; 129 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) { 130 enp->en_features |= EFX_FEATURE_TURBO; 131 132 if (EFX_DWORD_FIELD(capabilities, 133 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) { 134 encp->enc_clk_mult = 2; 135 } 136 } 137 138 encp->enc_evq_timer_quantum_ns = 139 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult; 140 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns << 141 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000; 142 143 /* When hash header insertion is enabled, Siena inserts 16 bytes */ 144 encp->enc_rx_prefix_size = 16; 145 146 /* Alignment for receive packet DMA buffers */ 147 encp->enc_rx_buf_align_start = 1; 148 encp->enc_rx_buf_align_end = 1; 149 150 /* Alignment for WPTR updates */ 151 encp->enc_rx_push_align = 1; 152 153 /* Resource limits */ 154 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq); 155 if (rc != 0) { 156 if (rc != ENOTSUP) 157 goto fail2; 158 159 nevq = 1024; 160 nrxq = EFX_RXQ_LIMIT_TARGET; 161 ntxq = EFX_TXQ_LIMIT_TARGET; 162 } 163 encp->enc_evq_limit = nevq; 164 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq); 165 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq); 166 167 encp->enc_buftbl_limit = SIENA_SRAM_ROWS - 168 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) - 169 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE)); 170 171 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 172 encp->enc_fw_assisted_tso_enabled = B_FALSE; 173 174 return (0); 175 176 fail2: 177 EFSYS_PROBE(fail2); 178 fail1: 179 EFSYS_PROBE1(fail1, int, rc); 180 181 return (rc); 182 } 183 184 static __checkReturn int 185 siena_phy_cfg( 186 __in efx_nic_t *enp) 187 { 188 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 189 int rc; 190 191 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 192 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 193 goto fail1; 194 195 #if EFSYS_OPT_PHY_STATS 196 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */ 197 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask, 198 NULL, &encp->enc_phy_stat_mask, NULL); 199 #endif /* EFSYS_OPT_PHY_STATS */ 200 201 return (0); 202 203 fail1: 204 EFSYS_PROBE1(fail1, int, rc); 205 206 return (rc); 207 } 208 209 __checkReturn int 210 siena_nic_probe( 211 __in efx_nic_t *enp) 212 { 213 efx_port_t *epp = &(enp->en_port); 214 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 215 siena_link_state_t sls; 216 unsigned int mask; 217 efx_oword_t oword; 218 int rc; 219 220 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 221 222 /* Test BIU */ 223 if ((rc = efx_nic_biu_test(enp)) != 0) 224 goto fail1; 225 226 /* Clear the region register */ 227 EFX_POPULATE_OWORD_4(oword, 228 FRF_AZ_ADR_REGION0, 0, 229 FRF_AZ_ADR_REGION1, (1 << 16), 230 FRF_AZ_ADR_REGION2, (2 << 16), 231 FRF_AZ_ADR_REGION3, (3 << 16)); 232 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword); 233 234 /* Read clear any assertion state */ 235 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 236 goto fail2; 237 238 /* Exit the assertion handler */ 239 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 240 goto fail3; 241 242 /* Wrestle control from the BMC */ 243 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 244 goto fail4; 245 246 if ((rc = siena_board_cfg(enp)) != 0) 247 goto fail5; 248 249 if ((rc = siena_phy_cfg(enp)) != 0) 250 goto fail6; 251 252 /* Obtain the default PHY advertised capabilities */ 253 if ((rc = siena_nic_reset(enp)) != 0) 254 goto fail7; 255 if ((rc = siena_phy_get_link(enp, &sls)) != 0) 256 goto fail8; 257 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask; 258 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; 259 260 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 261 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0) 262 goto fail9; 263 enp->en_u.siena.enu_partn_mask = mask; 264 #endif 265 266 #if EFSYS_OPT_MAC_STATS 267 /* Wipe the MAC statistics */ 268 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 269 goto fail10; 270 #endif 271 272 #if EFSYS_OPT_LOOPBACK 273 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 274 goto fail11; 275 #endif 276 277 #if EFSYS_OPT_MON_STATS 278 if ((rc = mcdi_mon_cfg_build(enp)) != 0) 279 goto fail12; 280 #endif 281 282 encp->enc_features = enp->en_features; 283 284 return (0); 285 286 #if EFSYS_OPT_MON_STATS 287 fail12: 288 EFSYS_PROBE(fail12); 289 #endif 290 #if EFSYS_OPT_LOOPBACK 291 fail11: 292 EFSYS_PROBE(fail11); 293 #endif 294 #if EFSYS_OPT_MAC_STATS 295 fail10: 296 EFSYS_PROBE(fail10); 297 #endif 298 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 299 fail9: 300 EFSYS_PROBE(fail9); 301 #endif 302 fail8: 303 EFSYS_PROBE(fail8); 304 fail7: 305 EFSYS_PROBE(fail7); 306 fail6: 307 EFSYS_PROBE(fail6); 308 fail5: 309 EFSYS_PROBE(fail5); 310 fail4: 311 EFSYS_PROBE(fail4); 312 fail3: 313 EFSYS_PROBE(fail3); 314 fail2: 315 EFSYS_PROBE(fail2); 316 fail1: 317 EFSYS_PROBE1(fail1, int, rc); 318 319 return (rc); 320 } 321 322 __checkReturn int 323 siena_nic_reset( 324 __in efx_nic_t *enp) 325 { 326 efx_mcdi_req_t req; 327 int rc; 328 329 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 330 331 /* siena_nic_reset() is called to recover from BADASSERT failures. */ 332 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 333 goto fail1; 334 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 335 goto fail2; 336 337 /* 338 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied 339 * for backwards compatibility with PORT_RESET_IN_LEN. 340 */ 341 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0); 342 343 req.emr_cmd = MC_CMD_ENTITY_RESET; 344 req.emr_in_buf = NULL; 345 req.emr_in_length = 0; 346 req.emr_out_buf = NULL; 347 req.emr_out_length = 0; 348 349 efx_mcdi_execute(enp, &req); 350 351 if (req.emr_rc != 0) { 352 rc = req.emr_rc; 353 goto fail3; 354 } 355 356 return (0); 357 358 fail3: 359 EFSYS_PROBE(fail3); 360 fail2: 361 EFSYS_PROBE(fail2); 362 fail1: 363 EFSYS_PROBE1(fail1, int, rc); 364 365 return (0); 366 } 367 368 static void 369 siena_nic_rx_cfg( 370 __in efx_nic_t *enp) 371 { 372 efx_oword_t oword; 373 374 /* 375 * RX_INGR_EN is always enabled on Siena, because we rely on 376 * the RX parser to be resiliant to missing SOP/EOP. 377 */ 378 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); 379 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1); 380 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); 381 382 /* Disable parsing of additional 802.1Q in Q packets */ 383 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 384 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0); 385 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 386 } 387 388 static void 389 siena_nic_usrev_dis( 390 __in efx_nic_t *enp) 391 { 392 efx_oword_t oword; 393 394 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1); 395 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword); 396 } 397 398 __checkReturn int 399 siena_nic_init( 400 __in efx_nic_t *enp) 401 { 402 int rc; 403 404 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 405 406 /* Enable reporting of some events (e.g. link change) */ 407 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 408 goto fail1; 409 410 siena_sram_init(enp); 411 412 /* Configure Siena's RX block */ 413 siena_nic_rx_cfg(enp); 414 415 /* Disable USR_EVents for now */ 416 siena_nic_usrev_dis(enp); 417 418 /* bug17057: Ensure set_link is called */ 419 if ((rc = siena_phy_reconfigure(enp)) != 0) 420 goto fail2; 421 422 return (0); 423 424 fail2: 425 EFSYS_PROBE(fail2); 426 fail1: 427 EFSYS_PROBE1(fail1, int, rc); 428 429 return (rc); 430 } 431 432 void 433 siena_nic_fini( 434 __in efx_nic_t *enp) 435 { 436 _NOTE(ARGUNUSED(enp)) 437 } 438 439 void 440 siena_nic_unprobe( 441 __in efx_nic_t *enp) 442 { 443 #if EFSYS_OPT_MON_STATS 444 mcdi_mon_cfg_free(enp); 445 #endif /* EFSYS_OPT_MON_STATS */ 446 (void) efx_mcdi_drv_attach(enp, B_FALSE); 447 } 448 449 #if EFSYS_OPT_DIAG 450 451 static efx_register_set_t __siena_registers[] = { 452 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 }, 453 { FR_CZ_USR_EV_CFG_OFST, 0, 1 }, 454 { FR_AZ_RX_CFG_REG_OFST, 0, 1 }, 455 { FR_AZ_TX_CFG_REG_OFST, 0, 1 }, 456 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 }, 457 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 }, 458 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 }, 459 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 }, 460 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 }, 461 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1}, 462 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1}, 463 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1}, 464 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1} 465 }; 466 467 static const uint32_t __siena_register_masks[] = { 468 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 469 0x000103FF, 0x00000000, 0x00000000, 0x00000000, 470 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000, 471 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF, 472 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF, 473 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000, 474 0x00000003, 0x00000000, 0x00000000, 0x00000000, 475 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 476 0x00000FFF, 0x00000000, 0x00000000, 0x00000000, 477 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 478 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 479 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 480 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000 481 }; 482 483 static efx_register_set_t __siena_tables[] = { 484 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP, 485 FR_AZ_RX_FILTER_TBL0_ROWS }, 486 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP, 487 FR_CZ_RX_MAC_FILTER_TBL0_ROWS }, 488 { FR_AZ_RX_DESC_PTR_TBL_OFST, 489 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS }, 490 { FR_AZ_TX_DESC_PTR_TBL_OFST, 491 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS }, 492 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS }, 493 { FR_CZ_TX_FILTER_TBL0_OFST, 494 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS }, 495 { FR_CZ_TX_MAC_FILTER_TBL0_OFST, 496 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS } 497 }; 498 499 static const uint32_t __siena_table_masks[] = { 500 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF, 501 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000, 502 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000, 503 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000, 504 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000, 505 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF, 506 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000, 507 }; 508 509 __checkReturn int 510 siena_nic_register_test( 511 __in efx_nic_t *enp) 512 { 513 efx_register_set_t *rsp; 514 const uint32_t *dwordp; 515 unsigned int nitems; 516 unsigned int count; 517 int rc; 518 519 /* Fill out the register mask entries */ 520 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks) 521 == EFX_ARRAY_SIZE(__siena_registers) * 4); 522 523 nitems = EFX_ARRAY_SIZE(__siena_registers); 524 dwordp = __siena_register_masks; 525 for (count = 0; count < nitems; ++count) { 526 rsp = __siena_registers + count; 527 rsp->mask.eo_u32[0] = *dwordp++; 528 rsp->mask.eo_u32[1] = *dwordp++; 529 rsp->mask.eo_u32[2] = *dwordp++; 530 rsp->mask.eo_u32[3] = *dwordp++; 531 } 532 533 /* Fill out the register table entries */ 534 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks) 535 == EFX_ARRAY_SIZE(__siena_tables) * 4); 536 537 nitems = EFX_ARRAY_SIZE(__siena_tables); 538 dwordp = __siena_table_masks; 539 for (count = 0; count < nitems; ++count) { 540 rsp = __siena_tables + count; 541 rsp->mask.eo_u32[0] = *dwordp++; 542 rsp->mask.eo_u32[1] = *dwordp++; 543 rsp->mask.eo_u32[2] = *dwordp++; 544 rsp->mask.eo_u32[3] = *dwordp++; 545 } 546 547 if ((rc = efx_nic_test_registers(enp, __siena_registers, 548 EFX_ARRAY_SIZE(__siena_registers))) != 0) 549 goto fail1; 550 551 if ((rc = efx_nic_test_tables(enp, __siena_tables, 552 EFX_PATTERN_BYTE_ALTERNATE, 553 EFX_ARRAY_SIZE(__siena_tables))) != 0) 554 goto fail2; 555 556 if ((rc = efx_nic_test_tables(enp, __siena_tables, 557 EFX_PATTERN_BYTE_CHANGING, 558 EFX_ARRAY_SIZE(__siena_tables))) != 0) 559 goto fail3; 560 561 if ((rc = efx_nic_test_tables(enp, __siena_tables, 562 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0) 563 goto fail4; 564 565 return (0); 566 567 fail4: 568 EFSYS_PROBE(fail4); 569 fail3: 570 EFSYS_PROBE(fail3); 571 fail2: 572 EFSYS_PROBE(fail2); 573 fail1: 574 EFSYS_PROBE1(fail1, int, rc); 575 576 return (rc); 577 } 578 579 #endif /* EFSYS_OPT_DIAG */ 580 581 #endif /* EFSYS_OPT_SIENA */ 582