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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 330 static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink, 331 const struct firmware *fw, u8 *mdm_rsp) 332 { 333 __le32 reg_info[2]; /* 0th position region address, 1st position size */ 334 char *file_ptr; 335 u32 rest_len; 336 u32 raw_len; 337 int ret; 338 339 file_ptr = (char *)fw->data; 340 reg_info[0] = cpu_to_le32(ipc_devlink->param.address); 341 342 if (!ipc_devlink->param.erase_full_flash_done) { 343 reg_info[1] = cpu_to_le32(ipc_devlink->param.address + 344 fw->size - 2); 345 ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_START, 346 (u8 *)reg_info, IOSM_MDM_SEND_8, 347 mdm_rsp); 348 if (ret) 349 goto dl_region_fail; 350 351 ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp); 352 if (ret) 353 goto dl_region_fail; 354 } 355 356 /* Request Flash Set Address */ 357 ret = ipc_flash_send_receive(ipc_devlink, FLASH_SET_ADDRESS, 358 (u8 *)reg_info, IOSM_MDM_SEND_4, mdm_rsp); 359 if (ret) 360 goto dl_region_fail; 361 362 rest_len = fw->size; 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 */ 399 int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink, 400 const struct firmware *fw, u8 *mdm_rsp) 401 { 402 u16 flash_cmd; 403 int ret; 404 405 if (ipc_devlink->param.erase_full_flash) { 406 ipc_devlink->param.erase_full_flash = false; 407 ret = ipc_flash_full_erase(ipc_devlink, mdm_rsp); 408 if (ret) 409 goto ipc_flash_err; 410 } 411 412 /* Request Sec Start */ 413 if (!ipc_devlink->param.download_region) { 414 ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_START, 415 (u8 *)fw->data, fw->size, mdm_rsp); 416 if (ret) 417 goto ipc_flash_err; 418 } else { 419 /* Download regions */ 420 ipc_devlink->param.region_count -= IOSM_SET_FLAG; 421 ret = ipc_flash_download_region(ipc_devlink, fw, mdm_rsp); 422 if (ret) 423 goto ipc_flash_err; 424 425 if (!ipc_devlink->param.region_count) { 426 /* Request Sec End */ 427 flash_cmd = IOSM_MDM_SEND_DATA; 428 ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_END, 429 (u8 *)&flash_cmd, 430 IOSM_MDM_SEND_2, mdm_rsp); 431 } 432 } 433 434 ipc_flash_err: 435 return ret; 436 } 437 438 /** 439 * ipc_flash_boot_psi - Inject PSI image 440 * @ipc_devlink: Pointer to devlink structure 441 * @fw: FW image 442 * 443 * Returns: 0 on success and failure value on error 444 */ 445 int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink, 446 const struct firmware *fw) 447 { 448 u8 psi_ack_byte[IOSM_PSI_ACK], read_data[2]; 449 u32 bytes_read; 450 u8 *psi_code; 451 int ret; 452 453 dev_dbg(ipc_devlink->dev, "Boot transfer PSI"); 454 psi_code = kmemdup(fw->data, fw->size, GFP_KERNEL); 455 if (!psi_code) 456 return -ENOMEM; 457 458 ret = ipc_imem_sys_devlink_write(ipc_devlink, psi_code, fw->size); 459 if (ret) { 460 dev_err(ipc_devlink->dev, "RPSI Image write failed"); 461 goto ipc_flash_psi_free; 462 } 463 464 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, 465 IOSM_LER_ACK_SIZE, &bytes_read); 466 if (ret) { 467 dev_err(ipc_devlink->dev, "ipc_devlink_sio_read ACK failed"); 468 goto ipc_flash_psi_free; 469 } 470 471 if (bytes_read != IOSM_LER_ACK_SIZE) { 472 ret = -EINVAL; 473 goto ipc_flash_psi_free; 474 } 475 476 snprintf(psi_ack_byte, sizeof(psi_ack_byte), "%x%x", read_data[0], 477 read_data[1]); 478 devlink_flash_update_status_notify(ipc_devlink->devlink_ctx, 479 psi_ack_byte, "PSI ACK", 0, 0); 480 481 if (read_data[0] == 0x00 && read_data[1] == 0xCD) { 482 dev_dbg(ipc_devlink->dev, "Coredump detected"); 483 ret = ipc_coredump_get_list(ipc_devlink, 484 rpsi_cmd_coredump_start); 485 if (ret) 486 dev_err(ipc_devlink->dev, "Failed to get cd list"); 487 } 488 489 ipc_flash_psi_free: 490 kfree(psi_code); 491 return ret; 492 } 493 494 /** 495 * ipc_flash_boot_ebl - Inject EBL image 496 * @ipc_devlink: Pointer to devlink structure 497 * @fw: FW image 498 * 499 * Returns: 0 on success and failure value on error 500 */ 501 int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink, 502 const struct firmware *fw) 503 { 504 u32 ebl_size = fw->size; 505 u8 read_data[2]; 506 u32 bytes_read; 507 int ret; 508 509 if (ipc_mmio_get_exec_stage(ipc_devlink->pcie->imem->mmio) != 510 IPC_MEM_EXEC_STAGE_PSI) { 511 devlink_flash_update_status_notify(ipc_devlink->devlink_ctx, 512 "Invalid execution stage", 513 NULL, 0, 0); 514 return -EINVAL; 515 } 516 517 dev_dbg(ipc_devlink->dev, "Boot transfer EBL"); 518 ret = ipc_devlink_send_cmd(ipc_devlink, rpsi_cmd_code_ebl, 519 IOSM_RPSI_LOAD_SIZE); 520 if (ret) { 521 dev_err(ipc_devlink->dev, "Sending rpsi_cmd_code_ebl failed"); 522 goto ipc_flash_ebl_err; 523 } 524 525 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE, 526 &bytes_read); 527 if (ret) { 528 dev_err(ipc_devlink->dev, "rpsi_cmd_code_ebl read failed"); 529 goto ipc_flash_ebl_err; 530 } 531 532 if (bytes_read != IOSM_READ_SIZE) { 533 ret = -EINVAL; 534 goto ipc_flash_ebl_err; 535 } 536 537 ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&ebl_size, 538 sizeof(ebl_size)); 539 if (ret) { 540 dev_err(ipc_devlink->dev, "EBL length write failed"); 541 goto ipc_flash_ebl_err; 542 } 543 544 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE, 545 &bytes_read); 546 if (ret) { 547 dev_err(ipc_devlink->dev, "EBL read failed"); 548 goto ipc_flash_ebl_err; 549 } 550 551 if (bytes_read != IOSM_READ_SIZE) { 552 ret = -EINVAL; 553 goto ipc_flash_ebl_err; 554 } 555 556 ret = ipc_imem_sys_devlink_write(ipc_devlink, (unsigned char *)fw->data, 557 fw->size); 558 if (ret) { 559 dev_err(ipc_devlink->dev, "EBL data transfer failed"); 560 goto ipc_flash_ebl_err; 561 } 562 563 ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE, 564 &bytes_read); 565 if (ret) { 566 dev_err(ipc_devlink->dev, "EBL read failed"); 567 goto ipc_flash_ebl_err; 568 } 569 570 if (bytes_read != IOSM_READ_SIZE) { 571 ret = -EINVAL; 572 goto ipc_flash_ebl_err; 573 } 574 575 ret = ipc_imem_sys_devlink_read(ipc_devlink, 576 ipc_devlink->ebl_ctx.m_ebl_resp, 577 IOSM_EBL_RSP_SIZE, &bytes_read); 578 if (ret) { 579 dev_err(ipc_devlink->dev, "EBL response read failed"); 580 goto ipc_flash_ebl_err; 581 } 582 583 if (bytes_read != IOSM_EBL_RSP_SIZE) 584 ret = -EINVAL; 585 586 ipc_flash_ebl_err: 587 return ret; 588 } 589