|
@@ -1111,7 +1111,8 @@ static int be_vid_config(struct be_adapter *adapter)
|
|
|
status = be_cmd_vlan_config(adapter, adapter->if_handle, vids, num);
|
|
|
if (status) {
|
|
|
/* Set to VLAN promisc mode as setting VLAN filter failed */
|
|
|
- if (status == MCC_ADDL_STS_INSUFFICIENT_RESOURCES)
|
|
|
+ if (addl_status(status) ==
|
|
|
+ MCC_ADDL_STATUS_INSUFFICIENT_RESOURCES)
|
|
|
goto set_vlan_promisc;
|
|
|
dev_err(&adapter->pdev->dev,
|
|
|
"Setting HW VLAN filtering failed.\n");
|
|
@@ -1190,7 +1191,7 @@ ret:
|
|
|
static void be_clear_promisc(struct be_adapter *adapter)
|
|
|
{
|
|
|
adapter->promiscuous = false;
|
|
|
- adapter->flags &= ~BE_FLAGS_VLAN_PROMISC;
|
|
|
+ adapter->flags &= ~(BE_FLAGS_VLAN_PROMISC | BE_FLAGS_MCAST_PROMISC);
|
|
|
|
|
|
be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
|
|
|
}
|
|
@@ -1215,10 +1216,8 @@ static void be_set_rx_mode(struct net_device *netdev)
|
|
|
|
|
|
/* Enable multicast promisc if num configured exceeds what we support */
|
|
|
if (netdev->flags & IFF_ALLMULTI ||
|
|
|
- netdev_mc_count(netdev) > be_max_mc(adapter)) {
|
|
|
- be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
|
|
|
- goto done;
|
|
|
- }
|
|
|
+ netdev_mc_count(netdev) > be_max_mc(adapter))
|
|
|
+ goto set_mcast_promisc;
|
|
|
|
|
|
if (netdev_uc_count(netdev) != adapter->uc_macs) {
|
|
|
struct netdev_hw_addr *ha;
|
|
@@ -1244,15 +1243,22 @@ static void be_set_rx_mode(struct net_device *netdev)
|
|
|
}
|
|
|
|
|
|
status = be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
|
|
|
-
|
|
|
- /* Set to MCAST promisc mode if setting MULTICAST address fails */
|
|
|
- if (status) {
|
|
|
- dev_info(&adapter->pdev->dev,
|
|
|
- "Exhausted multicast HW filters.\n");
|
|
|
- dev_info(&adapter->pdev->dev,
|
|
|
- "Disabling HW multicast filtering.\n");
|
|
|
- be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
|
|
|
+ if (!status) {
|
|
|
+ if (adapter->flags & BE_FLAGS_MCAST_PROMISC)
|
|
|
+ adapter->flags &= ~BE_FLAGS_MCAST_PROMISC;
|
|
|
+ goto done;
|
|
|
}
|
|
|
+
|
|
|
+set_mcast_promisc:
|
|
|
+ if (adapter->flags & BE_FLAGS_MCAST_PROMISC)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Set to MCAST promisc mode if setting MULTICAST address fails
|
|
|
+ * or if num configured exceeds what we support
|
|
|
+ */
|
|
|
+ status = be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
|
|
|
+ if (!status)
|
|
|
+ adapter->flags |= BE_FLAGS_MCAST_PROMISC;
|
|
|
done:
|
|
|
return;
|
|
|
}
|
|
@@ -1347,7 +1353,10 @@ static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
|
|
|
int min_tx_rate, int max_tx_rate)
|
|
|
{
|
|
|
struct be_adapter *adapter = netdev_priv(netdev);
|
|
|
- int status = 0;
|
|
|
+ struct device *dev = &adapter->pdev->dev;
|
|
|
+ int percent_rate, status = 0;
|
|
|
+ u16 link_speed = 0;
|
|
|
+ u8 link_status;
|
|
|
|
|
|
if (!sriov_enabled(adapter))
|
|
|
return -EPERM;
|
|
@@ -1358,18 +1367,47 @@ static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
|
|
|
if (min_tx_rate)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (max_tx_rate < 100 || max_tx_rate > 10000) {
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
- "max tx rate must be between 100 and 10000 Mbps\n");
|
|
|
- return -EINVAL;
|
|
|
+ if (!max_tx_rate)
|
|
|
+ goto config_qos;
|
|
|
+
|
|
|
+ status = be_cmd_link_status_query(adapter, &link_speed,
|
|
|
+ &link_status, 0);
|
|
|
+ if (status)
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ if (!link_status) {
|
|
|
+ dev_err(dev, "TX-rate setting not allowed when link is down\n");
|
|
|
+ status = -EPERM;
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (max_tx_rate < 100 || max_tx_rate > link_speed) {
|
|
|
+ dev_err(dev, "TX-rate must be between 100 and %d Mbps\n",
|
|
|
+ link_speed);
|
|
|
+ status = -EINVAL;
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* On Skyhawk the QOS setting must be done only as a % value */
|
|
|
+ percent_rate = link_speed / 100;
|
|
|
+ if (skyhawk_chip(adapter) && (max_tx_rate % percent_rate)) {
|
|
|
+ dev_err(dev, "TX-rate must be a multiple of %d Mbps\n",
|
|
|
+ percent_rate);
|
|
|
+ status = -EINVAL;
|
|
|
+ goto err;
|
|
|
}
|
|
|
|
|
|
- status = be_cmd_config_qos(adapter, max_tx_rate / 10, vf + 1);
|
|
|
+config_qos:
|
|
|
+ status = be_cmd_config_qos(adapter, max_tx_rate, link_speed, vf + 1);
|
|
|
if (status)
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
- "max tx rate %d on VF %d failed\n", max_tx_rate, vf);
|
|
|
- else
|
|
|
- adapter->vf_cfg[vf].tx_rate = max_tx_rate;
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ adapter->vf_cfg[vf].tx_rate = max_tx_rate;
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err:
|
|
|
+ dev_err(dev, "TX-rate setting of %dMbps on VF%d failed\n",
|
|
|
+ max_tx_rate, vf);
|
|
|
return status;
|
|
|
}
|
|
|
static int be_set_vf_link_state(struct net_device *netdev, int vf,
|
|
@@ -3130,7 +3168,6 @@ static int be_vf_setup(struct be_adapter *adapter)
|
|
|
struct be_vf_cfg *vf_cfg;
|
|
|
int status, old_vfs, vf;
|
|
|
u32 privileges;
|
|
|
- u16 lnk_speed;
|
|
|
|
|
|
old_vfs = pci_num_vf(adapter->pdev);
|
|
|
if (old_vfs) {
|
|
@@ -3186,16 +3223,9 @@ static int be_vf_setup(struct be_adapter *adapter)
|
|
|
vf);
|
|
|
}
|
|
|
|
|
|
- /* BE3 FW, by default, caps VF TX-rate to 100mbps.
|
|
|
- * Allow full available bandwidth
|
|
|
- */
|
|
|
- if (BE3_chip(adapter) && !old_vfs)
|
|
|
- be_cmd_config_qos(adapter, 1000, vf + 1);
|
|
|
-
|
|
|
- status = be_cmd_link_status_query(adapter, &lnk_speed,
|
|
|
- NULL, vf + 1);
|
|
|
- if (!status)
|
|
|
- vf_cfg->tx_rate = lnk_speed;
|
|
|
+ /* Allow full available bandwidth */
|
|
|
+ if (!old_vfs)
|
|
|
+ be_cmd_config_qos(adapter, 0, 0, vf + 1);
|
|
|
|
|
|
if (!old_vfs) {
|
|
|
be_cmd_enable_vf(adapter, vf + 1);
|
|
@@ -3601,34 +3631,7 @@ static void be_netpoll(struct net_device *netdev)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#define FW_FILE_HDR_SIGN "ServerEngines Corp. "
|
|
|
-static 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)
|
|
|
-{
|
|
|
- u32 crc_offset;
|
|
|
- u8 flashed_crc[4];
|
|
|
- int status;
|
|
|
-
|
|
|
- crc_offset = hdr_size + img_start + image_size - 4;
|
|
|
-
|
|
|
- p += crc_offset;
|
|
|
-
|
|
|
- status = be_cmd_get_flash_crc(adapter, flashed_crc, (image_size - 4));
|
|
|
- if (status) {
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
- "could not get crc from flash, not flashing redboot\n");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- /*update redboot only if crc does not match*/
|
|
|
- if (!memcmp(flashed_crc, p, 4))
|
|
|
- return false;
|
|
|
- else
|
|
|
- return true;
|
|
|
-}
|
|
|
+static char flash_cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
|
|
|
|
|
|
static bool phy_flashing_required(struct be_adapter *adapter)
|
|
|
{
|
|
@@ -3675,12 +3678,35 @@ static struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static int be_check_flash_crc(struct be_adapter *adapter, const u8 *p,
|
|
|
+ u32 img_offset, u32 img_size, int hdr_size,
|
|
|
+ u16 img_optype, bool *crc_match)
|
|
|
+{
|
|
|
+ u32 crc_offset;
|
|
|
+ int status;
|
|
|
+ u8 crc[4];
|
|
|
+
|
|
|
+ status = be_cmd_get_flash_crc(adapter, crc, img_optype, img_size - 4);
|
|
|
+ if (status)
|
|
|
+ return status;
|
|
|
+
|
|
|
+ crc_offset = hdr_size + img_offset + img_size - 4;
|
|
|
+
|
|
|
+ /* Skip flashing, if crc of flashed region matches */
|
|
|
+ if (!memcmp(crc, p + crc_offset, 4))
|
|
|
+ *crc_match = true;
|
|
|
+ else
|
|
|
+ *crc_match = false;
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
static int be_flash(struct be_adapter *adapter, const u8 *img,
|
|
|
struct be_dma_mem *flash_cmd, int optype, int img_size)
|
|
|
{
|
|
|
- u32 total_bytes = 0, flash_op, num_bytes = 0;
|
|
|
- int status = 0;
|
|
|
struct be_cmd_write_flashrom *req = flash_cmd->va;
|
|
|
+ u32 total_bytes, flash_op, num_bytes;
|
|
|
+ int status;
|
|
|
|
|
|
total_bytes = img_size;
|
|
|
while (total_bytes) {
|
|
@@ -3704,14 +3730,11 @@ static int be_flash(struct be_adapter *adapter, const u8 *img,
|
|
|
img += num_bytes;
|
|
|
status = be_cmd_write_flashrom(adapter, flash_cmd, optype,
|
|
|
flash_op, num_bytes);
|
|
|
- if (status) {
|
|
|
- if (status == ILLEGAL_IOCTL_REQ &&
|
|
|
- optype == OPTYPE_PHY_FW)
|
|
|
- break;
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
- "cmd to write to flash rom failed.\n");
|
|
|
+ if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST &&
|
|
|
+ optype == OPTYPE_PHY_FW)
|
|
|
+ break;
|
|
|
+ else if (status)
|
|
|
return status;
|
|
|
- }
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -3721,12 +3744,13 @@ static int be_flash_BEx(struct be_adapter *adapter,
|
|
|
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));
|
|
|
- const u8 *p = fw->data;
|
|
|
- const struct flash_comp *pflashcomp;
|
|
|
- int num_comp, redboot;
|
|
|
+ struct device *dev = &adapter->pdev->dev;
|
|
|
struct flash_section_info *fsec = NULL;
|
|
|
+ int status, i, filehdr_size, num_comp;
|
|
|
+ const struct flash_comp *pflashcomp;
|
|
|
+ bool crc_match;
|
|
|
+ const u8 *p;
|
|
|
|
|
|
struct flash_comp gen3_flash_types[] = {
|
|
|
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, OPTYPE_ISCSI_ACTIVE,
|
|
@@ -3783,8 +3807,7 @@ static int be_flash_BEx(struct be_adapter *adapter,
|
|
|
/* 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");
|
|
|
+ dev_err(dev, "Invalid Cookie. FW image may be corrupted\n");
|
|
|
return -1;
|
|
|
}
|
|
|
for (i = 0; i < num_comp; i++) {
|
|
@@ -3800,25 +3823,32 @@ static int be_flash_BEx(struct be_adapter *adapter,
|
|
|
continue;
|
|
|
|
|
|
if (pflashcomp[i].optype == OPTYPE_REDBOOT) {
|
|
|
- redboot = be_flash_redboot(adapter, fw->data,
|
|
|
- pflashcomp[i].offset,
|
|
|
- pflashcomp[i].size,
|
|
|
- filehdr_size +
|
|
|
- img_hdrs_size);
|
|
|
- if (!redboot)
|
|
|
+ status = be_check_flash_crc(adapter, fw->data,
|
|
|
+ pflashcomp[i].offset,
|
|
|
+ pflashcomp[i].size,
|
|
|
+ filehdr_size +
|
|
|
+ img_hdrs_size,
|
|
|
+ OPTYPE_REDBOOT, &crc_match);
|
|
|
+ if (status) {
|
|
|
+ dev_err(dev,
|
|
|
+ "Could not get CRC for 0x%x region\n",
|
|
|
+ pflashcomp[i].optype);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (crc_match)
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- p = fw->data;
|
|
|
- p += filehdr_size + pflashcomp[i].offset + img_hdrs_size;
|
|
|
+ p = fw->data + filehdr_size + pflashcomp[i].offset +
|
|
|
+ img_hdrs_size;
|
|
|
if (p + pflashcomp[i].size > fw->data + fw->size)
|
|
|
return -1;
|
|
|
|
|
|
status = be_flash(adapter, p, flash_cmd, pflashcomp[i].optype,
|
|
|
pflashcomp[i].size);
|
|
|
if (status) {
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
- "Flashing section type %d failed.\n",
|
|
|
+ dev_err(dev, "Flashing section type 0x%x failed\n",
|
|
|
pflashcomp[i].img_type);
|
|
|
return status;
|
|
|
}
|
|
@@ -3826,74 +3856,135 @@ static int be_flash_BEx(struct be_adapter *adapter,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static u16 be_get_img_optype(struct flash_section_entry fsec_entry)
|
|
|
+{
|
|
|
+ u32 img_type = le32_to_cpu(fsec_entry.type);
|
|
|
+ u16 img_optype = le16_to_cpu(fsec_entry.optype);
|
|
|
+
|
|
|
+ if (img_optype != 0xFFFF)
|
|
|
+ return img_optype;
|
|
|
+
|
|
|
+ switch (img_type) {
|
|
|
+ case IMAGE_FIRMWARE_iSCSI:
|
|
|
+ img_optype = OPTYPE_ISCSI_ACTIVE;
|
|
|
+ break;
|
|
|
+ case IMAGE_BOOT_CODE:
|
|
|
+ img_optype = OPTYPE_REDBOOT;
|
|
|
+ break;
|
|
|
+ case IMAGE_OPTION_ROM_ISCSI:
|
|
|
+ img_optype = OPTYPE_BIOS;
|
|
|
+ break;
|
|
|
+ case IMAGE_OPTION_ROM_PXE:
|
|
|
+ img_optype = OPTYPE_PXE_BIOS;
|
|
|
+ break;
|
|
|
+ case IMAGE_OPTION_ROM_FCoE:
|
|
|
+ img_optype = OPTYPE_FCOE_BIOS;
|
|
|
+ break;
|
|
|
+ case IMAGE_FIRMWARE_BACKUP_iSCSI:
|
|
|
+ img_optype = OPTYPE_ISCSI_BACKUP;
|
|
|
+ break;
|
|
|
+ case IMAGE_NCSI:
|
|
|
+ img_optype = OPTYPE_NCSI_FW;
|
|
|
+ break;
|
|
|
+ case IMAGE_FLASHISM_JUMPVECTOR:
|
|
|
+ img_optype = OPTYPE_FLASHISM_JUMPVECTOR;
|
|
|
+ break;
|
|
|
+ case IMAGE_FIRMWARE_PHY:
|
|
|
+ img_optype = OPTYPE_SH_PHY_FW;
|
|
|
+ break;
|
|
|
+ case IMAGE_REDBOOT_DIR:
|
|
|
+ img_optype = OPTYPE_REDBOOT_DIR;
|
|
|
+ break;
|
|
|
+ case IMAGE_REDBOOT_CONFIG:
|
|
|
+ img_optype = OPTYPE_REDBOOT_CONFIG;
|
|
|
+ break;
|
|
|
+ case IMAGE_UFI_DIR:
|
|
|
+ img_optype = OPTYPE_UFI_DIR;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return img_optype;
|
|
|
+}
|
|
|
+
|
|
|
static int be_flash_skyhawk(struct be_adapter *adapter,
|
|
|
const struct firmware *fw,
|
|
|
struct be_dma_mem *flash_cmd, int num_of_images)
|
|
|
{
|
|
|
- int status = 0, i, filehdr_size = 0;
|
|
|
- int img_offset, img_size, img_optype, redboot;
|
|
|
int img_hdrs_size = num_of_images * sizeof(struct image_hdr);
|
|
|
- const u8 *p = fw->data;
|
|
|
+ struct device *dev = &adapter->pdev->dev;
|
|
|
struct flash_section_info *fsec = NULL;
|
|
|
+ u32 img_offset, img_size, img_type;
|
|
|
+ int status, i, filehdr_size;
|
|
|
+ bool crc_match, old_fw_img;
|
|
|
+ u16 img_optype;
|
|
|
+ const u8 *p;
|
|
|
|
|
|
filehdr_size = sizeof(struct flash_file_hdr_g3);
|
|
|
fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
|
|
|
if (!fsec) {
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
- "Invalid Cookie. UFI corrupted ?\n");
|
|
|
+ dev_err(dev, "Invalid Cookie. FW image may be corrupted\n");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < le32_to_cpu(fsec->fsec_hdr.num_images); i++) {
|
|
|
img_offset = le32_to_cpu(fsec->fsec_entry[i].offset);
|
|
|
img_size = le32_to_cpu(fsec->fsec_entry[i].pad_size);
|
|
|
+ img_type = le32_to_cpu(fsec->fsec_entry[i].type);
|
|
|
+ img_optype = be_get_img_optype(fsec->fsec_entry[i]);
|
|
|
+ old_fw_img = fsec->fsec_entry[i].optype == 0xFFFF;
|
|
|
|
|
|
- switch (le32_to_cpu(fsec->fsec_entry[i].type)) {
|
|
|
- case IMAGE_FIRMWARE_iSCSI:
|
|
|
- img_optype = OPTYPE_ISCSI_ACTIVE;
|
|
|
- break;
|
|
|
- case IMAGE_BOOT_CODE:
|
|
|
- img_optype = OPTYPE_REDBOOT;
|
|
|
- break;
|
|
|
- case IMAGE_OPTION_ROM_ISCSI:
|
|
|
- img_optype = OPTYPE_BIOS;
|
|
|
- break;
|
|
|
- case IMAGE_OPTION_ROM_PXE:
|
|
|
- img_optype = OPTYPE_PXE_BIOS;
|
|
|
- break;
|
|
|
- case IMAGE_OPTION_ROM_FCoE:
|
|
|
- img_optype = OPTYPE_FCOE_BIOS;
|
|
|
- break;
|
|
|
- case IMAGE_FIRMWARE_BACKUP_iSCSI:
|
|
|
- img_optype = OPTYPE_ISCSI_BACKUP;
|
|
|
- break;
|
|
|
- case IMAGE_NCSI:
|
|
|
- img_optype = OPTYPE_NCSI_FW;
|
|
|
- break;
|
|
|
- default:
|
|
|
+ if (img_optype == 0xFFFF)
|
|
|
continue;
|
|
|
+ /* Don't bother verifying CRC if an old FW image is being
|
|
|
+ * flashed
|
|
|
+ */
|
|
|
+ if (old_fw_img)
|
|
|
+ goto flash;
|
|
|
+
|
|
|
+ status = be_check_flash_crc(adapter, fw->data, img_offset,
|
|
|
+ img_size, filehdr_size +
|
|
|
+ img_hdrs_size, img_optype,
|
|
|
+ &crc_match);
|
|
|
+ /* The current FW image on the card does not recognize the new
|
|
|
+ * FLASH op_type. The FW download is partially complete.
|
|
|
+ * Reboot the server now to enable FW image to recognize the
|
|
|
+ * new FLASH op_type. To complete the remaining process,
|
|
|
+ * download the same FW again after the reboot.
|
|
|
+ */
|
|
|
+ if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST ||
|
|
|
+ base_status(status) == MCC_STATUS_ILLEGAL_FIELD) {
|
|
|
+ dev_err(dev, "Flash incomplete. Reset the server\n");
|
|
|
+ dev_err(dev, "Download FW image again after reset\n");
|
|
|
+ return -EAGAIN;
|
|
|
+ } else if (status) {
|
|
|
+ dev_err(dev, "Could not get CRC for 0x%x region\n",
|
|
|
+ img_optype);
|
|
|
+ return -EFAULT;
|
|
|
}
|
|
|
|
|
|
- if (img_optype == OPTYPE_REDBOOT) {
|
|
|
- redboot = be_flash_redboot(adapter, fw->data,
|
|
|
- img_offset, img_size,
|
|
|
- filehdr_size +
|
|
|
- img_hdrs_size);
|
|
|
- if (!redboot)
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (crc_match)
|
|
|
+ continue;
|
|
|
|
|
|
- p = fw->data;
|
|
|
- p += filehdr_size + img_offset + img_hdrs_size;
|
|
|
+flash:
|
|
|
+ p = fw->data + filehdr_size + img_offset + img_hdrs_size;
|
|
|
if (p + img_size > fw->data + fw->size)
|
|
|
return -1;
|
|
|
|
|
|
status = be_flash(adapter, p, flash_cmd, img_optype, img_size);
|
|
|
- if (status) {
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
- "Flashing section type %d failed.\n",
|
|
|
- fsec->fsec_entry[i].type);
|
|
|
- return status;
|
|
|
+ /* For old FW images ignore ILLEGAL_FIELD error or errors on
|
|
|
+ * UFI_DIR region
|
|
|
+ */
|
|
|
+ if (old_fw_img &&
|
|
|
+ (base_status(status) == MCC_STATUS_ILLEGAL_FIELD ||
|
|
|
+ (img_optype == OPTYPE_UFI_DIR &&
|
|
|
+ base_status(status) == MCC_STATUS_FAILED))) {
|
|
|
+ continue;
|
|
|
+ } else if (status) {
|
|
|
+ dev_err(dev, "Flashing section type 0x%x failed\n",
|
|
|
+ img_type);
|
|
|
+ return -EFAULT;
|
|
|
}
|
|
|
}
|
|
|
return 0;
|