From: Richard Houldsworth <rhouldswo...@solarflare.com>

All signed images other than for the MCFW partition should
be written fully to the partition with no rearrangement.

Signed-off-by: Richard Houldsworth <rhouldswo...@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybche...@solarflare.com>
---
 drivers/net/sfc/base/ef10_image.c | 74 ++++++++++++++++++++++++---------------
 drivers/net/sfc/base/efx.h        |  1 +
 2 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_image.c 
b/drivers/net/sfc/base/ef10_image.c
index c035e0d..a19df7f 100644
--- a/drivers/net/sfc/base/ef10_image.c
+++ b/drivers/net/sfc/base/ef10_image.c
@@ -7,6 +7,8 @@
 #include "efx.h"
 #include "efx_impl.h"
 
+#include "ef10_firmware_ids.h"
+
 #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
 
 #if EFSYS_OPT_IMAGE_LAYOUT
@@ -429,54 +431,59 @@
 
 static __checkReturn   efx_rc_t
 efx_check_unsigned_image(
-       __in            void            *bufferp,
-       __in            uint32_t        buffer_size)
+       __in            void                    *bufferp,
+       __in            uint32_t                buffer_size,
+       __out           efx_image_header_t      **headerpp,
+       __out           efx_image_trailer_t     **trailerpp)
 {
-       efx_image_header_t *header;
-       efx_image_trailer_t *trailer;
+       efx_image_header_t *headerp;
+       efx_image_trailer_t *trailerp;
        uint32_t crc;
        efx_rc_t rc;
 
-       EFX_STATIC_ASSERT(sizeof (*header) == EFX_IMAGE_HEADER_SIZE);
-       EFX_STATIC_ASSERT(sizeof (*trailer) == EFX_IMAGE_TRAILER_SIZE);
+       EFX_STATIC_ASSERT(sizeof (*headerp) == EFX_IMAGE_HEADER_SIZE);
+       EFX_STATIC_ASSERT(sizeof (*trailerp) == EFX_IMAGE_TRAILER_SIZE);
 
        /* Must have at least enough space for required image header fields */
        if (buffer_size < (EFX_FIELD_OFFSET(efx_image_header_t, eih_size) +
-               sizeof (header->eih_size))) {
+               sizeof (headerp->eih_size))) {
                rc = ENOSPC;
                goto fail1;
        }
-       header = (efx_image_header_t *)bufferp;
+       headerp = (efx_image_header_t *)bufferp;
 
-       if (header->eih_magic != EFX_IMAGE_HEADER_MAGIC) {
-               rc = EINVAL;
+       /* Buffer must have space for image header, code and image trailer. */
+       if (buffer_size < (headerp->eih_size + headerp->eih_code_size +
+               EFX_IMAGE_TRAILER_SIZE)) {
+               rc = ENOSPC;
                goto fail2;
        }
 
+       trailerp = (efx_image_trailer_t *)((uint8_t *)headerp +
+           headerp->eih_size + headerp->eih_code_size);
+
+       *headerpp = headerp;
+       *trailerpp = trailerp;
+
+       if (headerp->eih_magic != EFX_IMAGE_HEADER_MAGIC) {
+               rc = EINVAL;
+               goto fail3;
+       }
+
        /*
         * Check image header version is same or higher than lowest required
         * version.
         */
-       if (header->eih_version < EFX_IMAGE_HEADER_VERSION) {
+       if (headerp->eih_version < EFX_IMAGE_HEADER_VERSION) {
                rc = EINVAL;
-               goto fail3;
-       }
-
-       /* Buffer must have space for image header, code and image trailer. */
-       if (buffer_size < (header->eih_size + header->eih_code_size +
-               EFX_IMAGE_TRAILER_SIZE)) {
-               rc = ENOSPC;
                goto fail4;
        }
 
        /* Check CRC from image buffer matches computed CRC. */
-       trailer = (efx_image_trailer_t *)((uint8_t *)header +
-           header->eih_size + header->eih_code_size);
+       crc = efx_crc32_calculate(0, (uint8_t *)headerp,
+           (headerp->eih_size + headerp->eih_code_size));
 
-       crc = efx_crc32_calculate(0, (uint8_t *)header,
-           (header->eih_size + header->eih_code_size));
-
-       if (trailer->eit_crc != crc) {
+       if (trailerp->eit_crc != crc) {
                rc = EINVAL;
                goto fail5;
        }
@@ -507,9 +514,10 @@
        uint32_t image_offset;
        uint32_t image_size;
        void *imagep;
+       efx_image_header_t *headerp;
+       efx_image_trailer_t *trailerp;
        efx_rc_t rc;
 
-
        EFSYS_ASSERT(infop != NULL);
        if (infop == NULL) {
                rc = EINVAL;
@@ -531,7 +539,7 @@
        if (rc == 0) {
                /*
                 * Buffer holds signed image format. Check that the encapsulated
-                * content is in unsigned image format.
+                * content contains an unsigned image format header.
                 */
                format = EFX_IMAGE_FORMAT_SIGNED;
        } else {
@@ -546,11 +554,21 @@
        }
        imagep = (uint8_t *)bufferp + image_offset;
 
-       /* Check unsigned image layout (image header, code, image trailer) */
-       rc = efx_check_unsigned_image(imagep, image_size);
+       /* Check image layout (image header, code, image trailer) */
+       rc = efx_check_unsigned_image(imagep, image_size, &headerp, &trailerp);
        if (rc != 0)
                goto fail4;
 
+       /*
+        * Signed images are packages consumed directly by the firmware,
+        * with the exception of MC firmware, where the image must be
+        * rearranged for booting purposes.
+        */
+       if (format == EFX_IMAGE_FORMAT_SIGNED) {
+               if (headerp->eih_type != FIRMWARE_TYPE_MCFW)
+                       format = EFX_IMAGE_FORMAT_SIGNED_PACKAGE;
+       }
+
        /* Return image details */
        infop->eii_format = format;
        infop->eii_imagep = bufferp;
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 4905918..d46e650 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1889,6 +1889,7 @@ enum {
        EFX_IMAGE_FORMAT_INVALID,
        EFX_IMAGE_FORMAT_UNSIGNED,
        EFX_IMAGE_FORMAT_SIGNED,
+       EFX_IMAGE_FORMAT_SIGNED_PACKAGE
 } efx_image_format_t;
 
 typedef struct efx_image_info_s {
-- 
1.8.3.1

Reply via email to