1*09e7b002SM Chetan Kumar // SPDX-License-Identifier: GPL-2.0-only 2*09e7b002SM Chetan Kumar /* 3*09e7b002SM Chetan Kumar * Copyright (C) 2020-2021 Intel Corporation. 4*09e7b002SM Chetan Kumar */ 5*09e7b002SM Chetan Kumar 6*09e7b002SM Chetan Kumar #include "iosm_ipc_coredump.h" 7*09e7b002SM Chetan Kumar 8*09e7b002SM Chetan Kumar /* Collect coredump data from modem */ 9*09e7b002SM Chetan Kumar int ipc_coredump_collect(struct iosm_devlink *devlink, u8 **data, int entry, 10*09e7b002SM Chetan Kumar u32 region_size) 11*09e7b002SM Chetan Kumar { 12*09e7b002SM Chetan Kumar int ret, bytes_to_read, bytes_read = 0, i = 0; 13*09e7b002SM Chetan Kumar s32 remaining; 14*09e7b002SM Chetan Kumar u8 *data_ptr; 15*09e7b002SM Chetan Kumar 16*09e7b002SM Chetan Kumar data_ptr = vmalloc(region_size); 17*09e7b002SM Chetan Kumar if (!data_ptr) 18*09e7b002SM Chetan Kumar return -ENOMEM; 19*09e7b002SM Chetan Kumar 20*09e7b002SM Chetan Kumar remaining = devlink->cd_file_info[entry].actual_size; 21*09e7b002SM Chetan Kumar ret = ipc_devlink_send_cmd(devlink, rpsi_cmd_coredump_get, entry); 22*09e7b002SM Chetan Kumar if (ret) { 23*09e7b002SM Chetan Kumar dev_err(devlink->dev, "Send coredump_get cmd failed"); 24*09e7b002SM Chetan Kumar goto get_cd_fail; 25*09e7b002SM Chetan Kumar } 26*09e7b002SM Chetan Kumar while (remaining > 0) { 27*09e7b002SM Chetan Kumar bytes_to_read = min(remaining, MAX_DATA_SIZE); 28*09e7b002SM Chetan Kumar bytes_read = 0; 29*09e7b002SM Chetan Kumar ret = ipc_imem_sys_devlink_read(devlink, data_ptr + i, 30*09e7b002SM Chetan Kumar bytes_to_read, &bytes_read); 31*09e7b002SM Chetan Kumar if (ret) { 32*09e7b002SM Chetan Kumar dev_err(devlink->dev, "CD data read failed"); 33*09e7b002SM Chetan Kumar goto get_cd_fail; 34*09e7b002SM Chetan Kumar } 35*09e7b002SM Chetan Kumar remaining -= bytes_read; 36*09e7b002SM Chetan Kumar i += bytes_read; 37*09e7b002SM Chetan Kumar } 38*09e7b002SM Chetan Kumar 39*09e7b002SM Chetan Kumar *data = data_ptr; 40*09e7b002SM Chetan Kumar 41*09e7b002SM Chetan Kumar return ret; 42*09e7b002SM Chetan Kumar get_cd_fail: 43*09e7b002SM Chetan Kumar vfree(data_ptr); 44*09e7b002SM Chetan Kumar return ret; 45*09e7b002SM Chetan Kumar } 46*09e7b002SM Chetan Kumar 47*09e7b002SM Chetan Kumar /* Get coredump list to be collected from modem */ 48*09e7b002SM Chetan Kumar int ipc_coredump_get_list(struct iosm_devlink *devlink, u16 cmd) 49*09e7b002SM Chetan Kumar { 50*09e7b002SM Chetan Kumar u32 byte_read, num_entries, file_size; 51*09e7b002SM Chetan Kumar struct iosm_cd_table *cd_table; 52*09e7b002SM Chetan Kumar u8 size[MAX_SIZE_LEN], i; 53*09e7b002SM Chetan Kumar char *filename; 54*09e7b002SM Chetan Kumar int ret = 0; 55*09e7b002SM Chetan Kumar 56*09e7b002SM Chetan Kumar cd_table = kzalloc(MAX_CD_LIST_SIZE, GFP_KERNEL); 57*09e7b002SM Chetan Kumar if (!cd_table) { 58*09e7b002SM Chetan Kumar ret = -ENOMEM; 59*09e7b002SM Chetan Kumar goto cd_init_fail; 60*09e7b002SM Chetan Kumar } 61*09e7b002SM Chetan Kumar 62*09e7b002SM Chetan Kumar ret = ipc_devlink_send_cmd(devlink, cmd, MAX_CD_LIST_SIZE); 63*09e7b002SM Chetan Kumar if (ret) { 64*09e7b002SM Chetan Kumar dev_err(devlink->dev, "rpsi_cmd_coredump_start failed"); 65*09e7b002SM Chetan Kumar goto cd_init_fail; 66*09e7b002SM Chetan Kumar } 67*09e7b002SM Chetan Kumar 68*09e7b002SM Chetan Kumar ret = ipc_imem_sys_devlink_read(devlink, (u8 *)cd_table, 69*09e7b002SM Chetan Kumar MAX_CD_LIST_SIZE, &byte_read); 70*09e7b002SM Chetan Kumar if (ret) { 71*09e7b002SM Chetan Kumar dev_err(devlink->dev, "Coredump data is invalid"); 72*09e7b002SM Chetan Kumar goto cd_init_fail; 73*09e7b002SM Chetan Kumar } 74*09e7b002SM Chetan Kumar 75*09e7b002SM Chetan Kumar if (byte_read != MAX_CD_LIST_SIZE) 76*09e7b002SM Chetan Kumar goto cd_init_fail; 77*09e7b002SM Chetan Kumar 78*09e7b002SM Chetan Kumar if (cmd == rpsi_cmd_coredump_start) { 79*09e7b002SM Chetan Kumar num_entries = le32_to_cpu(cd_table->list.num_entries); 80*09e7b002SM Chetan Kumar if (num_entries == 0 || num_entries > IOSM_NOF_CD_REGION) { 81*09e7b002SM Chetan Kumar ret = -EINVAL; 82*09e7b002SM Chetan Kumar goto cd_init_fail; 83*09e7b002SM Chetan Kumar } 84*09e7b002SM Chetan Kumar 85*09e7b002SM Chetan Kumar for (i = 0; i < num_entries; i++) { 86*09e7b002SM Chetan Kumar file_size = le32_to_cpu(cd_table->list.entry[i].size); 87*09e7b002SM Chetan Kumar filename = cd_table->list.entry[i].filename; 88*09e7b002SM Chetan Kumar 89*09e7b002SM Chetan Kumar if (file_size > devlink->cd_file_info[i].default_size) { 90*09e7b002SM Chetan Kumar ret = -EINVAL; 91*09e7b002SM Chetan Kumar goto cd_init_fail; 92*09e7b002SM Chetan Kumar } 93*09e7b002SM Chetan Kumar 94*09e7b002SM Chetan Kumar devlink->cd_file_info[i].actual_size = file_size; 95*09e7b002SM Chetan Kumar dev_dbg(devlink->dev, "file: %s actual size %d", 96*09e7b002SM Chetan Kumar filename, file_size); 97*09e7b002SM Chetan Kumar devlink_flash_update_status_notify(devlink->devlink_ctx, 98*09e7b002SM Chetan Kumar filename, 99*09e7b002SM Chetan Kumar "FILENAME", 0, 0); 100*09e7b002SM Chetan Kumar snprintf(size, sizeof(size), "%d", file_size); 101*09e7b002SM Chetan Kumar devlink_flash_update_status_notify(devlink->devlink_ctx, 102*09e7b002SM Chetan Kumar size, "FILE SIZE", 103*09e7b002SM Chetan Kumar 0, 0); 104*09e7b002SM Chetan Kumar } 105*09e7b002SM Chetan Kumar } 106*09e7b002SM Chetan Kumar 107*09e7b002SM Chetan Kumar cd_init_fail: 108*09e7b002SM Chetan Kumar kfree(cd_table); 109*09e7b002SM Chetan Kumar return ret; 110*09e7b002SM Chetan Kumar } 111