384 lines
13 KiB
Diff
384 lines
13 KiB
Diff
From: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
|
|
Date: Wed, 25 Apr 2012 01:47:15 +0000
|
|
Subject: [PATCH 50/58] be2net: Fix FW download for BE
|
|
|
|
commit c165541efc4d1024d7db22ecdf64359b1f6107fc upstream.
|
|
|
|
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 | 2 +-
|
|
drivers/net/ethernet/emulex/benet/be_hw.h | 74 ++++++++----
|
|
drivers/net/ethernet/emulex/benet/be_main.c | 168 ++++++++++++++++++---------
|
|
3 files changed, 166 insertions(+), 78 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
|
|
index 2673081..43167e8 100644
|
|
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
|
|
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
|
|
@@ -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);
|
|
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
|
|
index f2c89e3..0949aa6 100644
|
|
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
|
|
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
|
|
@@ -162,22 +162,23 @@
|
|
#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
|
|
@@ -223,6 +224,24 @@
|
|
#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;
|
|
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
|
|
index 9b1c03e..730fb1b 100644
|
|
--- a/drivers/net/ethernet/emulex/benet/be_main.c
|
|
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
|
|
@@ -2751,6 +2751,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)
|
|
@@ -2784,58 +2786,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) {
|
|
@@ -2847,22 +2892,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;
|
|
@@ -2873,12 +2933,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;
|
|
@@ -2890,7 +2950,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");
|
|
--
|
|
1.7.10
|
|
|