sfc_ef100: NVRAM selftest support code
authorEdward Cree <ecree@solarflare.com>
Thu, 2 Jul 2020 16:34:27 +0000 (17:34 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Jul 2020 21:47:40 +0000 (14:47 -0700)
We have yet another new scheme for NVRAM, and a corresponding new MCDI.

Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/mcdi.c
drivers/net/ethernet/sfc/mcdi.h

index 244fb62..6c49740 100644 (file)
@@ -1621,6 +1621,35 @@ fail:
        return rc;
 }
 
+/* This function finds types using the new NVRAM_PARTITIONS mcdi. */
+static int efx_new_mcdi_nvram_types(struct efx_nic *efx, u32 *number,
+                                   u32 *nvram_types)
+{
+       efx_dword_t *outbuf = kzalloc(MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2,
+                                     GFP_KERNEL);
+       size_t outlen;
+       int rc;
+
+       if (!outbuf)
+               return -ENOMEM;
+
+       BUILD_BUG_ON(MC_CMD_NVRAM_PARTITIONS_IN_LEN != 0);
+
+       rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_PARTITIONS, NULL, 0,
+                         outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2, &outlen);
+       if (rc)
+               goto fail;
+
+       *number = MCDI_DWORD(outbuf, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
+
+       memcpy(nvram_types, MCDI_PTR(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID),
+              *number * sizeof(u32));
+
+fail:
+       kfree(outbuf);
+       return rc;
+}
+
 int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
                        size_t *size_out, size_t *erase_size_out,
                        bool *protected_out)
@@ -1674,6 +1703,39 @@ static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type)
        }
 }
 
+/* This function tests nvram partitions using the new mcdi partition lookup scheme */
+int efx_new_mcdi_nvram_test_all(struct efx_nic *efx)
+{
+       u32 *nvram_types = kzalloc(MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2,
+                                  GFP_KERNEL);
+       unsigned int number;
+       int rc, i;
+
+       if (!nvram_types)
+               return -ENOMEM;
+
+       rc = efx_new_mcdi_nvram_types(efx, &number, nvram_types);
+       if (rc)
+               goto fail;
+
+       /* Require at least one check */
+       rc = -EAGAIN;
+
+       for (i = 0; i < number; i++) {
+               if (nvram_types[i] == NVRAM_PARTITION_TYPE_PARTITION_MAP ||
+                   nvram_types[i] == NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG)
+                       continue;
+
+               rc = efx_mcdi_nvram_test(efx, nvram_types[i]);
+               if (rc)
+                       goto fail;
+       }
+
+fail:
+       kfree(nvram_types);
+       return rc;
+}
+
 int efx_mcdi_nvram_test_all(struct efx_nic *efx)
 {
        u32 nvram_types;
index 10f064f..e053adf 100644 (file)
@@ -345,6 +345,7 @@ int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out);
 int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
                        size_t *size_out, size_t *erase_size_out,
                        bool *protected_out);
+int efx_new_mcdi_nvram_test_all(struct efx_nic *efx);
 int efx_mcdi_nvram_test_all(struct efx_nic *efx);
 int efx_mcdi_handle_assertion(struct efx_nic *efx);
 void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);