cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

iosm_ipc_flash.c (16066B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2020-2021 Intel Corporation.
      4 */
      5
      6#include "iosm_ipc_coredump.h"
      7#include "iosm_ipc_devlink.h"
      8#include "iosm_ipc_flash.h"
      9
     10/* This function will pack the data to be sent to the modem using the
     11 * payload, payload length and pack id
     12 */
     13static int ipc_flash_proc_format_ebl_pack(struct iosm_flash_data *flash_req,
     14					  u32 pack_length, u16 pack_id,
     15					  u8 *payload, u32 payload_length)
     16{
     17	u16 checksum = pack_id;
     18	u32 i;
     19
     20	if (payload_length + IOSM_EBL_HEAD_SIZE > pack_length)
     21		return -EINVAL;
     22
     23	flash_req->pack_id = cpu_to_le16(pack_id);
     24	flash_req->msg_length = cpu_to_le32(payload_length);
     25	checksum += (payload_length >> IOSM_EBL_PAYL_SHIFT) +
     26		     (payload_length & IOSM_EBL_CKSM);
     27
     28	for (i = 0; i < payload_length; i++)
     29		checksum += payload[i];
     30
     31	flash_req->checksum = cpu_to_le16(checksum);
     32
     33	return 0;
     34}
     35
     36/* validate the response received from modem and
     37 * check the type of errors received
     38 */
     39static int ipc_flash_proc_check_ebl_rsp(void *hdr_rsp, void *payload_rsp)
     40{
     41	struct iosm_ebl_error  *err_info = payload_rsp;
     42	u16 *rsp_code = hdr_rsp;
     43	u32 i;
     44
     45	if (*rsp_code == IOSM_EBL_RSP_BUFF) {
     46		for (i = 0; i < IOSM_MAX_ERRORS; i++) {
     47			if (!err_info->error[i].error_code) {
     48				pr_err("EBL: error_class = %d, error_code = %d",
     49				       err_info->error[i].error_class,
     50				       err_info->error[i].error_code);
     51			}
     52		}
     53		return -EINVAL;
     54	}
     55
     56	return 0;
     57}
     58
     59/* Send data to the modem */
     60static int ipc_flash_send_data(struct iosm_devlink *ipc_devlink, u32 size,
     61			       u16 pack_id, u8 *payload, u32 payload_length)
     62{
     63	struct iosm_flash_data flash_req;
     64	int ret;
     65
     66	ret = ipc_flash_proc_format_ebl_pack(&flash_req, size,
     67					     pack_id, payload, payload_length);
     68	if (ret) {
     69		dev_err(ipc_devlink->dev, "EBL2 pack failed for pack_id:%d",
     70			pack_id);
     71		goto ipc_free_payload;
     72	}
     73
     74	ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&flash_req,
     75					 IOSM_EBL_HEAD_SIZE);
     76	if (ret) {
     77		dev_err(ipc_devlink->dev, "EBL Header write failed for Id:%x",
     78			pack_id);
     79		goto ipc_free_payload;
     80	}
     81
     82	ret = ipc_imem_sys_devlink_write(ipc_devlink, payload, payload_length);
     83	if (ret) {
     84		dev_err(ipc_devlink->dev, "EBL Payload write failed for Id:%x",
     85			pack_id);
     86	}
     87
     88ipc_free_payload:
     89	return ret;
     90}
     91
     92/**
     93 * ipc_flash_link_establish - Flash link establishment
     94 * @ipc_imem:           Pointer to struct iosm_imem
     95 *
     96 * Returns:     0 on success and failure value on error
     97 */
     98int ipc_flash_link_establish(struct iosm_imem *ipc_imem)
     99{
    100	u8 ler_data[IOSM_LER_RSP_SIZE];
    101	u32 bytes_read;
    102
    103	/* Allocate channel for flashing/cd collection */
    104	ipc_imem->ipc_devlink->devlink_sio.channel =
    105					ipc_imem_sys_devlink_open(ipc_imem);
    106
    107	if (!ipc_imem->ipc_devlink->devlink_sio.channel)
    108		goto chl_open_fail;
    109
    110	if (ipc_imem_sys_devlink_read(ipc_imem->ipc_devlink, ler_data,
    111				      IOSM_LER_RSP_SIZE, &bytes_read))
    112		goto devlink_read_fail;
    113
    114	if (bytes_read != IOSM_LER_RSP_SIZE)
    115		goto devlink_read_fail;
    116
    117	return 0;
    118
    119devlink_read_fail:
    120	ipc_imem_sys_devlink_close(ipc_imem->ipc_devlink);
    121chl_open_fail:
    122	return -EIO;
    123}
    124
    125/* Receive data from the modem */
    126static int ipc_flash_receive_data(struct iosm_devlink *ipc_devlink, u32 size,
    127				  u8 *mdm_rsp)
    128{
    129	u8 mdm_rsp_hdr[IOSM_EBL_HEAD_SIZE];
    130	u32 bytes_read;
    131	int ret;
    132
    133	ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp_hdr,
    134					IOSM_EBL_HEAD_SIZE, &bytes_read);
    135	if (ret) {
    136		dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
    137			IOSM_EBL_HEAD_SIZE);
    138		goto ipc_flash_recv_err;
    139	}
    140
    141	if (bytes_read != IOSM_EBL_HEAD_SIZE) {
    142		ret = -EINVAL;
    143		goto ipc_flash_recv_err;
    144	}
    145
    146	ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp, size,
    147					&bytes_read);
    148	if (ret) {
    149		dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
    150			size);
    151		goto ipc_flash_recv_err;
    152	}
    153
    154	if (bytes_read != size) {
    155		ret = -EINVAL;
    156		goto ipc_flash_recv_err;
    157	}
    158
    159	ret = ipc_flash_proc_check_ebl_rsp(mdm_rsp_hdr + 2, mdm_rsp);
    160
    161ipc_flash_recv_err:
    162	return ret;
    163}
    164
    165/* Function to send command to modem and receive response */
    166static int ipc_flash_send_receive(struct iosm_devlink *ipc_devlink, u16 pack_id,
    167				  u8 *payload, u32 payload_length, u8 *mdm_rsp)
    168{
    169	size_t frame_len = IOSM_EBL_DW_PACK_SIZE;
    170	int ret;
    171
    172	if (pack_id == FLASH_SET_PROT_CONF)
    173		frame_len = IOSM_EBL_W_PACK_SIZE;
    174
    175	ret = ipc_flash_send_data(ipc_devlink, frame_len, pack_id, payload,
    176				  payload_length);
    177	if (ret)
    178		goto ipc_flash_send_rcv;
    179
    180	ret = ipc_flash_receive_data(ipc_devlink,
    181				     frame_len - IOSM_EBL_HEAD_SIZE, mdm_rsp);
    182
    183ipc_flash_send_rcv:
    184	return ret;
    185}
    186
    187/**
    188 * ipc_flash_boot_set_capabilities  - Set modem boot capabilities in flash
    189 * @ipc_devlink:        Pointer to devlink structure
    190 * @mdm_rsp:            Pointer to modem response buffer
    191 *
    192 * Returns:             0 on success and failure value on error
    193 */
    194int ipc_flash_boot_set_capabilities(struct iosm_devlink *ipc_devlink,
    195				    u8 *mdm_rsp)
    196{
    197	ipc_devlink->ebl_ctx.ebl_sw_info_version =
    198			ipc_devlink->ebl_ctx.m_ebl_resp[EBL_RSP_SW_INFO_VER];
    199	ipc_devlink->ebl_ctx.m_ebl_resp[EBL_SKIP_ERASE] = IOSM_CAP_NOT_ENHANCED;
    200	ipc_devlink->ebl_ctx.m_ebl_resp[EBL_SKIP_CRC] = IOSM_CAP_NOT_ENHANCED;
    201
    202	if (ipc_devlink->ebl_ctx.m_ebl_resp[EBL_CAPS_FLAG] &
    203							IOSM_CAP_USE_EXT_CAP) {
    204		if (ipc_devlink->param.erase_full_flash)
    205			ipc_devlink->ebl_ctx.m_ebl_resp[EBL_OOS_CONFIG] &=
    206				~((u8)IOSM_EXT_CAP_ERASE_ALL);
    207		else
    208			ipc_devlink->ebl_ctx.m_ebl_resp[EBL_OOS_CONFIG] &=
    209				~((u8)IOSM_EXT_CAP_COMMIT_ALL);
    210		ipc_devlink->ebl_ctx.m_ebl_resp[EBL_EXT_CAPS_HANDLED] =
    211				IOSM_CAP_USE_EXT_CAP;
    212	}
    213
    214	/* Write back the EBL capability to modem
    215	 * Request Set Protcnf command
    216	 */
    217	return ipc_flash_send_receive(ipc_devlink, FLASH_SET_PROT_CONF,
    218				     ipc_devlink->ebl_ctx.m_ebl_resp,
    219				     IOSM_EBL_RSP_SIZE, mdm_rsp);
    220}
    221
    222/* Read the SWID type and SWID value from the EBL */
    223int ipc_flash_read_swid(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
    224{
    225	struct iosm_flash_msg_control cmd_msg;
    226	struct iosm_swid_table *swid;
    227	char ebl_swid[IOSM_SWID_STR];
    228	int ret;
    229
    230	if (ipc_devlink->ebl_ctx.ebl_sw_info_version !=
    231			IOSM_EXT_CAP_SWID_OOS_PACK)
    232		return -EINVAL;
    233
    234	cmd_msg.action = cpu_to_le32(FLASH_OOSC_ACTION_READ);
    235	cmd_msg.type = cpu_to_le32(FLASH_OOSC_TYPE_SWID_TABLE);
    236	cmd_msg.length = cpu_to_le32(IOSM_MSG_LEN_ARG);
    237	cmd_msg.arguments = cpu_to_le32(IOSM_MSG_LEN_ARG);
    238
    239	ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
    240				     (u8 *)&cmd_msg, IOSM_MDM_SEND_16, mdm_rsp);
    241	if (ret)
    242		goto ipc_swid_err;
    243
    244	cmd_msg.action = cpu_to_le32(*((u32 *)mdm_rsp));
    245
    246	ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_DATA_READ,
    247				     (u8 *)&cmd_msg, IOSM_MDM_SEND_4, mdm_rsp);
    248	if (ret)
    249		goto ipc_swid_err;
    250
    251	swid = (struct iosm_swid_table *)mdm_rsp;
    252	dev_dbg(ipc_devlink->dev, "SWID %x RF_ENGINE_ID %x", swid->sw_id_val,
    253		swid->rf_engine_id_val);
    254
    255	snprintf(ebl_swid, sizeof(ebl_swid), "SWID: %x, RF_ENGINE_ID: %x",
    256		 swid->sw_id_val, swid->rf_engine_id_val);
    257
    258	devlink_flash_update_status_notify(ipc_devlink->devlink_ctx, ebl_swid,
    259					   NULL, 0, 0);
    260ipc_swid_err:
    261	return ret;
    262}
    263
    264/* Function to check if full erase or conditional erase was successful */
    265static int ipc_flash_erase_check(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
    266{
    267	int ret, count = 0;
    268	u16 mdm_rsp_data;
    269
    270	/* Request Flash Erase Check */
    271	do {
    272		mdm_rsp_data = IOSM_MDM_SEND_DATA;
    273		ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_CHECK,
    274					     (u8 *)&mdm_rsp_data,
    275					     IOSM_MDM_SEND_2, mdm_rsp);
    276		if (ret)
    277			goto ipc_erase_chk_err;
    278
    279		mdm_rsp_data = *((u16 *)mdm_rsp);
    280		if (mdm_rsp_data > IOSM_MDM_ERASE_RSP) {
    281			dev_err(ipc_devlink->dev,
    282				"Flash Erase Check resp wrong 0x%04X",
    283				mdm_rsp_data);
    284			ret = -EINVAL;
    285			goto ipc_erase_chk_err;
    286		}
    287		count++;
    288		msleep(IOSM_FLASH_ERASE_CHECK_INTERVAL);
    289	} while ((mdm_rsp_data != IOSM_MDM_ERASE_RSP) &&
    290		(count < (IOSM_FLASH_ERASE_CHECK_TIMEOUT /
    291		IOSM_FLASH_ERASE_CHECK_INTERVAL)));
    292
    293	if (mdm_rsp_data != IOSM_MDM_ERASE_RSP) {
    294		dev_err(ipc_devlink->dev, "Modem erase check timeout failure!");
    295		ret = -ETIMEDOUT;
    296	}
    297
    298ipc_erase_chk_err:
    299	return ret;
    300}
    301
    302/* Full erase function which will erase the nand flash through EBL command */
    303static int ipc_flash_full_erase(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
    304{
    305	u32 erase_address = IOSM_ERASE_START_ADDR;
    306	struct iosm_flash_msg_control cmd_msg;
    307	u32 erase_length = IOSM_ERASE_LEN;
    308	int ret;
    309
    310	dev_dbg(ipc_devlink->dev, "Erase full nand flash");
    311	cmd_msg.action = cpu_to_le32(FLASH_OOSC_ACTION_ERASE);
    312	cmd_msg.type = cpu_to_le32(FLASH_OOSC_TYPE_ALL_FLASH);
    313	cmd_msg.length = cpu_to_le32(erase_length);
    314	cmd_msg.arguments = cpu_to_le32(erase_address);
    315
    316	ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
    317				     (unsigned char *)&cmd_msg,
    318				     IOSM_MDM_SEND_16, mdm_rsp);
    319	if (ret)
    320		goto ipc_flash_erase_err;
    321
    322	ipc_devlink->param.erase_full_flash_done = IOSM_SET_FLAG;
    323	ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
    324
    325ipc_flash_erase_err:
    326	return ret;
    327}
    328
    329/* Logic for flashing all the Loadmaps available for individual fls file */
    330static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink,
    331				     const struct firmware *fw, u8 *mdm_rsp)
    332{
    333	u32 raw_len, rest_len = fw->size - IOSM_DEVLINK_HDR_SIZE;
    334	struct iosm_devlink_image *fls_data;
    335	__le32 reg_info[2]; /* 0th position region address, 1st position size */
    336	u32 nand_address;
    337	char *file_ptr;
    338	int ret;
    339
    340	fls_data = (struct iosm_devlink_image *)fw->data;
    341	file_ptr = (void *)(fls_data + 1);
    342	nand_address = le32_to_cpu(fls_data->region_address);
    343	reg_info[0] = cpu_to_le32(nand_address);
    344
    345	if (!ipc_devlink->param.erase_full_flash_done) {
    346		reg_info[1] = cpu_to_le32(nand_address + rest_len - 2);
    347		ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_START,
    348					     (u8 *)reg_info, IOSM_MDM_SEND_8,
    349					     mdm_rsp);
    350		if (ret)
    351			goto dl_region_fail;
    352
    353		ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
    354		if (ret)
    355			goto dl_region_fail;
    356	}
    357
    358	/* Request Flash Set Address */
    359	ret = ipc_flash_send_receive(ipc_devlink, FLASH_SET_ADDRESS,
    360				     (u8 *)reg_info, IOSM_MDM_SEND_4, mdm_rsp);
    361	if (ret)
    362		goto dl_region_fail;
    363
    364	/* Request Flash Write Raw Image */
    365	ret = ipc_flash_send_data(ipc_devlink, IOSM_EBL_DW_PACK_SIZE,
    366				  FLASH_WRITE_IMAGE_RAW, (u8 *)&rest_len,
    367				  IOSM_MDM_SEND_4);
    368	if (ret)
    369		goto dl_region_fail;
    370
    371	do {
    372		raw_len = (rest_len > IOSM_FLS_BUF_SIZE) ? IOSM_FLS_BUF_SIZE :
    373				rest_len;
    374		ret = ipc_imem_sys_devlink_write(ipc_devlink, file_ptr,
    375						 raw_len);
    376		if (ret) {
    377			dev_err(ipc_devlink->dev, "Image write failed");
    378			goto dl_region_fail;
    379		}
    380		file_ptr += raw_len;
    381		rest_len -= raw_len;
    382	} while (rest_len);
    383
    384	ret = ipc_flash_receive_data(ipc_devlink, IOSM_EBL_DW_PAYL_SIZE,
    385				     mdm_rsp);
    386
    387dl_region_fail:
    388	return ret;
    389}
    390
    391/**
    392 * ipc_flash_send_fls  - Inject Modem subsystem fls file to device
    393 * @ipc_devlink:        Pointer to devlink structure
    394 * @fw:                 FW image
    395 * @mdm_rsp:            Pointer to modem response buffer
    396 *
    397 * Returns:             0 on success and failure value on error
    398 */
    399int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
    400		       const struct firmware *fw, u8 *mdm_rsp)
    401{
    402	u32 fw_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
    403	struct iosm_devlink_image *fls_data;
    404	u16 flash_cmd;
    405	int ret;
    406
    407	fls_data = (struct iosm_devlink_image *)fw->data;
    408	if (ipc_devlink->param.erase_full_flash) {
    409		ipc_devlink->param.erase_full_flash = false;
    410		ret = ipc_flash_full_erase(ipc_devlink, mdm_rsp);
    411		if (ret)
    412			goto ipc_flash_err;
    413	}
    414
    415	/* Request Sec Start */
    416	if (!fls_data->download_region) {
    417		ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_START,
    418					     (u8 *)fw->data +
    419					     IOSM_DEVLINK_HDR_SIZE, fw_size,
    420					     mdm_rsp);
    421		if (ret)
    422			goto ipc_flash_err;
    423	} else {
    424		/* Download regions */
    425		ret = ipc_flash_download_region(ipc_devlink, fw, mdm_rsp);
    426		if (ret)
    427			goto ipc_flash_err;
    428
    429		if (fls_data->last_region) {
    430			/* Request Sec End */
    431			flash_cmd = IOSM_MDM_SEND_DATA;
    432			ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_END,
    433						     (u8 *)&flash_cmd,
    434						     IOSM_MDM_SEND_2, mdm_rsp);
    435		}
    436	}
    437
    438ipc_flash_err:
    439	return ret;
    440}
    441
    442/**
    443 * ipc_flash_boot_psi - Inject PSI image
    444 * @ipc_devlink:        Pointer to devlink structure
    445 * @fw:                 FW image
    446 *
    447 * Returns:             0 on success and failure value on error
    448 */
    449int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink,
    450		       const struct firmware *fw)
    451{
    452	u32 bytes_read, psi_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
    453	u8 psi_ack_byte[IOSM_PSI_ACK], read_data[2];
    454	u8 *psi_code;
    455	int ret;
    456
    457	dev_dbg(ipc_devlink->dev, "Boot transfer PSI");
    458	psi_code = kmemdup(fw->data + IOSM_DEVLINK_HDR_SIZE, psi_size,
    459			   GFP_KERNEL);
    460	if (!psi_code)
    461		return -ENOMEM;
    462
    463	ret = ipc_imem_sys_devlink_write(ipc_devlink, psi_code, psi_size);
    464	if (ret) {
    465		dev_err(ipc_devlink->dev, "RPSI Image write failed");
    466		goto ipc_flash_psi_free;
    467	}
    468
    469	ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data,
    470					IOSM_LER_ACK_SIZE, &bytes_read);
    471	if (ret) {
    472		dev_err(ipc_devlink->dev, "ipc_devlink_sio_read ACK failed");
    473		goto ipc_flash_psi_free;
    474	}
    475
    476	if (bytes_read != IOSM_LER_ACK_SIZE) {
    477		ret = -EINVAL;
    478		goto ipc_flash_psi_free;
    479	}
    480
    481	snprintf(psi_ack_byte, sizeof(psi_ack_byte), "%x%x", read_data[0],
    482		 read_data[1]);
    483	devlink_flash_update_status_notify(ipc_devlink->devlink_ctx,
    484					   psi_ack_byte, "PSI ACK", 0, 0);
    485
    486	if (read_data[0] == 0x00 && read_data[1] == 0xCD) {
    487		dev_dbg(ipc_devlink->dev, "Coredump detected");
    488		ret = ipc_coredump_get_list(ipc_devlink,
    489					    rpsi_cmd_coredump_start);
    490		if (ret)
    491			dev_err(ipc_devlink->dev, "Failed to get cd list");
    492	}
    493
    494ipc_flash_psi_free:
    495	kfree(psi_code);
    496	return ret;
    497}
    498
    499/**
    500 * ipc_flash_boot_ebl  - Inject EBL image
    501 * @ipc_devlink:        Pointer to devlink structure
    502 * @fw:                 FW image
    503 *
    504 * Returns:             0 on success and failure value on error
    505 */
    506int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink,
    507		       const struct firmware *fw)
    508{
    509	u32 ebl_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
    510	u8 read_data[2];
    511	u32 bytes_read;
    512	int ret;
    513
    514	if (ipc_mmio_get_exec_stage(ipc_devlink->pcie->imem->mmio) !=
    515				    IPC_MEM_EXEC_STAGE_PSI) {
    516		devlink_flash_update_status_notify(ipc_devlink->devlink_ctx,
    517						   "Invalid execution stage",
    518						   NULL, 0, 0);
    519		return -EINVAL;
    520	}
    521
    522	dev_dbg(ipc_devlink->dev, "Boot transfer EBL");
    523	ret = ipc_devlink_send_cmd(ipc_devlink, rpsi_cmd_code_ebl,
    524				   IOSM_RPSI_LOAD_SIZE);
    525	if (ret) {
    526		dev_err(ipc_devlink->dev, "Sending rpsi_cmd_code_ebl failed");
    527		goto ipc_flash_ebl_err;
    528	}
    529
    530	ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
    531					&bytes_read);
    532	if (ret) {
    533		dev_err(ipc_devlink->dev, "rpsi_cmd_code_ebl read failed");
    534		goto ipc_flash_ebl_err;
    535	}
    536
    537	if (bytes_read != IOSM_READ_SIZE) {
    538		ret = -EINVAL;
    539		goto ipc_flash_ebl_err;
    540	}
    541
    542	ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&ebl_size,
    543					 sizeof(ebl_size));
    544	if (ret) {
    545		dev_err(ipc_devlink->dev, "EBL length write failed");
    546		goto ipc_flash_ebl_err;
    547	}
    548
    549	ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
    550					&bytes_read);
    551	if (ret) {
    552		dev_err(ipc_devlink->dev, "EBL read failed");
    553		goto ipc_flash_ebl_err;
    554	}
    555
    556	if (bytes_read != IOSM_READ_SIZE) {
    557		ret = -EINVAL;
    558		goto ipc_flash_ebl_err;
    559	}
    560
    561	ret = ipc_imem_sys_devlink_write(ipc_devlink,
    562					 (u8 *)fw->data + IOSM_DEVLINK_HDR_SIZE,
    563					 ebl_size);
    564	if (ret) {
    565		dev_err(ipc_devlink->dev, "EBL data transfer failed");
    566		goto ipc_flash_ebl_err;
    567	}
    568
    569	ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
    570					&bytes_read);
    571	if (ret) {
    572		dev_err(ipc_devlink->dev, "EBL read failed");
    573		goto ipc_flash_ebl_err;
    574	}
    575
    576	if (bytes_read != IOSM_READ_SIZE) {
    577		ret = -EINVAL;
    578		goto ipc_flash_ebl_err;
    579	}
    580
    581	ret = ipc_imem_sys_devlink_read(ipc_devlink,
    582					ipc_devlink->ebl_ctx.m_ebl_resp,
    583					IOSM_EBL_RSP_SIZE, &bytes_read);
    584	if (ret) {
    585		dev_err(ipc_devlink->dev, "EBL response read failed");
    586		goto ipc_flash_ebl_err;
    587	}
    588
    589	if (bytes_read != IOSM_EBL_RSP_SIZE)
    590		ret = -EINVAL;
    591
    592ipc_flash_ebl_err:
    593	return ret;
    594}