siena_nvram.c revision 49ef7e0638c8b771d8a136eae78b1c0f99acc8e0
/*
* Copyright (c) 2009-2015 Solarflare Communications Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the FreeBSD Project.
*/
#include "efx.h"
#include "efx_impl.h"
#if EFSYS_OPT_SIENA
#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
{
goto fail1;
}
goto fail2;
}
return (0);
return (rc);
}
{
goto fail1;
}
return (0);
return (rc);
}
{
while (size > 0) {
MC_CMD_NVRAM_READ_IN_V2_DEFAULT)) != 0) {
goto fail1;
}
}
return (0);
return (rc);
}
{
goto fail1;
}
return (0);
return (rc);
}
{
while (size > 0) {
goto fail1;
}
}
return (0);
return (rc);
}
void
{
/*
* Reboot into the new image only for PHYs. The driver has to
* explicitly cope with an MC reboot after a firmware update.
*/
goto fail1;
}
return;
}
#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
#if EFSYS_OPT_NVRAM
typedef struct siena_parttbl_entry_s {
unsigned int partn;
unsigned int port;
static siena_parttbl_entry_t siena_parttbl[] = {
};
{
unsigned int i;
for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
return (0);
}
}
return (ENOTSUP);
}
#if EFSYS_OPT_DIAG
{
unsigned int i;
/*
* Iterate over the list of supported partition types
* applicable to *this* port
*/
for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
entry = &siena_parttbl[i];
continue;
goto fail1;
}
}
return (0);
return (rc);
}
#endif /* EFSYS_OPT_DIAG */
#define SIENA_DYNAMIC_CFG_SIZE(_nitems) \
(sizeof (siena_mc_dynamic_config_hdr_t) + ((_nitems) * \
{
unsigned int vpd_offset;
unsigned int vpd_length;
unsigned int hdr_length;
unsigned int nversions;
unsigned int pos;
unsigned int region;
/*
* Allocate sufficient memory for the entire dynamiccfg area, even
* if we're not actually going to read in the VPD.
*/
goto fail1;
goto fail2;
}
goto fail3;
/* Verify the magic */
goto invalid1;
/* All future versions of the structure must be backwards compatable */
/* Verify the hdr doesn't overflow the partn size */
goto invalid2;
/* Verify the header has room for all it's versions */
if (hdr_length < SIENA_DYNAMIC_CFG_SIZE(0) ||
goto invalid3;
/*
* Read the remaining portion of the dcfg, either including
* the whole of VPD (there is no vpd length in this structure,
* so we have to parse each tag), or just the dcfg header itself
*/
if (region > SIENA_NVRAM_CHUNK) {
region - SIENA_NVRAM_CHUNK)) != 0)
goto fail4;
}
/* Verify checksum */
cksum = 0;
if (cksum != 0)
goto invalid4;
goto done;
/*
* Construct a new "null" dcfg, with an empty version vector,
* and an empty VPD chunk trailing. This has the neat side effect
* of testing the exception paths in the write path.
*/
EFX_DWORD_0, sizeof (*dcfg));
done:
return (0);
return (rc);
}
{
goto fail1;
}
goto fail2;
}
if (req.emr_out_length_used <
goto fail3;
}
return (0);
return (rc);
}
{
unsigned int i;
goto fail1;
}
goto fail2;
/*
* Some partitions are accessible from both ports (for instance BOOTROM)
* Find the highest version reported by all dcfg structures on ports
* that have access to this partition.
*/
for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
unsigned int nitems;
entry = &siena_parttbl[i];
continue;
/*
* Ingore missing partitions on port 2, assuming they're due
* to to running on a single port part.
*/
continue;
}
goto fail3;
goto done;
done:
}
return (0);
return (rc);
}
{
goto fail1;
if (chunk_sizep != NULL)
return (0);
return (rc);
}
void
{
}
{
unsigned int hdr_length;
unsigned int vpd_length;
unsigned int vpd_offset;
unsigned int nitems;
unsigned int required_hdr_length;
unsigned int pos;
goto fail1;
goto fail2;
goto fail3;
/*
* NOTE: This function will blatt any fields trailing the version
* vector, or the VPD chunk.
*/
goto fail4;
}
if (vpd_offset < required_hdr_length) {
}
if (hdr_length < required_hdr_length) {
}
/* Get the subtype to insert into the fw_subtype array */
goto fail5;
/* Fill out the new version */
/* Update the version count */
}
/* Update the checksum */
cksum = 0;
/* Erase and write the new partition */
goto fail6;
/* Write out the new structure to nvram */
goto fail7;
return (0);
return (rc);
}
#endif /* EFSYS_OPT_NVRAM */
#endif /* EFSYS_OPT_SIENA */