be2net: Fix FW download for BE
authorPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Wed, 25 Apr 2012 01:47:15 +0000 (01:47 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 26 Apr 2012 09:03:31 +0000 (05:03 -0400)
Skip flashing a FW component if that component is not present in a
particular FW UFI image.

Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c

index 2673081..43167e8 100644 (file)
@@ -1979,7 +1979,7 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
        be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4, wrb, NULL);
 
-       req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
+       req->params.op_type = cpu_to_le32(OPTYPE_REDBOOT);
        req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
        req->params.offset = cpu_to_le32(offset);
        req->params.data_buf_size = cpu_to_le32(0x4);
index f2c89e3..0949aa6 100644 (file)
 #define QUERY_FAT      1
 
 /* Flashrom related descriptors */
+#define MAX_FLASH_COMP                 32
 #define IMAGE_TYPE_FIRMWARE            160
 #define IMAGE_TYPE_BOOTCODE            224
 #define IMAGE_TYPE_OPTIONROM           32
 
 #define NUM_FLASHDIR_ENTRIES           32
 
-#define IMG_TYPE_ISCSI_ACTIVE          0
-#define IMG_TYPE_REDBOOT               1
-#define IMG_TYPE_BIOS                  2
-#define IMG_TYPE_PXE_BIOS              3
-#define IMG_TYPE_FCOE_BIOS             8
-#define IMG_TYPE_ISCSI_BACKUP          9
-#define IMG_TYPE_FCOE_FW_ACTIVE                10
-#define IMG_TYPE_FCOE_FW_BACKUP        11
-#define IMG_TYPE_NCSI_FW               13
-#define IMG_TYPE_PHY_FW                        99
+#define OPTYPE_ISCSI_ACTIVE            0
+#define OPTYPE_REDBOOT                 1
+#define OPTYPE_BIOS                    2
+#define OPTYPE_PXE_BIOS                        3
+#define OPTYPE_FCOE_BIOS               8
+#define OPTYPE_ISCSI_BACKUP            9
+#define OPTYPE_FCOE_FW_ACTIVE          10
+#define OPTYPE_FCOE_FW_BACKUP          11
+#define OPTYPE_NCSI_FW                 13
+#define OPTYPE_PHY_FW                  99
 #define TN_8022                                13
 
 #define ILLEGAL_IOCTL_REQ              2
 #define FLASH_REDBOOT_START_g3             (262144)
 #define FLASH_PHY_FW_START_g3             1310720
 
+#define IMAGE_NCSI                     16
+#define IMAGE_OPTION_ROM_PXE           32
+#define IMAGE_OPTION_ROM_FCoE          33
+#define IMAGE_OPTION_ROM_ISCSI         34
+#define IMAGE_FLASHISM_JUMPVECTOR      48
+#define IMAGE_FLASH_ISM                        49
+#define IMAGE_JUMP_VECTOR              50
+#define IMAGE_FIRMWARE_iSCSI           160
+#define IMAGE_FIRMWARE_COMP_iSCSI      161
+#define IMAGE_FIRMWARE_FCoE            162
+#define IMAGE_FIRMWARE_COMP_FCoE       163
+#define IMAGE_FIRMWARE_BACKUP_iSCSI    176
+#define IMAGE_FIRMWARE_BACKUP_COMP_iSCSI 177
+#define IMAGE_FIRMWARE_BACKUP_FCoE     178
+#define IMAGE_FIRMWARE_BACKUP_COMP_FCoE 179
+#define IMAGE_FIRMWARE_PHY             192
+#define IMAGE_BOOT_CODE                        224
+
 /************* Rx Packet Type Encoding **************/
 #define BE_UNICAST_PACKET              0
 #define BE_MULTICAST_PACKET            1
