0001
0002
0003
0004
0005
0006 #include "iosm_ipc_coredump.h"
0007 #include "iosm_ipc_devlink.h"
0008 #include "iosm_ipc_flash.h"
0009
0010
0011
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
0037
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
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
0094
0095
0096
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
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
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
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
0189
0190
0191
0192
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
0215
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
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
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
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
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
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];
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
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
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
0393
0394
0395
0396
0397
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
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
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
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
0444
0445
0446
0447
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
0501
0502
0503
0504
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 }