1 /* 2 * Copyright 2007-2013 Solarflare Communications Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include "efsys.h" 27 #include "efx.h" 28 #include "falcon_nvram.h" 29 #include "efx_types.h" 30 #include "efx_impl.h" 31 32 #if EFSYS_OPT_FALCON 33 34 #if EFSYS_OPT_MON_LM87 35 #include "lm87.h" 36 #endif 37 38 #if EFSYS_OPT_MON_MAX6647 39 #include "max6647.h" 40 #endif 41 42 #if EFSYS_OPT_NVRAM_SFX7101 43 #include "sfx7101.h" 44 #endif 45 46 #if EFSYS_OPT_NVRAM_SFT9001 47 #include "sft9001.h" 48 #endif 49 50 #define FALCON_NVRAM_INIT_LOWEST_REG \ 51 MIN(CFG_VERSION_REG_SF_OFST, \ 52 MIN(CFG_FLASH_DEV_REG_SF_OFST, \ 53 CFG_EEPROM_DEV_REG_SF_OFST)) 54 55 #define FALCON_NVRAM_INIT_HIGHEST_REG \ 56 MAX(CFG_VERSION_REG_SF_OFST, \ 57 MAX(CFG_FLASH_DEV_REG_SF_OFST, \ 58 CFG_EEPROM_DEV_REG_SF_OFST)) 59 60 #define FALCON_NVRAM_INIT_NEEDED_CFG_SIZE \ 61 (FALCON_NVRAM_INIT_HIGHEST_REG + sizeof (efx_oword_t) \ 62 - FALCON_NVRAM_INIT_LOWEST_REG) 63 64 __checkReturn int 65 falcon_nvram_init( 66 __in efx_nic_t *enp) 67 { 68 falcon_spi_dev_t *fsdp; 69 efx_oword_t oword; 70 uint16_t version; 71 int rc; 72 uint8_t cfg[FALCON_NVRAM_INIT_NEEDED_CFG_SIZE]; 73 uint8_t *origin = cfg - FALCON_NVRAM_INIT_LOWEST_REG; 74 75 /* All boards have flash and EEPROM */ 76 EFX_BAR_READO(enp, FR_AB_NIC_STAT_REG, &oword); 77 EFX_SET_OWORD_FIELD(oword, FRF_AB_SF_PRST, 1); 78 EFX_SET_OWORD_FIELD(oword, FRF_AB_EE_PRST, 1); 79 EFX_BAR_WRITEO(enp, FR_AB_NIC_STAT_REG, &oword); 80 81 /* Set up partial flash parameters */ 82 fsdp = &(enp->en_u.falcon.enu_fsd[FALCON_SPI_FLASH]); 83 fsdp->fsd_sf_sel = 1; 84 fsdp->fsd_adbcnt = 3; 85 fsdp->fsd_munge = B_FALSE; 86 87 if ((rc = falcon_nic_cfg_raw_read_verify(enp, 88 FALCON_NVRAM_INIT_LOWEST_REG, 89 FALCON_NVRAM_INIT_NEEDED_CFG_SIZE, cfg)) != 0) 90 goto fail1; 91 92 version = EFX_WORD_FIELD( 93 *(efx_word_t *)(origin + CFG_VERSION_REG_SF_OFST), VERSION); 94 95 if (version < 3) { 96 fsdp->fsd_size = (size_t)1 << 17; 97 fsdp->fsd_erase_cmd = 0x52; 98 fsdp->fsd_erase_size = (size_t)1 << 15; 99 fsdp->fsd_write_size = (size_t)1 << 8; 100 } else { 101 efx_dword_t *dwordp = 102 (efx_dword_t *)(origin + CFG_FLASH_DEV_REG_SF_OFST); 103 104 if (EFX_DWORD_FIELD(*dwordp, SPI_DEV_ADBCNT) != 3 || 105 EFX_DWORD_FIELD(*dwordp, SPI_DEV_SIZE) >= 24) { 106 rc = EINVAL; 107 goto fail2; 108 } 109 110 fsdp->fsd_size = (size_t)1 << EFX_DWORD_FIELD(*dwordp, 111 SPI_DEV_SIZE); 112 fsdp->fsd_erase_cmd = EFX_DWORD_FIELD(*dwordp, 113 SPI_DEV_ERASE_CMD); 114 fsdp->fsd_erase_size = (size_t)1 << EFX_DWORD_FIELD(*dwordp, 115 SPI_DEV_ERASE_SIZE); 116 fsdp->fsd_write_size = (size_t)1 << EFX_DWORD_FIELD(*dwordp, 117 SPI_DEV_WRITE_SIZE); 118 } 119 120 /* Configure the EEPROM */ 121 fsdp = &(enp->en_u.falcon.enu_fsd[FALCON_SPI_EEPROM]); 122 123 fsdp->fsd_sf_sel = 0; 124 if (version < 3) { 125 fsdp->fsd_adbcnt = 1; 126 fsdp->fsd_size = (size_t)1 << 9; 127 fsdp->fsd_munge = B_TRUE; 128 fsdp->fsd_erase_cmd = 0; 129 fsdp->fsd_erase_size = 1; 130 fsdp->fsd_write_size = (size_t)1 << 3; 131 } else { 132 efx_dword_t *dwordp = 133 (efx_dword_t *)(origin + CFG_EEPROM_DEV_REG_SF_OFST); 134 135 fsdp->fsd_adbcnt = EFX_DWORD_FIELD(*dwordp, SPI_DEV_ADBCNT); 136 fsdp->fsd_size = (size_t)1 << EFX_DWORD_FIELD(*dwordp, 137 SPI_DEV_SIZE); 138 fsdp->fsd_munge = (EFX_DWORD_FIELD(*dwordp, SPI_DEV_SIZE) > 139 fsdp->fsd_adbcnt * 8); 140 fsdp->fsd_erase_cmd = EFX_DWORD_FIELD(*dwordp, 141 SPI_DEV_ERASE_CMD); 142 fsdp->fsd_erase_size = (size_t)1 << EFX_DWORD_FIELD(*dwordp, 143 SPI_DEV_ERASE_SIZE); 144 fsdp->fsd_write_size = (size_t)1 << EFX_DWORD_FIELD(*dwordp, 145 SPI_DEV_WRITE_SIZE); 146 } 147 148 return (0); 149 150 fail2: 151 EFSYS_PROBE(fail2); 152 fail1: 153 EFSYS_PROBE1(fail1, int, rc); 154 155 (void) memset(enp->en_u.falcon.enu_fsd, 0, 156 sizeof (enp->en_u.falcon.enu_fsd)); 157 158 return (rc); 159 } 160 161 #if EFSYS_OPT_NVRAM 162 163 typedef struct falcon_nvram_ops_s { 164 int (*fnvo_size)(efx_nic_t *, size_t *); 165 int (*fnvo_get_version)(efx_nic_t *, uint32_t *, uint16_t *); 166 int (*fnvo_rw_start)(efx_nic_t *, size_t *); 167 int (*fnvo_read_chunk)(efx_nic_t *, unsigned int, 168 caddr_t, size_t); 169 int (*fnvo_erase)(efx_nic_t *); 170 int (*fnvo_write_chunk)(efx_nic_t *, unsigned int, 171 caddr_t, size_t); 172 void (*fnvo_rw_finish)(efx_nic_t *); 173 } falcon_nvram_ops_t; 174 175 #if EFSYS_OPT_NVRAM_FALCON_BOOTROM 176 177 #define FALCON_GPXE_IMAGE_OFFSET 0x8000 178 #define FALCON_GPXE_IMAGE_SIZE 0x18000 179 180 static __checkReturn int 181 falcon_nvram_bootrom_size( 182 __in efx_nic_t *enp, 183 __out size_t *sizep) 184 { 185 _NOTE(ARGUNUSED(enp)) 186 EFSYS_ASSERT(sizep != NULL); 187 *sizep = FALCON_GPXE_IMAGE_SIZE; 188 189 return (0); 190 } 191 192 static __checkReturn int 193 falcon_nvram_bootrom_get_version( 194 __in efx_nic_t *enp, 195 __out uint32_t *subtypep, 196 __out_ecount(4) uint16_t version[4]) 197 { 198 const char prefix[] = "Solarstorm Boot Manager (v"; 199 char buf[16], p; 200 size_t current, needle; 201 uint16_t *versionp; 202 int rc; 203 204 version[0] = version[1] = version[2] = version[3] = 0; 205 versionp = NULL; 206 needle = 0; 207 208 /* 209 * Search from [current, end) for prefix, and return the 210 * trailing four decimal number. 211 */ 212 for (current = 0; current < 0x600; current++) { 213 if (current % sizeof (buf) == 0) { 214 if ((rc = falcon_spi_dev_read(enp, FALCON_SPI_FLASH, 215 FALCON_GPXE_IMAGE_OFFSET + current, buf, 216 sizeof (buf))) != 0) 217 break; 218 } 219 220 p = buf[current % sizeof (buf)]; 221 if (versionp == NULL) { 222 if (prefix[needle] == p) { 223 ++needle; 224 if (needle == sizeof (prefix) - 1) 225 versionp = version; 226 } else 227 needle = 0; 228 } else { 229 if (p == ')' && versionp == version + 3) 230 goto done; 231 else if (p >= '0' && p <= '9') 232 *versionp = (*versionp * 10) + (p - '0'); 233 else if (p == '.' && versionp != version + 3) 234 ++versionp; 235 else 236 /* Invalid format */ 237 break; 238 } 239 } 240 241 version[0] = version[1] = version[2] = version[3] = 0; 242 243 done: 244 *subtypep = 0; /* Falcon bootrom is type 0 */ 245 246 return (0); 247 } 248 249 static __checkReturn int 250 falcon_nvram_bootrom_rw_start( 251 __in efx_nic_t *enp, 252 __out size_t *chunk_sizep) 253 { 254 _NOTE(ARGUNUSED(enp)) 255 if (chunk_sizep != NULL) 256 *chunk_sizep = sizeof (efx_oword_t); 257 258 return (0); 259 } 260 261 static __checkReturn int 262 falcon_nvram_bootrom_read_chunk( 263 __in efx_nic_t *enp, 264 __in unsigned int offset, 265 __out_bcount(size) caddr_t data, 266 __in size_t size) 267 { 268 int rc; 269 270 EFSYS_ASSERT3U(size + offset, <=, FALCON_GPXE_IMAGE_SIZE); 271 272 if ((rc = falcon_spi_dev_read(enp, FALCON_SPI_FLASH, 273 FALCON_GPXE_IMAGE_OFFSET + offset, data, size)) != 0) 274 goto fail1; 275 276 return (0); 277 278 fail1: 279 EFSYS_PROBE1(fail1, int, rc); 280 281 return (rc); 282 } 283 284 static __checkReturn int 285 falcon_nvram_bootrom_erase( 286 __in efx_nic_t *enp) 287 { 288 int rc; 289 290 if ((rc = falcon_spi_dev_erase(enp, FALCON_SPI_FLASH, 291 FALCON_GPXE_IMAGE_OFFSET, FALCON_GPXE_IMAGE_SIZE)) != 0) 292 goto fail1; 293 294 return (0); 295 296 fail1: 297 EFSYS_PROBE1(fail1, int, rc); 298 299 return (rc); 300 } 301 302 static __checkReturn int 303 falcon_nvram_bootrom_write_chunk( 304 __in efx_nic_t *enp, 305 __in unsigned int offset, 306 __out_bcount(size) caddr_t base, 307 __in size_t size) 308 { 309 int rc; 310 311 if ((rc = falcon_spi_dev_write(enp, FALCON_SPI_FLASH, 312 FALCON_GPXE_IMAGE_OFFSET + offset, base, size)) != 0) 313 goto fail1; 314 315 return (0); 316 317 fail1: 318 EFSYS_PROBE1(fail1, int, rc); 319 320 return (rc); 321 } 322 323 static falcon_nvram_ops_t __cs __falcon_nvram_bootrom_ops = { 324 falcon_nvram_bootrom_size, /* fnvo_size */ 325 falcon_nvram_bootrom_get_version, /* fnvo_get_version */ 326 falcon_nvram_bootrom_rw_start, /* fnvo_rw_start */ 327 falcon_nvram_bootrom_read_chunk, /* fnvo_read_chunk */ 328 falcon_nvram_bootrom_erase, /* fnvo_erase */ 329 falcon_nvram_bootrom_write_chunk, /* fnvo_write_chunk */ 330 NULL, /* fnvo_rw_finish */ 331 }; 332 333 #define FALCON_GPXE_CFG_OFFSET 0x800 334 335 static __checkReturn int 336 falcon_nvram_bootrom_cfg_size( 337 __in efx_nic_t *enp, 338 __out size_t *sizep) 339 { 340 falcon_spi_dev_t *fsdp = 341 &(enp->en_u.falcon.enu_fsd[FALCON_SPI_EEPROM]); 342 int rc; 343 344 EFSYS_ASSERT(sizep != NULL); 345 EFSYS_ASSERT(fsdp != NULL); 346 347 if (fsdp->fsd_size < FALCON_GPXE_CFG_OFFSET) { 348 *sizep = 0; 349 rc = ENOTSUP; 350 goto fail1; 351 } 352 353 *sizep = fsdp->fsd_size - FALCON_GPXE_CFG_OFFSET; 354 355 return (0); 356 357 fail1: 358 EFSYS_PROBE1(fail1, int, rc); 359 360 return (rc); 361 } 362 363 static __checkReturn int 364 falcon_nvram_bootrom_cfg_get_version( 365 __in efx_nic_t *enp, 366 __out uint32_t *subtypep, 367 __out_ecount(4) uint16_t version[4]) 368 { 369 falcon_spi_dev_t *fsdp = 370 &(enp->en_u.falcon.enu_fsd[FALCON_SPI_EEPROM]); 371 int rc; 372 373 EFSYS_ASSERT(fsdp != NULL); 374 if (fsdp->fsd_size < FALCON_GPXE_CFG_OFFSET) { 375 rc = ENOTSUP; 376 goto fail1; 377 } 378 379 /* gpxecfg is not versioned */ 380 *subtypep = 0; 381 version[0] = version[1] = version[2] = version[3]; 382 383 return (0); 384 385 fail1: 386 EFSYS_PROBE1(fail1, int, rc); 387 388 return (rc); 389 } 390 391 static __checkReturn int 392 falcon_nvram_bootrom_cfg_rw_start( 393 __in efx_nic_t *enp, 394 __out size_t *chunk_sizep) 395 { 396 falcon_spi_dev_t *fsdp = 397 &(enp->en_u.falcon.enu_fsd[FALCON_SPI_EEPROM]); 398 int rc; 399 400 EFSYS_ASSERT(fsdp != NULL); 401 if (fsdp->fsd_size < FALCON_GPXE_CFG_OFFSET) { 402 rc = ENOTSUP; 403 goto fail1; 404 } 405 406 if (chunk_sizep != NULL) 407 *chunk_sizep = sizeof (efx_oword_t); 408 409 return (0); 410 411 fail1: 412 EFSYS_PROBE1(fail1, int, rc); 413 414 return (rc); 415 } 416 417 418 static __checkReturn int 419 falcon_nvram_bootrom_cfg_read_chunk( 420 __in efx_nic_t *enp, 421 __in unsigned int offset, 422 __out_bcount(size) caddr_t data, 423 __in size_t size) 424 { 425 falcon_spi_dev_t *fsdp = 426 &(enp->en_u.falcon.enu_fsd[FALCON_SPI_EEPROM]); 427 int rc; 428 429 EFSYS_ASSERT(fsdp != NULL); 430 EFSYS_ASSERT3U(fsdp->fsd_size, >=, FALCON_GPXE_CFG_OFFSET); 431 EFSYS_ASSERT3U(offset + size, <=, 432 fsdp->fsd_size - FALCON_GPXE_CFG_OFFSET); 433 434 if ((rc = falcon_spi_dev_read(enp, FALCON_SPI_EEPROM, 435 FALCON_GPXE_CFG_OFFSET + offset, data, size)) != 0) 436 goto fail1; 437 438 return (0); 439 440 fail1: 441 EFSYS_PROBE1(fail1, int, rc); 442 443 return (rc); 444 } 445 446 static __checkReturn int 447 falcon_nvram_bootrom_cfg_write_chunk( 448 __in efx_nic_t *enp, 449 __in unsigned int offset, 450 __in_bcount(size) caddr_t base, 451 __in size_t size) 452 { 453 falcon_spi_dev_t *fsdp = 454 &(enp->en_u.falcon.enu_fsd[FALCON_SPI_EEPROM]); 455 int rc; 456 457 EFSYS_ASSERT(fsdp != NULL); 458 EFSYS_ASSERT3U(fsdp->fsd_size, >=, FALCON_GPXE_CFG_OFFSET); 459 EFSYS_ASSERT3U(offset + size, <=, 460 fsdp->fsd_size - FALCON_GPXE_CFG_OFFSET); 461 462 if ((rc = falcon_spi_dev_write(enp, FALCON_SPI_EEPROM, 463 FALCON_GPXE_CFG_OFFSET + offset, base, size)) != 0) 464 goto fail1; 465 466 return (0); 467 468 fail1: 469 EFSYS_PROBE1(fail1, int, rc); 470 471 return (rc); 472 } 473 474 static falcon_nvram_ops_t __cs __falcon_nvram_bootrom_cfg_ops = { 475 falcon_nvram_bootrom_cfg_size, /* fnvo_size */ 476 falcon_nvram_bootrom_cfg_get_version, /* fnvo_get_version */ 477 falcon_nvram_bootrom_cfg_rw_start, /* fnvo_rw_start */ 478 falcon_nvram_bootrom_cfg_read_chunk, /* fnvo_read_chunk */ 479 NULL, /* fnvo_erase */ 480 falcon_nvram_bootrom_cfg_write_chunk, /* fnvo_write_chunk */ 481 NULL, /* fnvo_rw_finish */ 482 }; 483 484 #endif /* EFSYS_OPT_NVRAM_FALCON_BOOTROM */ 485 486 #if EFSYS_OPT_NVRAM_SFX7101 487 488 static falcon_nvram_ops_t __cs __falcon_sfx7101_ops = { 489 sfx7101_nvram_size, /* fnvo_size */ 490 sfx7101_nvram_get_version, /* fnvo_get_version */ 491 sfx7101_nvram_rw_start, /* fnvo_rw_start */ 492 sfx7101_nvram_read_chunk, /* fnvo_read_chunk */ 493 sfx7101_nvram_erase, /* fnvo_erase */ 494 sfx7101_nvram_write_chunk, /* fnvo_write_chunk */ 495 sfx7101_nvram_rw_finish, /* fnvo_rw_finish */ 496 }; 497 498 #endif /* EFSYS_OPT_NVRAM_SFX7101 */ 499 500 #if EFSYS_OPT_NVRAM_SFT9001 501 502 static falcon_nvram_ops_t __cs __falcon_sft9001_ops = { 503 sft9001_nvram_size, /* fnvo_size */ 504 sft9001_nvram_get_version, /* fnvo_get_version */ 505 sft9001_nvram_rw_start, /* fnvo_rw_start */ 506 sft9001_nvram_read_chunk, /* fnvo_read_chunk */ 507 sft9001_nvram_erase, /* fnvo_erase */ 508 sft9001_nvram_write_chunk, /* fnvo_write_chunk */ 509 sft9001_nvram_rw_finish, /* fnvo_rw_finish */ 510 }; 511 512 #endif /* EFSYS_OPT_NVRAM_SFT9001 */ 513 514 static __checkReturn int 515 falcon_nvram_get_ops( 516 __in efx_nic_t *enp, 517 __in efx_nvram_type_t type, 518 __out falcon_nvram_ops_t **fnvopp) 519 { 520 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 521 falcon_nvram_ops_t *fnvop; 522 int rc; 523 524 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); 525 526 switch (type) { 527 #if EFSYS_OPT_NVRAM_FALCON_BOOTROM 528 case EFX_NVRAM_BOOTROM_CFG: 529 fnvop = (falcon_nvram_ops_t *)&__falcon_nvram_bootrom_cfg_ops; 530 goto done; 531 532 case EFX_NVRAM_BOOTROM: 533 fnvop = (falcon_nvram_ops_t *)&__falcon_nvram_bootrom_ops; 534 goto done; 535 #endif 536 case EFX_NVRAM_PHY: 537 switch (encp->enc_phy_type) { 538 #if EFSYS_OPT_NVRAM_SFX7101 539 case EFX_PHY_SFX7101: 540 fnvop = (falcon_nvram_ops_t *)&__falcon_sfx7101_ops; 541 goto done; 542 #endif /* EFSYS_OPT_NVRAM_SFX7101 */ 543 544 #if EFSYS_OPT_NVRAM_SFT9001 545 case EFX_PHY_SFT9001B: 546 fnvop = (falcon_nvram_ops_t *)&__falcon_sft9001_ops; 547 goto done; 548 #endif /* EFSYS_OPT_NVRAM_SFT9001 */ 549 550 default: 551 break; 552 } 553 554 break; 555 556 default: 557 break; 558 } 559 560 rc = ENOTSUP; 561 goto fail1; 562 563 done: 564 *fnvopp = fnvop; 565 566 return (0); 567 568 fail1: 569 EFSYS_PROBE1(fail1, int, rc); 570 571 return (rc); 572 } 573 574 #if EFSYS_OPT_DIAG 575 576 __checkReturn int 577 falcon_nvram_test( 578 __in efx_nic_t *enp) 579 { 580 efx_nic_cfg_t enc; 581 int rc; 582 583 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 584 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 585 586 if ((rc = falcon_nic_cfg_build(enp, &enc)) != 0) 587 goto fail1; 588 589 return (0); 590 591 fail1: 592 EFSYS_PROBE1(fail1, int, rc); 593 594 return (rc); 595 } 596 597 #endif /* EFSYS_OPT_DIAG */ 598 599 __checkReturn int 600 falcon_nvram_size( 601 __in efx_nic_t *enp, 602 __in efx_nvram_type_t type, 603 __out size_t *sizep) 604 { 605 falcon_nvram_ops_t *fnvop; 606 int rc; 607 608 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 609 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 610 611 if ((rc = falcon_nvram_get_ops(enp, type, &fnvop)) != 0) 612 goto fail1; 613 614 if ((rc = fnvop->fnvo_size(enp, sizep)) != 0) 615 goto fail2; 616 617 return (0); 618 619 fail2: 620 EFSYS_PROBE(fail2); 621 fail1: 622 EFSYS_PROBE1(fail1, int, rc); 623 624 return (rc); 625 } 626 627 __checkReturn int 628 falcon_nvram_get_version( 629 __in efx_nic_t *enp, 630 __in efx_nvram_type_t type, 631 __out uint32_t *subtypep, 632 __out_ecount(4) uint16_t version[4]) 633 { 634 falcon_nvram_ops_t *fnvop; 635 int rc; 636 637 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 638 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 639 640 if ((rc = falcon_nvram_get_ops(enp, type, &fnvop)) != 0) 641 goto fail1; 642 643 if ((rc = fnvop->fnvo_get_version(enp, subtypep, version)) != 0) 644 goto fail2; 645 646 return (0); 647 648 fail2: 649 EFSYS_PROBE(fail2); 650 fail1: 651 EFSYS_PROBE1(fail1, int, rc); 652 653 return (rc); 654 } 655 656 __checkReturn int 657 falcon_nvram_rw_start( 658 __in efx_nic_t *enp, 659 __in efx_nvram_type_t type, 660 __out size_t *chunk_sizep) 661 { 662 falcon_nvram_ops_t *fnvop; 663 int rc; 664 665 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 666 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 667 668 if ((rc = falcon_nvram_get_ops(enp, type, &fnvop)) != 0) 669 goto fail1; 670 671 if ((rc = fnvop->fnvo_rw_start(enp, chunk_sizep)) != 0) 672 goto fail2; 673 674 return (0); 675 676 fail2: 677 EFSYS_PROBE(fail2); 678 fail1: 679 EFSYS_PROBE1(fail1, int, rc); 680 681 return (rc); 682 } 683 684 __checkReturn int 685 falcon_nvram_read_chunk( 686 __in efx_nic_t *enp, 687 __in efx_nvram_type_t type, 688 __in unsigned int offset, 689 __out_bcount(size) caddr_t data, 690 __in size_t size) 691 { 692 falcon_nvram_ops_t *fnvop; 693 int rc; 694 695 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 696 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 697 698 if ((rc = falcon_nvram_get_ops(enp, type, &fnvop)) != 0) 699 goto fail1; 700 701 if ((rc = fnvop->fnvo_read_chunk(enp, offset, data, size)) != 0) 702 goto fail2; 703 704 return (0); 705 706 fail2: 707 EFSYS_PROBE(fail2); 708 fail1: 709 EFSYS_PROBE1(fail1, int, rc); 710 711 return (rc); 712 } 713 714 __checkReturn int 715 falcon_nvram_erase( 716 __in efx_nic_t *enp, 717 __in efx_nvram_type_t type) 718 { 719 falcon_nvram_ops_t *fnvop; 720 int rc; 721 722 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 723 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 724 725 if ((rc = falcon_nvram_get_ops(enp, type, &fnvop)) != 0) 726 goto fail1; 727 728 if (fnvop->fnvo_erase != NULL) { 729 if ((rc = fnvop->fnvo_erase(enp)) != 0) 730 goto fail2; 731 } 732 733 return (0); 734 735 fail2: 736 EFSYS_PROBE(fail2); 737 fail1: 738 EFSYS_PROBE1(fail1, int, rc); 739 740 return (rc); 741 } 742 743 __checkReturn int 744 falcon_nvram_write_chunk( 745 __in efx_nic_t *enp, 746 __in efx_nvram_type_t type, 747 __in unsigned int offset, 748 __in_bcount(size) caddr_t data, 749 __in size_t size) 750 { 751 falcon_nvram_ops_t *fnvop; 752 int rc; 753 754 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 755 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 756 757 if ((rc = falcon_nvram_get_ops(enp, type, &fnvop)) != 0) 758 goto fail1; 759 760 if ((rc = fnvop->fnvo_write_chunk(enp, offset, data, size)) != 0) 761 goto fail2; 762 763 return (0); 764 765 fail2: 766 EFSYS_PROBE(fail2); 767 fail1: 768 EFSYS_PROBE1(fail1, int, rc); 769 770 return (rc); 771 } 772 773 void 774 falcon_nvram_rw_finish( 775 __in efx_nic_t *enp, 776 __in efx_nvram_type_t type) 777 { 778 falcon_nvram_ops_t *fnvop; 779 int rc; 780 781 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 782 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 783 784 rc = falcon_nvram_get_ops(enp, type, &fnvop); 785 EFSYS_ASSERT(rc == 0); 786 if (rc == 0) { 787 if (fnvop->fnvo_rw_finish != NULL) 788 fnvop->fnvo_rw_finish(enp); 789 } 790 } 791 792 __checkReturn int 793 falcon_nvram_set_version( 794 __in efx_nic_t *enp, 795 __in efx_nvram_type_t type, 796 __out uint16_t version[4]) 797 { 798 falcon_nvram_ops_t *fnvop; 799 uint32_t subtype; 800 uint16_t old_version[4]; 801 int rc; 802 803 _NOTE(ARGUNUSED(enp)) 804 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 805 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON); 806 807 /* 808 * There is no room on Falcon to version anything, so it's 809 * inferred where possible from the underlying entity. 810 */ 811 if ((rc = falcon_nvram_get_ops(enp, type, &fnvop)) != 0) 812 goto fail1; 813 814 /* 815 * The user *really should be setting the version correctly 816 */ 817 if ((rc = fnvop->fnvo_get_version(enp, &subtype, old_version)) != 0) 818 goto fail2; 819 EFSYS_ASSERT(memcmp(old_version, version, sizeof (old_version)) == 0); 820 821 return (0); 822 823 fail2: 824 EFSYS_PROBE(fail2); 825 fail1: 826 EFSYS_PROBE1(fail1, int, rc); 827 828 return (rc); 829 } 830 831 #endif /* EFSYS_OPT_NVRAM */ 832 833 void 834 falcon_nvram_fini( 835 __in efx_nic_t *enp) 836 { 837 (void) memset(&enp->en_u.falcon.enu_fsd, 0, 838 sizeof (enp->en_u.falcon.enu_fsd)); 839 } 840 841 #endif /* EFSYS_OPT_FALCON */