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