1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2020-2021 Intel Corporation.
6 #include "iosm_ipc_coredump.h"
7 #include "iosm_ipc_devlink.h"
8 #include "iosm_ipc_flash.h"
10 /* This function will pack the data to be sent to the modem using the
11 * payload, payload length and pack id
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)
17 u16 checksum = pack_id;
20 if (payload_length + IOSM_EBL_HEAD_SIZE > pack_length)
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);
28 for (i = 0; i < payload_length; i++)
29 checksum += payload[i];
31 flash_req->checksum = cpu_to_le16(checksum);
36 /* validate the response received from modem and
37 * check the type of errors received
39 static int ipc_flash_proc_check_ebl_rsp(void *hdr_rsp, void *payload_rsp)
41 struct iosm_ebl_error *err_info = payload_rsp;
42 u16 *rsp_code = hdr_rsp;
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);
59 /* Send data to the modem */
60 static int ipc_flash_send_data(struct iosm_devlink *ipc_devlink, u32 size,
61 u16 pack_id, u8 *payload, u32 payload_length)
63 struct iosm_flash_data flash_req;
66 ret = ipc_flash_proc_format_ebl_pack(&flash_req, size,
67 pack_id, payload, payload_length);
69 dev_err(ipc_devlink->dev, "EBL2 pack failed for pack_id:%d",
71 goto ipc_free_payload;
74 ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&flash_req,
77 dev_err(ipc_devlink->dev, "EBL Header write failed for Id:%x",
79 goto ipc_free_payload;
82 ret = ipc_imem_sys_devlink_write(ipc_devlink, payload, payload_length);
84 dev_err(ipc_devlink->dev, "EBL Payload write failed for Id:%x",
93 * ipc_flash_link_establish - Flash link establishment
94 * @ipc_imem: Pointer to struct iosm_imem
96 * Returns: 0 on success and failure value on error
98 int ipc_flash_link_establish(struct iosm_imem *ipc_imem)
100 u8 ler_data[IOSM_LER_RSP_SIZE];
103 /* Allocate channel for flashing/cd collection */
104 ipc_imem->ipc_devlink->devlink_sio.channel =
105 ipc_imem_sys_devlink_open(ipc_imem);
107 if (!ipc_imem->ipc_devlink->devlink_sio.channel)
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;
114 if (bytes_read != IOSM_LER_RSP_SIZE)
115 goto devlink_read_fail;
120 ipc_imem_sys_devlink_close(ipc_imem->ipc_devlink);
125 /* Receive data from the modem */
126 static int ipc_flash_receive_data(struct iosm_devlink *ipc_devlink, u32 size,
129 u8 mdm_rsp_hdr[IOSM_EBL_HEAD_SIZE];
133 ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp_hdr,
134 IOSM_EBL_HEAD_SIZE, &bytes_read);
136 dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
138 goto ipc_flash_recv_err;
141 if (bytes_read != IOSM_EBL_HEAD_SIZE) {
143 goto ipc_flash_recv_err;
146 ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp, size,
149 dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
151 goto ipc_flash_recv_err;
154 if (bytes_read != size) {
156 goto ipc_flash_recv_err;
159 ret = ipc_flash_proc_check_ebl_rsp(mdm_rsp_hdr + 2, mdm_rsp);
165 /* Function to send command to modem and receive response */
166 static int ipc_flash_send_receive(struct iosm_devlink *ipc_devlink, u16 pack_id,
167 u8 *payload, u32 payload_length, u8 *mdm_rsp)
169 size_t frame_len = IOSM_EBL_DW_PACK_SIZE;
172 if (pack_id == FLASH_SET_PROT_CONF)
173 frame_len = IOSM_EBL_W_PACK_SIZE;
175 ret = ipc_flash_send_data(ipc_devlink, frame_len, pack_id, payload,
178 goto ipc_flash_send_rcv;
180 ret = ipc_flash_receive_data(ipc_devlink,
181 frame_len - IOSM_EBL_HEAD_SIZE, mdm_rsp);
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
192 * Returns: 0 on success and failure value on error
194 int ipc_flash_boot_set_capabilities(struct iosm_devlink *ipc_devlink,
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;
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);
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;
214 /* Write back the EBL capability to modem
215 * Request Set Protcnf command
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);
222 /* Read the SWID type and SWID value from the EBL */
223 int ipc_flash_read_swid(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
225 struct iosm_flash_msg_control cmd_msg;
226 struct iosm_swid_table *swid;
227 char ebl_swid[IOSM_SWID_STR];
230 if (ipc_devlink->ebl_ctx.ebl_sw_info_version !=
231 IOSM_EXT_CAP_SWID_OOS_PACK)
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);
239 ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
240 (u8 *)&cmd_msg, IOSM_MDM_SEND_16, mdm_rsp);
244 cmd_msg.action = cpu_to_le32(*((u32 *)mdm_rsp));
246 ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_DATA_READ,
247 (u8 *)&cmd_msg, IOSM_MDM_SEND_4, mdm_rsp);
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);
255 snprintf(ebl_swid, sizeof(ebl_swid), "SWID: %x, RF_ENGINE_ID: %x",
256 swid->sw_id_val, swid->rf_engine_id_val);
258 devlink_flash_update_status_notify(ipc_devlink->devlink_ctx, ebl_swid,
264 /* Function to check if full erase or conditional erase was successful */
265 static int ipc_flash_erase_check(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
270 /* Request Flash Erase Check */
272 mdm_rsp_data = IOSM_MDM_SEND_DATA;
273 ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_CHECK,
275 IOSM_MDM_SEND_2, mdm_rsp);
277 goto ipc_erase_chk_err;
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",
285 goto ipc_erase_chk_err;
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)));
293 if (mdm_rsp_data != IOSM_MDM_ERASE_RSP) {
294 dev_err(ipc_devlink->dev, "Modem erase check timeout failure!");
302 /* Full erase function which will erase the nand flash through EBL command */
303 static int ipc_flash_full_erase(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
305 u32 erase_address = IOSM_ERASE_START_ADDR;
306 struct iosm_flash_msg_control cmd_msg;
307 u32 erase_length = IOSM_ERASE_LEN;
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);
316 ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
317 (unsigned char *)&cmd_msg,
318 IOSM_MDM_SEND_16, mdm_rsp);
320 goto ipc_flash_erase_err;
322 ipc_devlink->param.erase_full_flash_done = IOSM_SET_FLAG;
323 ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
329 /* Logic for flashing all the Loadmaps available for individual fls file */
330 static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink,
331 const struct firmware *fw, u8 *mdm_rsp)
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 */
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);
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,
353 ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
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);
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,
372 raw_len = (rest_len > IOSM_FLS_BUF_SIZE) ? IOSM_FLS_BUF_SIZE :
374 ret = ipc_imem_sys_devlink_write(ipc_devlink, file_ptr,
377 dev_err(ipc_devlink->dev, "Image write failed");
384 ret = ipc_flash_receive_data(ipc_devlink, IOSM_EBL_DW_PAYL_SIZE,
392 * ipc_flash_send_fls - Inject Modem subsystem fls file to device
393 * @ipc_devlink: Pointer to devlink structure
395 * @mdm_rsp: Pointer to modem response buffer
397 * Returns: 0 on success and failure value on error
399 int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
400 const struct firmware *fw, u8 *mdm_rsp)
402 u32 fw_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
403 struct iosm_devlink_image *fls_data;
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);
415 /* Request Sec Start */
416 if (!fls_data->download_region) {
417 ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_START,
419 IOSM_DEVLINK_HDR_SIZE, fw_size,
424 /* Download regions */
425 ret = ipc_flash_download_region(ipc_devlink, fw, mdm_rsp);
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,
434 IOSM_MDM_SEND_2, mdm_rsp);
443 * ipc_flash_boot_psi - Inject PSI image
444 * @ipc_devlink: Pointer to devlink structure
447 * Returns: 0 on success and failure value on error
449 int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink,
450 const struct firmware *fw)
452 u32 bytes_read, psi_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
453 u8 psi_ack_byte[IOSM_PSI_ACK], read_data[2];
457 dev_dbg(ipc_devlink->dev, "Boot transfer PSI");
458 psi_code = kmemdup(fw->data + IOSM_DEVLINK_HDR_SIZE, psi_size,
463 ret = ipc_imem_sys_devlink_write(ipc_devlink, psi_code, psi_size);
465 dev_err(ipc_devlink->dev, "RPSI Image write failed");
466 goto ipc_flash_psi_free;
469 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data,
470 IOSM_LER_ACK_SIZE, &bytes_read);
472 dev_err(ipc_devlink->dev, "ipc_devlink_sio_read ACK failed");
473 goto ipc_flash_psi_free;
476 if (bytes_read != IOSM_LER_ACK_SIZE) {
478 goto ipc_flash_psi_free;
481 snprintf(psi_ack_byte, sizeof(psi_ack_byte), "%x%x", read_data[0],
483 devlink_flash_update_status_notify(ipc_devlink->devlink_ctx,
484 psi_ack_byte, "PSI ACK", 0, 0);
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);
491 dev_err(ipc_devlink->dev, "Failed to get cd list");
500 * ipc_flash_boot_ebl - Inject EBL image
501 * @ipc_devlink: Pointer to devlink structure
504 * Returns: 0 on success and failure value on error
506 int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink,
507 const struct firmware *fw)
509 u32 ebl_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
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",
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);
526 dev_err(ipc_devlink->dev, "Sending rpsi_cmd_code_ebl failed");
527 goto ipc_flash_ebl_err;
530 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
533 dev_err(ipc_devlink->dev, "rpsi_cmd_code_ebl read failed");
534 goto ipc_flash_ebl_err;
537 if (bytes_read != IOSM_READ_SIZE) {
539 goto ipc_flash_ebl_err;
542 ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&ebl_size,
545 dev_err(ipc_devlink->dev, "EBL length write failed");
546 goto ipc_flash_ebl_err;
549 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
552 dev_err(ipc_devlink->dev, "EBL read failed");
553 goto ipc_flash_ebl_err;
556 if (bytes_read != IOSM_READ_SIZE) {
558 goto ipc_flash_ebl_err;
561 ret = ipc_imem_sys_devlink_write(ipc_devlink,
562 (u8 *)fw->data + IOSM_DEVLINK_HDR_SIZE,
565 dev_err(ipc_devlink->dev, "EBL data transfer failed");
566 goto ipc_flash_ebl_err;
569 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
572 dev_err(ipc_devlink->dev, "EBL read failed");
573 goto ipc_flash_ebl_err;
576 if (bytes_read != IOSM_READ_SIZE) {
578 goto ipc_flash_ebl_err;
581 ret = ipc_imem_sys_devlink_read(ipc_devlink,
582 ipc_devlink->ebl_ctx.m_ebl_resp,
583 IOSM_EBL_RSP_SIZE, &bytes_read);
585 dev_err(ipc_devlink->dev, "EBL response read failed");
586 goto ipc_flash_ebl_err;
589 if (bytes_read != IOSM_EBL_RSP_SIZE)