@@ -445,6 +464,7 @@ struct flash_comp {
        unsigned long offset;
        int optype;
        int size;
+       int img_type;
 };
 
 struct image_hdr {
@@ -481,17 +501,19 @@ struct flash_section_hdr {
        u32 format_rev;
        u32 cksum;
        u32 antidote;
-       u32 build_no;
-       u8 id_string[64];
-       u32 active_entry_mask;
-       u32 valid_entry_mask;
-       u32 org_content_mask;
-       u32 rsvd0;
-       u32 rsvd1;
-       u32 rsvd2;
-       u32 rsvd3;
-       u32 rsvd4;
-};
+       u32 num_images;
+       u8 id_string[128];
+       u32 rsvd[4];
+} __packed;
+
+struct flash_section_hdr_g2 {
+       u32 format_rev;
+       u32 cksum;
+       u32 antidote;
+       u32 build_num;
+       u8 id_string[128];
+       u32 rsvd[8];
+} __packed;
 
 struct flash_section_entry {
        u32 type;
@@ -503,10 +525,16 @@ struct flash_section_entry {
        u32 rsvd0;
        u32 rsvd1;
        u8 ver_data[32];
-};
+} __packed;
 
 struct flash_section_info {
        u8 cookie[32];
        struct flash_section_hdr fsec_hdr;
        struct flash_section_entry fsec_entry[32];
-};
+} __packed;
+
+struct flash_section_info_g2 {
+       u8 cookie[32];
+       struct flash_section_hdr_g2 fsec_hdr;
+       struct flash_section_entry fsec_entry[32];
+} __packed;
index 8bc9e12..c9f757c 100644 (file)
@@ -2759,6 +2759,8 @@ static void be_netpoll(struct net_device *netdev)
 #endif
 
 #define FW_FILE_HDR_SIGN       "ServerEngines Corp. "
+char flash_cookie[2][16] =      {"*** SE FLAS", "H DIRECTORY *** "};
+
 static bool be_flash_redboot(struct be_adapter *adapter,
                        const u8 *p, u32 img_start, int image_size,
                        int hdr_size)
@@ -2792,58 +2794,101 @@ static bool phy_flashing_required(struct be_adapter *adapter)
                adapter->phy.interface_type == PHY_TYPE_BASET_10GB);
 }
 
