be2net: refactor code that checks flash file compatibility
authorVasundhara Volam <vasundhara.volam@emulex.com>
Fri, 6 Feb 2015 13:18:37 +0000 (08:18 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sun, 8 Feb 2015 06:50:58 +0000 (22:50 -0800)
This patch re-factors the code that checks for flash file compatibility with
the chip type, for better readability, as follows:
- be_get_ufi_type() returns the UFI type from the flash file
- be_check_ufi_compatibility() checks if the UFI type is compatible
  with the adapter/chip that is being flashed

Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_main.c

index c231e45..bed4a32 100644 (file)
@@ -1091,6 +1091,9 @@ struct be_cmd_req_query_fw_cfg {
        u32 rsvd[31];
 };
 
+/* ASIC revisions */
+#define ASIC_REV_B0            0x10
+
 struct be_cmd_resp_query_fw_cfg {
        struct be_cmd_resp_hdr hdr;
        u32 be_config_number;
@@ -1260,6 +1263,11 @@ struct flash_file_hdr_g2 {
        u8 build[24];
 };
 
+/* First letter of the build version of the image */
+#define BLD_STR_UFI_TYPE_BE2   '2'
+#define BLD_STR_UFI_TYPE_BE3   '3'
+#define BLD_STR_UFI_TYPE_SH    '4'
+
 struct flash_file_hdr_g3 {
        u8 sign[52];
        u8 ufi_version[4];
index 1605bd7..2b9e1be 100644 (file)
@@ -4058,6 +4058,7 @@ static int be_flash_BEx(struct be_adapter *adapter,
                pflashcomp = gen2_flash_types;
                filehdr_size = sizeof(struct flash_file_hdr_g2);
                num_comp = ARRAY_SIZE(gen2_flash_types);
+               img_hdrs_size = 0;
        }
 
        /* Get flash section info*/
@@ -4331,98 +4332,99 @@ static int lancer_fw_download(struct be_adapter *adapter,
        return 0;
 }
 
-#define UFI_TYPE2              2
-#define UFI_TYPE3              3
-#define UFI_TYPE3R             10
-#define UFI_TYPE4              4
+#define BE2_UFI                2
+#define BE3_UFI                3
+#define BE3R_UFI       10
+#define SH_UFI         4
+
 static int be_get_ufi_type(struct be_adapter *adapter,
                           struct flash_file_hdr_g3 *fhdr)
 {
-       if (!fhdr)
-               goto be_get_ufi_exit;
+       if (!fhdr) {
+               dev_err(&adapter->pdev->dev, "Invalid FW UFI file");
+               return -1;
+       }
 
-       if (skyhawk_chip(adapter) && fhdr->build[0] == '4')
-               return UFI_TYPE4;
-       else if (BE3_chip(adapter) && fhdr->build[0] == '3') {
-               if (fhdr->asic_type_rev == 0x10)
-                       return UFI_TYPE3R;
-               else
-                       return UFI_TYPE3;
-       } else if (BE2_chip(adapter) && fhdr->build[0] == '2')
-               return UFI_TYPE2;
+       /* First letter of the build version is used to identify
+        * which chip this image file is meant for.
+        */
+       switch (fhdr->build[0]) {
+       case BLD_STR_UFI_TYPE_SH:
+               return SH_UFI;
+       case BLD_STR_UFI_TYPE_BE3:
+               return (fhdr->asic_type_rev == ASIC_REV_B0) ? BE3R_UFI :
+                                                               BE3_UFI;
+       case BLD_STR_UFI_TYPE_BE2:
+               return BE2_UFI;
+       default:
+               return -1;
+       }
+}
 
-be_get_ufi_exit:
-       dev_err(&adapter->pdev->dev,
-               "UFI and Interface are not compatible for flashing\n");
-       return -1;
+/* Check if the flash image file is compatible with the adapter that
+ * is being flashed.
+ * BE3 chips with asic-rev B0 must be flashed only with BE3R_UFI type.
+ */
+static bool be_check_ufi_compatibility(struct be_adapter *adapter,
+                                      struct flash_file_hdr_g3 *fhdr)
+{
+       int ufi_type = be_get_ufi_type(adapter, fhdr);
+
+       switch (ufi_type) {
+       case SH_UFI:
+               return skyhawk_chip(adapter);
+       case BE3R_UFI:
+               return BE3_chip(adapter);
+       case BE3_UFI:
+               return (BE3_chip(adapter) && adapter->asic_rev < ASIC_REV_B0);
+       case BE2_UFI:
+               return BE2_chip(adapter);
+       default:
+               return false;
+       }
 }
 
 static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
 {
+       struct device *dev = &adapter->pdev->dev;
        struct flash_file_hdr_g3 *fhdr3;
-       struct image_hdr *img_hdr_ptr = NULL;
+       struct image_hdr *img_hdr_ptr;
+       int status = 0, i, num_imgs;
        struct be_dma_mem flash_cmd;
-       const u8 *p;
-       int status = 0, i = 0, num_imgs = 0, ufi_type = 0;
 
-       flash_cmd.size = sizeof(struct be_cmd_write_flashrom);
-       flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
-                                         &flash_cmd.dma, GFP_KERNEL);
-       if (!flash_cmd.va) {
-               status = -ENOMEM;
-               goto be_fw_exit;
+       fhdr3 = (struct flash_file_hdr_g3 *)fw->data;
+       if (!be_check_ufi_compatibility(adapter, fhdr3)) {
+               dev_err(dev, "Flash image is not compatible with adapter\n");
+               return -EINVAL;
        }
 
-       p = fw->data;
-       fhdr3 = (struct flash_file_hdr_g3 *)p;
-
-       ufi_type = be_get_ufi_type(adapter, fhdr3);
+       flash_cmd.size = sizeof(struct be_cmd_write_flashrom);
+       flash_cmd.va = dma_alloc_coherent(dev, flash_cmd.size, &flash_cmd.dma,
+                                         GFP_KERNEL);
+       if (!flash_cmd.va)
+               return -ENOMEM;
 
        num_imgs = le32_to_cpu(fhdr3->num_imgs);
        for (i = 0; i < num_imgs; i++) {
                img_hdr_ptr = (struct image_hdr *)(fw->data +
                                (sizeof(struct flash_file_hdr_g3) +
                                 i * sizeof(struct image_hdr)));
-               if (le32_to_cpu(img_hdr_ptr->imageid) == 1) {
-                       switch (ufi_type) {
-                       case UFI_TYPE4:
-                               status = be_flash_skyhawk(adapter, fw,
-                                                         &flash_cmd, num_imgs);
-                               break;
-                       case UFI_TYPE3R:
-                               status = be_flash_BEx(adapter, fw, &flash_cmd,
-                                                     num_imgs);
-                               break;
-                       case UFI_TYPE3:
-                               /* Do not flash this ufi on BE3-R cards */
-                               if (adapter->asic_rev < 0x10)
-                                       status = be_flash_BEx(adapter, fw,
-                                                             &flash_cmd,
-                                                             num_imgs);
-                               else {
-                                       status = -EINVAL;
-                                       dev_err(&adapter->pdev->dev,
-                                               "Can't load BE3 UFI on BE3R\n");
-                               }
-                       }
-               }
-       }
-
-       if (ufi_type == UFI_TYPE2)
-               status = be_flash_BEx(adapter, fw, &flash_cmd, 0);
-       else if (ufi_type == -1)
-               status = -EINVAL;
+               if (!BE2_chip(adapter) &&
+                   le32_to_cpu(img_hdr_ptr->imageid) != 1)
+                       continue;
 
-       dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
-                         flash_cmd.dma);
-       if (status) {
-               dev_err(&adapter->pdev->dev, "Firmware load error\n");
-               goto be_fw_exit;
+               if (skyhawk_chip(adapter))
+                       status = be_flash_skyhawk(adapter, fw, &flash_cmd,
+                                                 num_imgs);
+               else
+                       status = be_flash_BEx(adapter, fw, &flash_cmd,
+                                             num_imgs);
        }
 
-       dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
+       dma_free_coherent(dev, flash_cmd.size, flash_cmd.va, flash_cmd.dma);
+       if (!status)
+               dev_info(dev, "Firmware flashed successfully\n");
 
-be_fw_exit:
        return status;
 }