|
@@ -2712,7 +2712,6 @@ static int be_flash_data(struct be_adapter *adapter,
|
|
|
"cmd to write to flash rom failed.\n");
|
|
|
return -1;
|
|
|
}
|
|
|
- yield();
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
@@ -2730,32 +2729,98 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int be_load_fw(struct be_adapter *adapter, u8 *func)
|
|
|
+static int lancer_fw_download(struct be_adapter *adapter,
|
|
|
+ const struct firmware *fw)
|
|
|
{
|
|
|
- char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
|
|
|
- const struct firmware *fw;
|
|
|
- struct flash_file_hdr_g2 *fhdr;
|
|
|
- struct flash_file_hdr_g3 *fhdr3;
|
|
|
- struct image_hdr *img_hdr_ptr = NULL;
|
|
|
+#define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024)
|
|
|
+#define LANCER_FW_DOWNLOAD_LOCATION "/prg"
|
|
|
struct be_dma_mem flash_cmd;
|
|
|
- int status, i = 0, num_imgs = 0;
|
|
|
- const u8 *p;
|
|
|
+ struct lancer_cmd_req_write_object *req;
|
|
|
+ const u8 *data_ptr = NULL;
|
|
|
+ u8 *dest_image_ptr = NULL;
|
|
|
+ size_t image_size = 0;
|
|
|
+ u32 chunk_size = 0;
|
|
|
+ u32 data_written = 0;
|
|
|
+ u32 offset = 0;
|
|
|
+ int status = 0;
|
|
|
+ u8 add_status = 0;
|
|
|
|
|
|
- if (!netif_running(adapter->netdev)) {
|
|
|
+ if (!IS_ALIGNED(fw->size, sizeof(u32))) {
|
|
|
dev_err(&adapter->pdev->dev,
|
|
|
- "Firmware load not allowed (interface is down)\n");
|
|
|
- return -EPERM;
|
|
|
+ "FW Image not properly aligned. "
|
|
|
+ "Length must be 4 byte aligned.\n");
|
|
|
+ status = -EINVAL;
|
|
|
+ goto lancer_fw_exit;
|
|
|
}
|
|
|
|
|
|
- strcpy(fw_file, func);
|
|
|
+ flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
|
|
|
+ + LANCER_FW_DOWNLOAD_CHUNK;
|
|
|
+ flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
|
|
|
+ &flash_cmd.dma, GFP_KERNEL);
|
|
|
+ if (!flash_cmd.va) {
|
|
|
+ status = -ENOMEM;
|
|
|
+ dev_err(&adapter->pdev->dev,
|
|
|
+ "Memory allocation failure while flashing\n");
|
|
|
+ goto lancer_fw_exit;
|
|
|
+ }
|
|
|
|
|
|
- status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
|
|
|
- if (status)
|
|
|
- goto fw_exit;
|
|
|
+ req = flash_cmd.va;
|
|
|
+ dest_image_ptr = flash_cmd.va +
|
|
|
+ sizeof(struct lancer_cmd_req_write_object);
|
|
|
+ image_size = fw->size;
|
|
|
+ data_ptr = fw->data;
|
|
|
+
|
|
|
+ while (image_size) {
|
|
|
+ chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK);
|
|
|
+
|
|
|
+ /* Copy the image chunk content. */
|
|
|
+ memcpy(dest_image_ptr, data_ptr, chunk_size);
|
|
|
+
|
|
|
+ status = lancer_cmd_write_object(adapter, &flash_cmd,
|
|
|
+ chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION,
|
|
|
+ &data_written, &add_status);
|
|
|
+
|
|
|
+ if (status)
|
|
|
+ break;
|
|
|
+
|
|
|
+ offset += data_written;
|
|
|
+ data_ptr += data_written;
|
|
|
+ image_size -= data_written;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!status) {
|
|
|
+ /* Commit the FW written */
|
|
|
+ status = lancer_cmd_write_object(adapter, &flash_cmd,
|
|
|
+ 0, offset, LANCER_FW_DOWNLOAD_LOCATION,
|
|
|
+ &data_written, &add_status);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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. "
|
|
|
+ "Status code: 0x%x Additional Status: 0x%x\n",
|
|
|
+ status, add_status);
|
|
|
+ goto lancer_fw_exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
|
|
|
+lancer_fw_exit:
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
|
|
|
+{
|
|
|
+ struct flash_file_hdr_g2 *fhdr;
|
|
|
+ struct flash_file_hdr_g3 *fhdr3;
|
|
|
+ struct image_hdr *img_hdr_ptr = NULL;
|
|
|
+ struct be_dma_mem flash_cmd;
|
|
|
+ const u8 *p;
|
|
|
+ int status = 0, i = 0, num_imgs = 0;
|
|
|
|
|
|
p = fw->data;
|
|
|
fhdr = (struct flash_file_hdr_g2 *) p;
|
|
|
- dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
|
|
|
|
|
|
flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
|
|
|
flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
|
|
@@ -2764,7 +2829,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
|
|
|
status = -ENOMEM;
|
|
|
dev_err(&adapter->pdev->dev,
|
|
|
"Memory allocation failure while flashing\n");
|
|
|
- goto fw_exit;
|
|
|
+ goto be_fw_exit;
|
|
|
}
|
|
|
|
|
|
if ((adapter->generation == BE_GEN3) &&
|
|
@@ -2792,11 +2857,37 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
|
|
|
flash_cmd.dma);
|
|
|
if (status) {
|
|
|
dev_err(&adapter->pdev->dev, "Firmware load error\n");
|
|
|
- goto fw_exit;
|
|
|
+ goto be_fw_exit;
|
|
|
}
|
|
|
|
|
|
dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
|
|
|
|
|
|
+be_fw_exit:
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
|
|
|
+{
|
|
|
+ const struct firmware *fw;
|
|
|
+ int status;
|
|
|
+
|
|
|
+ if (!netif_running(adapter->netdev)) {
|
|
|
+ dev_err(&adapter->pdev->dev,
|
|
|
+ "Firmware load not allowed (interface is down)\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
|
|
|
+ if (status)
|
|
|
+ goto fw_exit;
|
|
|
+
|
|
|
+ dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
|
|
|
+
|
|
|
+ if (lancer_chip(adapter))
|
|
|
+ status = lancer_fw_download(adapter, fw);
|
|
|
+ else
|
|
|
+ status = be_fw_download(adapter, fw);
|
|
|
+
|
|
|
fw_exit:
|
|
|
release_firmware(fw);
|
|
|
return status;
|