X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fbase%2Fefx_nvram.c;h=5e7236ca7566878f3dabc3faacbd86786e996d7a;hb=ce77e6bf5113650e6d026e0b7fb395b60ab1f363;hp=6bd7fc2f975db6e5a39b0da16b624ddda584a806;hpb=e5fff4ee25ce572a10c04b06d09d94b9d8d4b21c;p=dpdk.git diff --git a/drivers/net/sfc/base/efx_nvram.c b/drivers/net/sfc/base/efx_nvram.c index 6bd7fc2f97..5e7236ca75 100644 --- a/drivers/net/sfc/base/efx_nvram.c +++ b/drivers/net/sfc/base/efx_nvram.c @@ -1,31 +1,7 @@ -/* - * Copyright (c) 2009-2016 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 - * and/or other materials provided with the distribution. +/* SPDX-License-Identifier: BSD-3-Clause * - * 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. + * Copyright (c) 2009-2018 Solarflare Communications Inc. + * All rights reserved. */ #include "efx.h" @@ -40,7 +16,7 @@ static const efx_nvram_ops_t __efx_nvram_siena_ops = { siena_nvram_test, /* envo_test */ #endif /* EFSYS_OPT_DIAG */ siena_nvram_type_to_partn, /* envo_type_to_partn */ - siena_nvram_partn_size, /* envo_partn_size */ + siena_nvram_partn_info, /* envo_partn_info */ siena_nvram_partn_rw_start, /* envo_partn_rw_start */ siena_nvram_partn_read, /* envo_partn_read */ siena_nvram_partn_read, /* envo_partn_read_backup */ @@ -54,14 +30,14 @@ static const efx_nvram_ops_t __efx_nvram_siena_ops = { #endif /* EFSYS_OPT_SIENA */ -#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD +#if EFX_OPTS_EF10() static const efx_nvram_ops_t __efx_nvram_ef10_ops = { #if EFSYS_OPT_DIAG ef10_nvram_test, /* envo_test */ #endif /* EFSYS_OPT_DIAG */ ef10_nvram_type_to_partn, /* envo_type_to_partn */ - ef10_nvram_partn_size, /* envo_partn_size */ + ef10_nvram_partn_info, /* envo_partn_info */ ef10_nvram_partn_rw_start, /* envo_partn_rw_start */ ef10_nvram_partn_read, /* envo_partn_read */ ef10_nvram_partn_read_backup, /* envo_partn_read_backup */ @@ -73,7 +49,7 @@ static const efx_nvram_ops_t __efx_nvram_ef10_ops = { ef10_nvram_buffer_validate, /* envo_buffer_validate */ }; -#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ +#endif /* EFX_OPTS_EF10() */ __checkReturn efx_rc_t efx_nvram_init( @@ -105,6 +81,12 @@ efx_nvram_init( break; #endif /* EFSYS_OPT_MEDFORD */ +#if EFSYS_OPT_MEDFORD2 + case EFX_FAMILY_MEDFORD2: + envop = &__efx_nvram_ef10_ops; + break; +#endif /* EFSYS_OPT_MEDFORD2 */ + default: EFSYS_ASSERT(0); rc = ENOTSUP; @@ -156,6 +138,7 @@ efx_nvram_size( __out size_t *sizep) { const efx_nvram_ops_t *envop = enp->en_envop; + efx_nvram_info_t eni = { 0 }; uint32_t partn; efx_rc_t rc; @@ -165,9 +148,11 @@ efx_nvram_size( if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0) goto fail1; - if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0) + if ((rc = envop->envo_partn_info(enp, partn, &eni)) != 0) goto fail2; + *sizep = eni.eni_partn_size; + return (0); fail2: @@ -179,6 +164,36 @@ fail1: return (rc); } +extern __checkReturn efx_rc_t +efx_nvram_info( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out efx_nvram_info_t *enip) +{ + const efx_nvram_ops_t *envop = enp->en_envop; + uint32_t partn; + efx_rc_t rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0) + goto fail1; + + if ((rc = envop->envo_partn_info(enp, partn, enip)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t efx_nvram_get_version( __in efx_nic_t *enp, @@ -323,7 +338,7 @@ efx_nvram_erase( { const efx_nvram_ops_t *envop = enp->en_envop; unsigned int offset = 0; - size_t size = 0; + efx_nvram_info_t eni = { 0 }; uint32_t partn; efx_rc_t rc; @@ -335,10 +350,11 @@ efx_nvram_erase( EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, partn); - if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0) + if ((rc = envop->envo_partn_info(enp, partn, &eni)) != 0) goto fail2; - if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0) + if ((rc = envop->envo_partn_erase(enp, partn, offset, + eni.eni_partn_size)) != 0) goto fail3; return (0); @@ -486,7 +502,7 @@ efx_nvram_validate( goto fail1; if (envop->envo_buffer_validate != NULL) { - if ((rc = envop->envo_buffer_validate(enp, partn, + if ((rc = envop->envo_buffer_validate(partn, partn_data, partn_size)) != 0) goto fail2; } @@ -532,12 +548,11 @@ efx_mcdi_nvram_partitions( __out unsigned int *npartnp) { efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN, - MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_PARTITIONS_IN_LEN, + MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX); unsigned int npartn; efx_rc_t rc; - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_PARTITIONS; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN; @@ -595,11 +610,10 @@ efx_mcdi_nvram_metadata( __in size_t size) { efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN, - MC_CMD_NVRAM_METADATA_OUT_LENMAX)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_METADATA_IN_LEN, + MC_CMD_NVRAM_METADATA_OUT_LENMAX); efx_rc_t rc; - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_METADATA; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN; @@ -608,7 +622,7 @@ efx_mcdi_nvram_metadata( MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn); - efx_mcdi_execute(enp, &req); + efx_mcdi_execute_quiet(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; @@ -680,17 +694,13 @@ fail1: efx_mcdi_nvram_info( __in efx_nic_t *enp, __in uint32_t partn, - __out_opt size_t *sizep, - __out_opt uint32_t *addressp, - __out_opt uint32_t *erase_sizep, - __out_opt uint32_t *write_sizep) + __out efx_nvram_info_t *enip) { - uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN, - MC_CMD_NVRAM_INFO_V2_OUT_LEN)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_INFO_IN_LEN, + MC_CMD_NVRAM_INFO_V2_OUT_LEN); efx_mcdi_req_t req; efx_rc_t rc; - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_INFO; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN; @@ -711,21 +721,26 @@ efx_mcdi_nvram_info( goto fail2; } - if (sizep) - *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE); + enip->eni_partn_size = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE); - if (addressp) - *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR); + enip->eni_address = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR); - if (erase_sizep) - *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE); + enip->eni_erase_size = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE); - if (write_sizep) { - *write_sizep = + enip->eni_write_size = (req.emr_out_length_used < MC_CMD_NVRAM_INFO_V2_OUT_LEN) ? 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE); - } + + enip->eni_flags = 0; + + if (MCDI_OUT_DWORD_FIELD(req, NVRAM_INFO_OUT_FLAGS, + NVRAM_INFO_OUT_PROTECTED)) + enip->eni_flags |= EFX_NVRAM_FLAG_READ_ONLY; + + if (MCDI_OUT_DWORD_FIELD(req, NVRAM_INFO_OUT_FLAGS, + NVRAM_INFO_OUT_READ_ONLY)) + enip->eni_flags |= EFX_NVRAM_FLAG_READ_ONLY; return (0); @@ -746,12 +761,11 @@ efx_mcdi_nvram_update_start( __in efx_nic_t *enp, __in uint32_t partn) { - uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN, - MC_CMD_NVRAM_UPDATE_START_OUT_LEN)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN, + MC_CMD_NVRAM_UPDATE_START_OUT_LEN); efx_mcdi_req_t req; efx_rc_t rc; - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_UPDATE_START; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN; @@ -788,8 +802,8 @@ efx_mcdi_nvram_read( __in uint32_t mode) { efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN, - MC_CMD_NVRAM_READ_OUT_LENMAX)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_READ_IN_V2_LEN, + MC_CMD_NVRAM_READ_OUT_LENMAX); efx_rc_t rc; if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) { @@ -797,7 +811,6 @@ efx_mcdi_nvram_read( goto fail1; } - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_READ; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN; @@ -843,11 +856,10 @@ efx_mcdi_nvram_erase( __in size_t size) { efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN, - MC_CMD_NVRAM_ERASE_OUT_LEN)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_ERASE_IN_LEN, + MC_CMD_NVRAM_ERASE_OUT_LEN); efx_rc_t rc; - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_ERASE; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN; @@ -883,27 +895,31 @@ efx_mcdi_nvram_write( __in efx_nic_t *enp, __in uint32_t partn, __in uint32_t offset, - __out_bcount(size) caddr_t data, + __in_bcount(size) caddr_t data, __in size_t size) { efx_mcdi_req_t req; - uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1, - MCDI_CTL_SDU_LEN_MAX_V2)]; + uint8_t *payload; efx_rc_t rc; size_t max_data_size; + size_t payload_len = enp->en_nic_cfg.enc_mcdi_max_payload_length; - max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length - - MC_CMD_NVRAM_WRITE_IN_LEN(0); - EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0); - EFSYS_ASSERT3U(max_data_size, <, - enp->en_nic_cfg.enc_mcdi_max_payload_length); + max_data_size = payload_len - MC_CMD_NVRAM_WRITE_IN_LEN(0); + EFSYS_ASSERT3U(payload_len, >, 0); + EFSYS_ASSERT3U(max_data_size, <, payload_len); if (size > max_data_size) { rc = EINVAL; goto fail1; } - (void) memset(payload, 0, sizeof (payload)); + EFSYS_KMEM_ALLOC(enp->en_esip, payload_len, payload); + if (payload == NULL) { + rc = ENOMEM; + goto fail2; + } + + (void) memset(payload, 0, payload_len); req.emr_cmd = MC_CMD_NVRAM_WRITE; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size); @@ -921,11 +937,16 @@ efx_mcdi_nvram_write( if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail2; + goto fail3; } + EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload); + return (0); +fail3: + EFSYS_PROBE(fail3); + EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload); fail2: EFSYS_PROBE(fail2); fail1: @@ -944,16 +965,16 @@ efx_mcdi_nvram_update_finish( __in efx_nic_t *enp, __in uint32_t partn, __in boolean_t reboot, + __in uint32_t flags, __out_opt uint32_t *verify_resultp) { const efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN, - MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN, + MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN); uint32_t verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN; - efx_rc_t rc; + efx_rc_t rc = 0; - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN; @@ -963,8 +984,19 @@ efx_mcdi_nvram_update_finish( MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_TYPE, partn); MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_REBOOT, reboot); - MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_FINISH_V2_IN_FLAGS, - NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1); + if (!encp->enc_nvram_update_poll_verify_result_supported) { + flags &= ~EFX_NVRAM_UPDATE_FLAGS_BACKGROUND; + flags &= ~EFX_NVRAM_UPDATE_FLAGS_POLL; + } + + MCDI_IN_POPULATE_DWORD_3(req, NVRAM_UPDATE_FINISH_V2_IN_FLAGS, + NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT, + 1, + NVRAM_UPDATE_FINISH_V2_IN_FLAG_RUN_IN_BACKGROUND, + (flags & EFX_NVRAM_UPDATE_FLAGS_BACKGROUND) ? 1 : 0, + NVRAM_UPDATE_FINISH_V2_IN_FLAG_POLL_VERIFY_RESULT, + (flags & EFX_NVRAM_UPDATE_FLAGS_POLL) ? 1 : 0 + ); efx_mcdi_execute(enp, &req); @@ -985,11 +1017,13 @@ efx_mcdi_nvram_update_finish( MCDI_OUT_DWORD(req, NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE); } - if ((encp->enc_nvram_update_verify_result_supported) && - (verify_result != MC_CMD_NVRAM_VERIFY_RC_SUCCESS)) { - /* Update verification failed */ - rc = EINVAL; - goto fail3; + if (encp->enc_nvram_update_verify_result_supported) { + if ((verify_result != MC_CMD_NVRAM_VERIFY_RC_SUCCESS) && + (verify_result != MC_CMD_NVRAM_VERIFY_RC_PENDING)) { + /* Update verification failed */ + rc = EINVAL; + goto fail3; + } } if (verify_resultp != NULL) @@ -1019,12 +1053,11 @@ efx_mcdi_nvram_test( __in uint32_t partn) { efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN, - MC_CMD_NVRAM_TEST_OUT_LEN)]; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TEST_IN_LEN, + MC_CMD_NVRAM_TEST_OUT_LEN); int result; efx_rc_t rc; - (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_NVRAM_TEST; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;