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 */
ipc_flash_proc_format_ebl_pack(struct iosm_flash_data * flash_req,u32 pack_length,u16 pack_id,u8 * payload,u32 payload_length)13 static 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 */
ipc_flash_proc_check_ebl_rsp(void * hdr_rsp,void * payload_rsp)39 static 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 */
ipc_flash_send_data(struct iosm_devlink * ipc_devlink,u32 size,u16 pack_id,u8 * payload,u32 payload_length)60 static 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
88 ipc_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 */
ipc_flash_link_establish(struct iosm_imem * ipc_imem)98 int 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
119 devlink_read_fail:
120 ipc_imem_sys_devlink_close(ipc_imem->ipc_devlink);
121 chl_open_fail:
122 return -EIO;
123 }
124
125 /* Receive data from the modem */
ipc_flash_receive_data(struct iosm_devlink * ipc_devlink,u32 size,u8 * mdm_rsp)126 static 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
161 ipc_flash_recv_err:
162 return ret;
163 }
164
165 /* Function to send command to modem and receive response */
ipc_flash_send_receive(struct iosm_devlink * ipc_devlink,u16 pack_id,u8 * payload,u32 payload_length,u8 * mdm_rsp)166 static 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
183 ipc_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 */
ipc_flash_boot_set_capabilities(struct iosm_devlink * ipc_devlink,u8 * mdm_rsp)194 int 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 */
ipc_flash_read_swid(struct iosm_devlink * ipc_devlink,u8 * mdm_rsp)223 int 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);
260 ipc_swid_err:
261 return ret;
262 }
263
264 /* Function to check if full erase or conditional erase was successful */
ipc_flash_erase_check(struct iosm_devlink * ipc_devlink,u8 * mdm_rsp)265 static 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
298 ipc_erase_chk_err:
299 return ret;
300 }
301
302 /* Full erase function which will erase the nand flash through EBL command */
ipc_flash_full_erase(struct iosm_devlink * ipc_devlink,u8 * mdm_rsp)303 static 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
325 ipc_flash_erase_err:
326 return ret;
327 }
328
329 /* Logic for flashing all the Loadmaps available for individual fls file */
ipc_flash_download_region(struct iosm_devlink * ipc_devlink,const struct firmware * fw,u8 * mdm_rsp)330 static 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
387 dl_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 */
ipc_flash_send_fls(struct iosm_devlink * ipc_devlink,const struct firmware * fw,u8 * mdm_rsp)399 int 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
438 ipc_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 */
ipc_flash_boot_psi(struct iosm_devlink * ipc_devlink,const struct firmware * fw)449 int 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
494 ipc_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 */
ipc_flash_boot_ebl(struct iosm_devlink * ipc_devlink,const struct firmware * fw)506 int 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
592 ipc_flash_ebl_err:
593 return ret;
594 }
595