net/bonding: use non deprecated PCI API
[dpdk.git] / drivers / net / sfc / base / efx_nvram.c
index 6bd7fc2..5e7236c 100644 (file)
@@ -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;