Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2020-2021 Intel Corporation.
0004  */
0005 
0006 #include "iosm_ipc_coredump.h"
0007 #include "iosm_ipc_devlink.h"
0008 #include "iosm_ipc_flash.h"
0009 
0010 /* This function will pack the data to be sent to the modem using the
0011  * payload, payload length and pack id
0012  */
0013 static int ipc_flash_proc_format_ebl_pack(struct iosm_flash_data *flash_req,
0014                       u32 pack_length, u16 pack_id,
0015                       u8 *payload, u32 payload_length)
0016 {
0017     u16 checksum = pack_id;
0018     u32 i;
0019 
0020     if (payload_length + IOSM_EBL_HEAD_SIZE > pack_length)
0021         return -EINVAL;
0022 
0023     flash_req->pack_id = cpu_to_le16(pack_id);
0024     flash_req->msg_length = cpu_to_le32(payload_length);
0025     checksum += (payload_length >> IOSM_EBL_PAYL_SHIFT) +
0026              (payload_length & IOSM_EBL_CKSM);
0027 
0028     for (i = 0; i < payload_length; i++)
0029         checksum += payload[i];
0030 
0031     flash_req->checksum = cpu_to_le16(checksum);
0032 
0033     return 0;
0034 }
0035 
0036 /* validate the response received from modem and
0037  * check the type of errors received
0038  */
0039 static int ipc_flash_proc_check_ebl_rsp(void *hdr_rsp, void *payload_rsp)
0040 {
0041     struct iosm_ebl_error  *err_info = payload_rsp;
0042     u16 *rsp_code = hdr_rsp;
0043     u32 i;
0044 
0045     if (*rsp_code == IOSM_EBL_RSP_BUFF) {
0046         for (i = 0; i < IOSM_MAX_ERRORS; i++) {
0047             if (!err_info->error[i].error_code) {
0048                 pr_err("EBL: error_class = %d, error_code = %d",
0049                        err_info->error[i].error_class,
0050                        err_info->error[i].error_code);
0051             }
0052         }
0053         return -EINVAL;
0054     }
0055 
0056     return 0;
0057 }
0058 
0059 /* Send data to the modem */
0060 static int ipc_flash_send_data(struct iosm_devlink *ipc_devlink, u32 size,
0061                    u16 pack_id, u8 *payload, u32 payload_length)
0062 {
0063     struct iosm_flash_data flash_req;
0064     int ret;
0065 
0066     ret = ipc_flash_proc_format_ebl_pack(&flash_req, size,
0067                          pack_id, payload, payload_length);
0068     if (ret) {
0069         dev_err(ipc_devlink->dev, "EBL2 pack failed for pack_id:%d",
0070             pack_id);
0071         goto ipc_free_payload;
0072     }
0073 
0074     ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&flash_req,
0075                      IOSM_EBL_HEAD_SIZE);
0076     if (ret) {
0077         dev_err(ipc_devlink->dev, "EBL Header write failed for Id:%x",
0078             pack_id);
0079         goto ipc_free_payload;
0080     }
0081 
0082     ret = ipc_imem_sys_devlink_write(ipc_devlink, payload, payload_length);
0083     if (ret) {
0084         dev_err(ipc_devlink->dev, "EBL Payload write failed for Id:%x",
0085             pack_id);
0086     }
0087 
0088 ipc_free_payload:
0089     return ret;
0090 }
0091 
0092 /**
0093  * ipc_flash_link_establish - Flash link establishment
0094  * @ipc_imem:           Pointer to struct iosm_imem
0095  *
0096  * Returns:     0 on success and failure value on error
0097  */
0098 int ipc_flash_link_establish(struct iosm_imem *ipc_imem)
0099 {
0100     u8 ler_data[IOSM_LER_RSP_SIZE];
0101     u32 bytes_read;
0102 
0103     /* Allocate channel for flashing/cd collection */
0104     ipc_imem->ipc_devlink->devlink_sio.channel =
0105                     ipc_imem_sys_devlink_open(ipc_imem);
0106 
0107     if (!ipc_imem->ipc_devlink->devlink_sio.channel)
0108         goto chl_open_fail;
0109 
0110     if (ipc_imem_sys_devlink_read(ipc_imem->ipc_devlink, ler_data,
0111                       IOSM_LER_RSP_SIZE, &bytes_read))
0112         goto devlink_read_fail;
0113 
0114     if (bytes_read != IOSM_LER_RSP_SIZE)
0115         goto devlink_read_fail;
0116 
0117     return 0;
0118 
0119 devlink_read_fail:
0120     ipc_imem_sys_devlink_close(ipc_imem->ipc_devlink);
0121 chl_open_fail:
0122     return -EIO;
0123 }
0124 
0125 /* Receive data from the modem */
0126 static int ipc_flash_receive_data(struct iosm_devlink *ipc_devlink, u32 size,
0127                   u8 *mdm_rsp)
0128 {
0129     u8 mdm_rsp_hdr[IOSM_EBL_HEAD_SIZE];
0130     u32 bytes_read;
0131     int ret;
0132 
0133     ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp_hdr,
0134                     IOSM_EBL_HEAD_SIZE, &bytes_read);
0135     if (ret) {
0136         dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
0137             IOSM_EBL_HEAD_SIZE);
0138         goto ipc_flash_recv_err;
0139     }
0140 
0141     if (bytes_read != IOSM_EBL_HEAD_SIZE) {
0142         ret = -EINVAL;
0143         goto ipc_flash_recv_err;
0144     }
0145 
0146     ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp, size,
0147                     &bytes_read);
0148     if (ret) {
0149         dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
0150             size);
0151         goto ipc_flash_recv_err;
0152     }
0153 
0154     if (bytes_read != size) {
0155         ret = -EINVAL;
0156         goto ipc_flash_recv_err;
0157     }
0158 
0159     ret = ipc_flash_proc_check_ebl_rsp(mdm_rsp_hdr + 2, mdm_rsp);
0160 
0161 ipc_flash_recv_err:
0162     return ret;
0163 }
0164 
0165 /* Function to send command to modem and receive response */
0166 static int ipc_flash_send_receive(struct iosm_devlink *ipc_devlink, u16 pack_id,
0167                   u8 *payload, u32 payload_length, u8 *mdm_rsp)
0168 {
0169     size_t frame_len = IOSM_EBL_DW_PACK_SIZE;
0170     int ret;
0171 
0172     if (pack_id == FLASH_SET_PROT_CONF)
0173         frame_len = IOSM_EBL_W_PACK_SIZE;
0174 
0175     ret = ipc_flash_send_data(ipc_devlink, frame_len, pack_id, payload,
0176                   payload_length);
0177     if (ret)
0178         goto ipc_flash_send_rcv;
0179 
0180     ret = ipc_flash_receive_data(ipc_devlink,
0181                      frame_len - IOSM_EBL_HEAD_SIZE, mdm_rsp);
0182 
0183 ipc_flash_send_rcv:
0184     return ret;
0185 }
0186 
0187 /**
0188  * ipc_flash_boot_set_capabilities  - Set modem boot capabilities in flash
0189  * @ipc_devlink:        Pointer to devlink structure
0190  * @mdm_rsp:            Pointer to modem response buffer
0191  *
0192  * Returns:             0 on success and failure value on error
0193  */
0194 int ipc_flash_boot_set_capabilities(struct iosm_devlink *ipc_devlink,
0195                     u8 *mdm_rsp)
0196 {
0197     ipc_devlink->ebl_ctx.ebl_sw_info_version =
0198             ipc_devlink->ebl_ctx.m_ebl_resp[EBL_RSP_SW_INFO_VER];
0199     ipc_devlink->ebl_ctx.m_ebl_resp[EBL_SKIP_ERASE] = IOSM_CAP_NOT_ENHANCED;
0200     ipc_devlink->ebl_ctx.m_ebl_resp[EBL_SKIP_CRC] = IOSM_CAP_NOT_ENHANCED;
0201 
0202     if (ipc_devlink->ebl_ctx.m_ebl_resp[EBL_CAPS_FLAG] &
0203                             IOSM_CAP_USE_EXT_CAP) {
0204         if (ipc_devlink->param.erase_full_flash)
0205             ipc_devlink->ebl_ctx.m_ebl_resp[EBL_OOS_CONFIG] &=
0206                 ~((u8)IOSM_EXT_CAP_ERASE_ALL);
0207         else
0208             ipc_devlink->ebl_ctx.m_ebl_resp[EBL_OOS_CONFIG] &=
0209                 ~((u8)IOSM_EXT_CAP_COMMIT_ALL);
0210         ipc_devlink->ebl_ctx.m_ebl_resp[EBL_EXT_CAPS_HANDLED] =
0211                 IOSM_CAP_USE_EXT_CAP;
0212     }
0213 
0214     /* Write back the EBL capability to modem
0215      * Request Set Protcnf command
0216      */
0217     return ipc_flash_send_receive(ipc_devlink, FLASH_SET_PROT_CONF,
0218                      ipc_devlink->ebl_ctx.m_ebl_resp,
0219                      IOSM_EBL_RSP_SIZE, mdm_rsp);
0220 }
0221 
0222 /* Read the SWID type and SWID value from the EBL */
0223 int ipc_flash_read_swid(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
0224 {
0225     struct iosm_flash_msg_control cmd_msg;
0226     struct iosm_swid_table *swid;
0227     char ebl_swid[IOSM_SWID_STR];
0228     int ret;
0229 
0230     if (ipc_devlink->ebl_ctx.ebl_sw_info_version !=
0231             IOSM_EXT_CAP_SWID_OOS_PACK)
0232         return -EINVAL;
0233 
0234     cmd_msg.action = cpu_to_le32(FLASH_OOSC_ACTION_READ);
0235     cmd_msg.type = cpu_to_le32(FLASH_OOSC_TYPE_SWID_TABLE);
0236     cmd_msg.length = cpu_to_le32(IOSM_MSG_LEN_ARG);
0237     cmd_msg.arguments = cpu_to_le32(IOSM_MSG_LEN_ARG);
0238 
0239     ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
0240                      (u8 *)&cmd_msg, IOSM_MDM_SEND_16, mdm_rsp);
0241     if (ret)
0242         goto ipc_swid_err;
0243 
0244     cmd_msg.action = cpu_to_le32(*((u32 *)mdm_rsp));
0245 
0246     ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_DATA_READ,
0247                      (u8 *)&cmd_msg, IOSM_MDM_SEND_4, mdm_rsp);
0248     if (ret)
0249         goto ipc_swid_err;
0250 
0251     swid = (struct iosm_swid_table *)mdm_rsp;
0252     dev_dbg(ipc_devlink->dev, "SWID %x RF_ENGINE_ID %x", swid->sw_id_val,
0253         swid->rf_engine_id_val);
0254 
0255     snprintf(ebl_swid, sizeof(ebl_swid), "SWID: %x, RF_ENGINE_ID: %x",
0256          swid->sw_id_val, swid->rf_engine_id_val);
0257 
0258     devlink_flash_update_status_notify(ipc_devlink->devlink_ctx, ebl_swid,
0259                        NULL, 0, 0);
0260 ipc_swid_err:
0261     return ret;
0262 }
0263 
0264 /* Function to check if full erase or conditional erase was successful */
0265 static int ipc_flash_erase_check(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
0266 {
0267     int ret, count = 0;
0268     u16 mdm_rsp_data;
0269 
0270     /* Request Flash Erase Check */
0271     do {
0272         mdm_rsp_data = IOSM_MDM_SEND_DATA;
0273         ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_CHECK,
0274                          (u8 *)&mdm_rsp_data,
0275                          IOSM_MDM_SEND_2, mdm_rsp);
0276         if (ret)
0277             goto ipc_erase_chk_err;
0278 
0279         mdm_rsp_data = *((u16 *)mdm_rsp);
0280         if (mdm_rsp_data > IOSM_MDM_ERASE_RSP) {
0281             dev_err(ipc_devlink->dev,
0282                 "Flash Erase Check resp wrong 0x%04X",
0283                 mdm_rsp_data);
0284             ret = -EINVAL;
0285             goto ipc_erase_chk_err;
0286         }
0287         count++;
0288         msleep(IOSM_FLASH_ERASE_CHECK_INTERVAL);
0289     } while ((mdm_rsp_data != IOSM_MDM_ERASE_RSP) &&
0290         (count < (IOSM_FLASH_ERASE_CHECK_TIMEOUT /
0291         IOSM_FLASH_ERASE_CHECK_INTERVAL)));
0292 
0293     if (mdm_rsp_data != IOSM_MDM_ERASE_RSP) {
0294         dev_err(ipc_devlink->dev, "Modem erase check timeout failure!");
0295         ret = -ETIMEDOUT;
0296     }
0297 
0298 ipc_erase_chk_err:
0299     return ret;
0300 }
0301 
0302 /* Full erase function which will erase the nand flash through EBL command */
0303 static int ipc_flash_full_erase(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
0304 {
0305     u32 erase_address = IOSM_ERASE_START_ADDR;
0306     struct iosm_flash_msg_control cmd_msg;
0307     u32 erase_length = IOSM_ERASE_LEN;
0308     int ret;
0309 
0310     dev_dbg(ipc_devlink->dev, "Erase full nand flash");
0311     cmd_msg.action = cpu_to_le32(FLASH_OOSC_ACTION_ERASE);
0312     cmd_msg.type = cpu_to_le32(FLASH_OOSC_TYPE_ALL_FLASH);
0313     cmd_msg.length = cpu_to_le32(erase_length);
0314     cmd_msg.arguments = cpu_to_le32(erase_address);
0315 
0316     ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
0317                      (unsigned char *)&cmd_msg,
0318                      IOSM_MDM_SEND_16, mdm_rsp);
0319     if (ret)
0320         goto ipc_flash_erase_err;
0321 
0322     ipc_devlink->param.erase_full_flash_done = IOSM_SET_FLAG;
0323     ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
0324 
0325 ipc_flash_erase_err:
0326     return ret;
0327 }
0328 
0329 /* Logic for flashing all the Loadmaps available for individual fls file */
0330 static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink,
0331                      const struct firmware *fw, u8 *mdm_rsp)
0332 {
0333     u32 raw_len, rest_len = fw->size - IOSM_DEVLINK_HDR_SIZE;
0334     struct iosm_devlink_image *fls_data;
0335     __le32 reg_info[2]; /* 0th position region address, 1st position size */
0336     u32 nand_address;
0337     char *file_ptr;
0338     int ret;
0339 
0340     fls_data = (struct iosm_devlink_image *)fw->data;
0341     file_ptr = (void *)(fls_data + 1);
0342     nand_address = le32_to_cpu(fls_data->region_address);
0343     reg_info[0] = cpu_to_le32(nand_address);
0344 
0345     if (!ipc_devlink->param.erase_full_flash_done) {
0346         reg_info[1] = cpu_to_le32(nand_address + rest_len - 2);
0347         ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_START,
0348                          (u8 *)reg_info, IOSM_MDM_SEND_8,
0349                          mdm_rsp);
0350         if (ret)
0351             goto dl_region_fail;
0352 
0353         ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
0354         if (ret)
0355             goto dl_region_fail;
0356     }
0357 
0358     /* Request Flash Set Address */
0359     ret = ipc_flash_send_receive(ipc_devlink, FLASH_SET_ADDRESS,
0360                      (u8 *)reg_info, IOSM_MDM_SEND_4, mdm_rsp);
0361     if (ret)
0362         goto dl_region_fail;
0363 
0364     /* Request Flash Write Raw Image */
0365     ret = ipc_flash_send_data(ipc_devlink, IOSM_EBL_DW_PACK_SIZE,
0366                   FLASH_WRITE_IMAGE_RAW, (u8 *)&rest_len,
0367                   IOSM_MDM_SEND_4);
0368     if (ret)
0369         goto dl_region_fail;
0370 
0371     do {
0372         raw_len = (rest_len > IOSM_FLS_BUF_SIZE) ? IOSM_FLS_BUF_SIZE :
0373                 rest_len;
0374         ret = ipc_imem_sys_devlink_write(ipc_devlink, file_ptr,
0375                          raw_len);
0376         if (ret) {
0377             dev_err(ipc_devlink->dev, "Image write failed");
0378             goto dl_region_fail;
0379         }
0380         file_ptr += raw_len;
0381         rest_len -= raw_len;
0382     } while (rest_len);
0383 
0384     ret = ipc_flash_receive_data(ipc_devlink, IOSM_EBL_DW_PAYL_SIZE,
0385                      mdm_rsp);
0386 
0387 dl_region_fail:
0388     return ret;
0389 }
0390 
0391 /**
0392  * ipc_flash_send_fls  - Inject Modem subsystem fls file to device
0393  * @ipc_devlink:        Pointer to devlink structure
0394  * @fw:                 FW image
0395  * @mdm_rsp:            Pointer to modem response buffer
0396  *
0397  * Returns:             0 on success and failure value on error
0398  */
0399 int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
0400                const struct firmware *fw, u8 *mdm_rsp)
0401 {
0402     u32 fw_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
0403     struct iosm_devlink_image *fls_data;
0404     u16 flash_cmd;
0405     int ret;
0406 
0407     fls_data = (struct iosm_devlink_image *)fw->data;
0408     if (ipc_devlink->param.erase_full_flash) {
0409         ipc_devlink->param.erase_full_flash = false;
0410         ret = ipc_flash_full_erase(ipc_devlink, mdm_rsp);
0411         if (ret)
0412             goto ipc_flash_err;
0413     }
0414 
0415     /* Request Sec Start */
0416     if (!fls_data->download_region) {
0417         ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_START,
0418                          (u8 *)fw->data +
0419                          IOSM_DEVLINK_HDR_SIZE, fw_size,
0420                          mdm_rsp);
0421         if (ret)
0422             goto ipc_flash_err;
0423     } else {
0424         /* Download regions */
0425         ret = ipc_flash_download_region(ipc_devlink, fw, mdm_rsp);
0426         if (ret)
0427             goto ipc_flash_err;
0428 
0429         if (fls_data->last_region) {
0430             /* Request Sec End */
0431             flash_cmd = IOSM_MDM_SEND_DATA;
0432             ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_END,
0433                              (u8 *)&flash_cmd,
0434                              IOSM_MDM_SEND_2, mdm_rsp);
0435         }
0436     }
0437 
0438 ipc_flash_err:
0439     return ret;
0440 }
0441 
0442 /**
0443  * ipc_flash_boot_psi - Inject PSI image
0444  * @ipc_devlink:        Pointer to devlink structure
0445  * @fw:                 FW image
0446  *
0447  * Returns:             0 on success and failure value on error
0448  */
0449 int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink,
0450                const struct firmware *fw)
0451 {
0452     u32 bytes_read, psi_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
0453     u8 psi_ack_byte[IOSM_PSI_ACK], read_data[2];
0454     u8 *psi_code;
0455     int ret;
0456 
0457     dev_dbg(ipc_devlink->dev, "Boot transfer PSI");
0458     psi_code = kmemdup(fw->data + IOSM_DEVLINK_HDR_SIZE, psi_size,
0459                GFP_KERNEL);
0460     if (!psi_code)
0461         return -ENOMEM;
0462 
0463     ret = ipc_imem_sys_devlink_write(ipc_devlink, psi_code, psi_size);
0464     if (ret) {
0465         dev_err(ipc_devlink->dev, "RPSI Image write failed");
0466         goto ipc_flash_psi_free;
0467     }
0468 
0469     ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data,
0470                     IOSM_LER_ACK_SIZE, &bytes_read);
0471     if (ret) {
0472         dev_err(ipc_devlink->dev, "ipc_devlink_sio_read ACK failed");
0473         goto ipc_flash_psi_free;
0474     }
0475 
0476     if (bytes_read != IOSM_LER_ACK_SIZE) {
0477         ret = -EINVAL;
0478         goto ipc_flash_psi_free;
0479     }
0480 
0481     snprintf(psi_ack_byte, sizeof(psi_ack_byte), "%x%x", read_data[0],
0482          read_data[1]);
0483     devlink_flash_update_status_notify(ipc_devlink->devlink_ctx,
0484                        psi_ack_byte, "PSI ACK", 0, 0);
0485 
0486     if (read_data[0] == 0x00 && read_data[1] == 0xCD) {
0487         dev_dbg(ipc_devlink->dev, "Coredump detected");
0488         ret = ipc_coredump_get_list(ipc_devlink,
0489                         rpsi_cmd_coredump_start);
0490         if (ret)
0491             dev_err(ipc_devlink->dev, "Failed to get cd list");
0492     }
0493 
0494 ipc_flash_psi_free:
0495     kfree(psi_code);
0496     return ret;
0497 }
0498 
0499 /**
0500  * ipc_flash_boot_ebl  - Inject EBL image
0501  * @ipc_devlink:        Pointer to devlink structure
0502  * @fw:                 FW image
0503  *
0504  * Returns:             0 on success and failure value on error
0505  */
0506 int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink,
0507                const struct firmware *fw)
0508 {
0509     u32 ebl_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
0510     u8 read_data[2];
0511     u32 bytes_read;
0512     int ret;
0513 
0514     if (ipc_mmio_get_exec_stage(ipc_devlink->pcie->imem->mmio) !=
0515                     IPC_MEM_EXEC_STAGE_PSI) {
0516         devlink_flash_update_status_notify(ipc_devlink->devlink_ctx,
0517                            "Invalid execution stage",
0518                            NULL, 0, 0);
0519         return -EINVAL;
0520     }
0521 
0522     dev_dbg(ipc_devlink->dev, "Boot transfer EBL");
0523     ret = ipc_devlink_send_cmd(ipc_devlink, rpsi_cmd_code_ebl,
0524                    IOSM_RPSI_LOAD_SIZE);
0525     if (ret) {
0526         dev_err(ipc_devlink->dev, "Sending rpsi_cmd_code_ebl failed");
0527         goto ipc_flash_ebl_err;
0528     }
0529 
0530     ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
0531                     &bytes_read);
0532     if (ret) {
0533         dev_err(ipc_devlink->dev, "rpsi_cmd_code_ebl read failed");
0534         goto ipc_flash_ebl_err;
0535     }
0536 
0537     if (bytes_read != IOSM_READ_SIZE) {
0538         ret = -EINVAL;
0539         goto ipc_flash_ebl_err;
0540     }
0541 
0542     ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&ebl_size,
0543                      sizeof(ebl_size));
0544     if (ret) {
0545         dev_err(ipc_devlink->dev, "EBL length write failed");
0546         goto ipc_flash_ebl_err;
0547     }
0548 
0549     ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
0550                     &bytes_read);
0551     if (ret) {
0552         dev_err(ipc_devlink->dev, "EBL read failed");
0553         goto ipc_flash_ebl_err;
0554     }
0555 
0556     if (bytes_read != IOSM_READ_SIZE) {
0557         ret = -EINVAL;
0558         goto ipc_flash_ebl_err;
0559     }
0560 
0561     ret = ipc_imem_sys_devlink_write(ipc_devlink,
0562                      (u8 *)fw->data + IOSM_DEVLINK_HDR_SIZE,
0563                      ebl_size);
0564     if (ret) {
0565         dev_err(ipc_devlink->dev, "EBL data transfer failed");
0566         goto ipc_flash_ebl_err;
0567     }
0568 
0569     ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
0570                     &bytes_read);
0571     if (ret) {
0572         dev_err(ipc_devlink->dev, "EBL read failed");
0573         goto ipc_flash_ebl_err;
0574     }
0575 
0576     if (bytes_read != IOSM_READ_SIZE) {
0577         ret = -EINVAL;
0578         goto ipc_flash_ebl_err;
0579     }
0580 
0581     ret = ipc_imem_sys_devlink_read(ipc_devlink,
0582                     ipc_devlink->ebl_ctx.m_ebl_resp,
0583                     IOSM_EBL_RSP_SIZE, &bytes_read);
0584     if (ret) {
0585         dev_err(ipc_devlink->dev, "EBL response read failed");
0586         goto ipc_flash_ebl_err;
0587     }
0588 
0589     if (bytes_read != IOSM_EBL_RSP_SIZE)
0590         ret = -EINVAL;
0591 
0592 ipc_flash_ebl_err:
0593     return ret;
0594 }