+static bool is_comp_in_ufi(struct be_adapter *adapter,
+                          struct flash_section_info *fsec, int type)
+{
+       int i = 0, img_type = 0;
+       struct flash_section_info_g2 *fsec_g2 = NULL;
+
+       if (adapter->generation != BE_GEN3)
+               fsec_g2 = (struct flash_section_info_g2 *)fsec;
+
+       for (i = 0; i < MAX_FLASH_COMP; i++) {
+               if (fsec_g2)
+                       img_type = le32_to_cpu(fsec_g2->fsec_entry[i].type);
+               else
+                       img_type = le32_to_cpu(fsec->fsec_entry[i].type);
+
+               if (img_type == type)
+                       return true;
+       }
+       return false;
+
+}
+
+struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
+                                        int header_size,
+                                        const struct firmware *fw)
+{
+       struct flash_section_info *fsec = NULL;
+       const u8 *p = fw->data;
+
+       p += header_size;
+       while (p < (fw->data + fw->size)) {
+               fsec = (struct flash_section_info *)p;
+               if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie)))
+                       return fsec;
+               p += 32;
+       }
+       return NULL;
+}
+
 static int be_flash_data(struct be_adapter *adapter,
-                       const struct firmware *fw,
-                       struct be_dma_mem *flash_cmd, int num_of_images)
+                        const struct firmware *fw,
+                        struct be_dma_mem *flash_cmd,
+                        int num_of_images)
 
 {
        int status = 0, i, filehdr_size = 0;
+       int img_hdrs_size = (num_of_images * sizeof(struct image_hdr));
        u32 total_bytes = 0, flash_op;
        int num_bytes;
        const u8 *p = fw->data;
        struct be_cmd_write_flashrom *req = flash_cmd->va;
        const struct flash_comp *pflashcomp;
-       int num_comp;
-
-       static const struct flash_comp gen3_flash_types[10] = {
-               { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
-                       FLASH_IMAGE_MAX_SIZE_g3},
-               { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
-                       FLASH_REDBOOT_IMAGE_MAX_SIZE_g3},
-               { FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS,
-                       FLASH_BIOS_IMAGE_MAX_SIZE_g3},
-               { FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS,
-                       FLASH_BIOS_IMAGE_MAX_SIZE_g3},
-               { FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS,
-                       FLASH_BIOS_IMAGE_MAX_SIZE_g3},
-               { FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP,
-                       FLASH_IMAGE_MAX_SIZE_g3},
-               { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
-                       FLASH_IMAGE_MAX_SIZE_g3},
-               { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
-                       FLASH_IMAGE_MAX_SIZE_g3},
-               { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
-                       FLASH_NCSI_IMAGE_MAX_SIZE_g3},
-               { FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
-                       FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
+       int num_comp, hdr_size;
+       struct flash_section_info *fsec = NULL;
+
+       struct flash_comp gen3_flash_types[] = {
+               { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, OPTYPE_ISCSI_ACTIVE,
+                       FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_iSCSI},
+               { FLASH_REDBOOT_START_g3, OPTYPE_REDBOOT,
+                       FLASH_REDBOOT_IMAGE_MAX_SIZE_g3, IMAGE_BOOT_CODE},
+               { FLASH_iSCSI_BIOS_START_g3, OPTYPE_BIOS,
+                       FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_ISCSI},
+               { FLASH_PXE_BIOS_START_g3, OPTYPE_PXE_BIOS,
+                       FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_PXE},
+               { FLASH_FCoE_BIOS_START_g3, OPTYPE_FCOE_BIOS,
+                       FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_FCoE},
+               { FLASH_iSCSI_BACKUP_IMAGE_START_g3, OPTYPE_ISCSI_BACKUP,
+                       FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_iSCSI},
+               { FLASH_FCoE_PRIMARY_IMAGE_START_g3, OPTYPE_FCOE_FW_ACTIVE,
+                       FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_FCoE},
+               { FLASH_FCoE_BACKUP_IMAGE_START_g3, OPTYPE_FCOE_FW_BACKUP,
+                       FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_FCoE},
+               { FLASH_NCSI_START_g3, OPTYPE_NCSI_FW,
+                       FLASH_NCSI_IMAGE_MAX_SIZE_g3, IMAGE_NCSI},
+               { FLASH_PHY_FW_START_g3, OPTYPE_PHY_FW,
+                       FLASH_PHY_FW_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_PHY}
        };
-       static const struct flash_comp gen2_flash_types[8] = {
-               { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
-                       FLASH_IMAGE_MAX_SIZE_g2},
-               { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
-                       FLASH_REDBOOT_IMAGE_MAX_SIZE_g2},
-               { FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS,
-                       FLASH_BIOS_IMAGE_MAX_SIZE_g2},
-               { FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS,
-                       FLASH_BIOS_IMAGE_MAX_SIZE_g2},
-               { FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS,
-                       FLASH_BIOS_IMAGE_MAX_SIZE_g2},
-               { FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP,
-                       FLASH_IMAGE_MAX_SIZE_g2},
-               { FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE,
-                       FLASH_IMAGE_MAX_SIZE_g2},
-               { FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP,
-                        FLASH_IMAGE_MAX_SIZE_g2}
+
+       struct flash_comp gen2_flash_types[] = {
+               { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, OPTYPE_ISCSI_ACTIVE,
+                       FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_iSCSI},
+               { FLASH_REDBOOT_START_g2, OPTYPE_REDBOOT,
+                       FLASH_REDBOOT_IMAGE_MAX_SIZE_g2, IMAGE_BOOT_CODE},
+               { FLASH_iSCSI_BIOS_START_g2, OPTYPE_BIOS,
+                       FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_ISCSI},
+               { FLASH_PXE_BIOS_START_g2, OPTYPE_PXE_BIOS,
+                       FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_PXE},
+               { FLASH_FCoE_BIOS_START_g2, OPTYPE_FCOE_BIOS,
+                       FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_FCoE},
+               { FLASH_iSCSI_BACKUP_IMAGE_START_g2, OPTYPE_ISCSI_BACKUP,
+                       FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_iSCSI},
+               { FLASH_FCoE_PRIMARY_IMAGE_START_g2, OPTYPE_FCOE_FW_ACTIVE,
+                       FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_FCoE},
+               { FLASH_FCoE_BACKUP_IMAGE_START_g2, OPTYPE_FCOE_FW_BACKUP,
+                        FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_FCoE}
        };
 
        if (adapter->generation == BE_GEN3) {
@@ -2855,22 +2900,37 @@ static int be_flash_data(struct be_adapter *adapter,
                filehdr_size = sizeof(struct flash_file_hdr_g2);
                num_comp = ARRAY_SIZE(gen2_flash_types);
        }
+       /* Get flash section info*/
+       fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
+       if (!fsec) {
+               dev_err(&adapter->pdev->dev,
+                       "Invalid Cookie. UFI corrupted ?\n");
+               return -1;
+       }
        for (i = 0; i < num_comp; i++) {
-               if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
-                               memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
+               if (!is_comp_in_ufi(adapter, fsec, pflashcomp[i].img_type))
                        continue;
-               if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
+
+               if ((pflashcomp[i].optype == OPTYPE_NCSI_FW) &&
+                   memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
+                       continue;
+
+               if (pflashcomp[i].optype == OPTYPE_PHY_FW) {
                        if (!phy_flashing_required(adapter))
                                continue;
                }
-               if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
-                       (!be_flash_redboot(adapter, fw->data,
-                       pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
-                       (num_of_images * sizeof(struct image_hdr)))))
+
+               hdr_size = filehdr_size +
+                          (num_of_images * sizeof(struct image_hdr));
+
+               if ((pflashcomp[i].optype == OPTYPE_REDBOOT) &&
+                   (!be_flash_redboot(adapter, fw->data, pflashcomp[i].offset,
+                                      pflashcomp[i].size, hdr_size)))
                        continue;
+
+               /* Flash the component */
                p = fw->data;
-               p += filehdr_size + pflashcomp[i].offset
-                       + (num_of_images * sizeof(struct image_hdr));
+               p += filehdr_size + pflashcomp[i].offset + img_hdrs_size;
                if (p + pflashcomp[i].size > fw->data + fw->size)
                        return -1;
                total_bytes = pflashcomp[i].size;
@@ -2881,12 +2941,12 @@ static int be_flash_data(struct be_adapter *adapter,
                                num_bytes = total_bytes;
                        total_bytes -= num_bytes;
                        if (!total_bytes) {
-                               if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
+                               if (pflashcomp[i].optype == OPTYPE_PHY_FW)
                                        flash_op = FLASHROM_OPER_PHY_FLASH;
                                else
                                        flash_op = FLASHROM_OPER_FLASH;
                        } else {
-                               if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
+                               if (pflashcomp[i].optype == OPTYPE_PHY_FW)
                                        flash_op = FLASHROM_OPER_PHY_SAVE;
                                else
                                        flash_op = FLASHROM_OPER_SAVE;
@@ -2898,7 +2958,7 @@ static int be_flash_data(struct be_adapter *adapter,
                        if (status) {
                                if ((status == ILLEGAL_IOCTL_REQ) &&
                                        (pflashcomp[i].optype ==
-                                               IMG_TYPE_PHY_FW))
+                                               OPTYPE_PHY_FW))
                                        break;
                                dev_err(&adapter->pdev->dev,
                                        "cmd to write to flash rom failed.\n");