Skip to content

Commit 13bb842

Browse files
mchetankumardavem330
authored andcommitted
net: wwan: iosm: firmware flashing and coredump collection
This patch brings-in support for M.2 7560 Device firmware flashing & coredump collection using devlink. - Driver Registers with Devlink framework. - Register devlink params callback for configuring device params required in flashing or coredump flow. - Implements devlink ops flash_update callback that programs modem firmware. - Creates region & snapshot required for device coredump log collection. On early detection of device in boot rom stage. Driver registers with Devlink framework and establish transport channel for PSI (Primary Signed Image) injection. Once PSI is injected to device, the device execution stage details are read to determine whether device is in flash or exception mode. The collected information is reported to devlink user space application & based on this informationi, application proceeds with either modem firmware flashing or coredump collection. Signed-off-by: M Chetan Kumar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 08c53ae commit 13bb842

14 files changed

+2055
-31
lines changed

drivers/net/wwan/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ config RPMSG_WWAN_CTRL
7171
config IOSM
7272
tristate "IOSM Driver for Intel M.2 WWAN Device"
7373
depends on INTEL_IOMMU
74+
select NET_DEVLINK
7475
help
7576
This driver enables Intel M.2 WWAN Device communication.
7677

drivers/net/wwan/iosm/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ iosm-y = \
1818
iosm_ipc_protocol.o \
1919
iosm_ipc_protocol_ops.o \
2020
iosm_ipc_mux.o \
21-
iosm_ipc_mux_codec.o
21+
iosm_ipc_mux_codec.o \
22+
iosm_ipc_devlink.o \
23+
iosm_ipc_flash.o \
24+
iosm_ipc_coredump.o
2225

2326
obj-$(CONFIG_IOSM) := iosm.o

drivers/net/wwan/iosm/iosm_ipc_chnl_cfg.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "iosm_ipc_chnl_cfg.h"
99

1010
/* Max. sizes of a downlink buffers */
11-
#define IPC_MEM_MAX_DL_FLASH_BUF_SIZE (16 * 1024)
11+
#define IPC_MEM_MAX_DL_FLASH_BUF_SIZE (64 * 1024)
1212
#define IPC_MEM_MAX_DL_LOOPBACK_SIZE (1 * 1024 * 1024)
1313
#define IPC_MEM_MAX_DL_AT_BUF_SIZE 2048
1414
#define IPC_MEM_MAX_DL_RPC_BUF_SIZE (32 * 1024)
@@ -60,6 +60,10 @@ static struct ipc_chnl_cfg modem_cfg[] = {
6060
{ IPC_MEM_CTRL_CHL_ID_6, IPC_MEM_PIPE_12, IPC_MEM_PIPE_13,
6161
IPC_MEM_MAX_TDS_MBIM, IPC_MEM_MAX_TDS_MBIM,
6262
IPC_MEM_MAX_DL_MBIM_BUF_SIZE, WWAN_PORT_MBIM },
63+
/* Flash Channel/Coredump Channel */
64+
{ IPC_MEM_CTRL_CHL_ID_7, IPC_MEM_PIPE_0, IPC_MEM_PIPE_1,
65+
IPC_MEM_MAX_TDS_FLASH_UL, IPC_MEM_MAX_TDS_FLASH_DL,
66+
IPC_MEM_MAX_DL_FLASH_BUF_SIZE, WWAN_PORT_UNKNOWN },
6367
};
6468

6569
int ipc_chnl_cfg_get(struct ipc_chnl_cfg *chnl_cfg, int index)

drivers/net/wwan/iosm/iosm_ipc_chnl_cfg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum ipc_channel_id {
2323
IPC_MEM_CTRL_CHL_ID_4,
2424
IPC_MEM_CTRL_CHL_ID_5,
2525
IPC_MEM_CTRL_CHL_ID_6,
26+
IPC_MEM_CTRL_CHL_ID_7,
2627
};
2728

2829
/**
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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+
8+
/* Collect coredump data from modem */
9+
int ipc_coredump_collect(struct iosm_devlink *devlink, u8 **data, int entry,
10+
u32 region_size)
11+
{
12+
int ret, bytes_to_read, bytes_read = 0, i = 0;
13+
s32 remaining;
14+
u8 *data_ptr;
15+
16+
data_ptr = vmalloc(region_size);
17+
if (!data_ptr)
18+
return -ENOMEM;
19+
20+
remaining = devlink->cd_file_info[entry].actual_size;
21+
ret = ipc_devlink_send_cmd(devlink, rpsi_cmd_coredump_get, entry);
22+
if (ret) {
23+
dev_err(devlink->dev, "Send coredump_get cmd failed");
24+
goto get_cd_fail;
25+
}
26+
while (remaining > 0) {
27+
bytes_to_read = min(remaining, MAX_DATA_SIZE);
28+
bytes_read = 0;
29+
ret = ipc_imem_sys_devlink_read(devlink, data_ptr + i,
30+
bytes_to_read, &bytes_read);
31+
if (ret) {
32+
dev_err(devlink->dev, "CD data read failed");
33+
goto get_cd_fail;
34+
}
35+
remaining -= bytes_read;
36+
i += bytes_read;
37+
}
38+
39+
*data = data_ptr;
40+
41+
return ret;
42+
get_cd_fail:
43+
vfree(data_ptr);
44+
return ret;
45+
}
46+
47+
/* Get coredump list to be collected from modem */
48+
int ipc_coredump_get_list(struct iosm_devlink *devlink, u16 cmd)
49+
{
50+
u32 byte_read, num_entries, file_size;
51+
struct iosm_cd_table *cd_table;
52+
u8 size[MAX_SIZE_LEN], i;
53+
char *filename;
54+
int ret = 0;
55+
56+
cd_table = kzalloc(MAX_CD_LIST_SIZE, GFP_KERNEL);
57+
if (!cd_table) {
58+
ret = -ENOMEM;
59+
goto cd_init_fail;
60+
}
61+
62+
ret = ipc_devlink_send_cmd(devlink, cmd, MAX_CD_LIST_SIZE);
63+
if (ret) {
64+
dev_err(devlink->dev, "rpsi_cmd_coredump_start failed");
65+
goto cd_init_fail;
66+
}
67+
68+
ret = ipc_imem_sys_devlink_read(devlink, (u8 *)cd_table,
69+
MAX_CD_LIST_SIZE, &byte_read);
70+
if (ret) {
71+
dev_err(devlink->dev, "Coredump data is invalid");
72+
goto cd_init_fail;
73+
}
74+
75+
if (byte_read != MAX_CD_LIST_SIZE)
76+
goto cd_init_fail;
77+
78+
if (cmd == rpsi_cmd_coredump_start) {
79+
num_entries = le32_to_cpu(cd_table->list.num_entries);
80+
if (num_entries == 0 || num_entries > IOSM_NOF_CD_REGION) {
81+
ret = -EINVAL;
82+
goto cd_init_fail;
83+
}
84+
85+
for (i = 0; i < num_entries; i++) {
86+
file_size = le32_to_cpu(cd_table->list.entry[i].size);
87+
filename = cd_table->list.entry[i].filename;
88+
89+
if (file_size > devlink->cd_file_info[i].default_size) {
90+
ret = -EINVAL;
91+
goto cd_init_fail;
92+
}
93+
94+
devlink->cd_file_info[i].actual_size = file_size;
95+
dev_dbg(devlink->dev, "file: %s actual size %d",
96+
filename, file_size);
97+
devlink_flash_update_status_notify(devlink->devlink_ctx,
98+
filename,
99+
"FILENAME", 0, 0);
100+
snprintf(size, sizeof(size), "%d", file_size);
101+
devlink_flash_update_status_notify(devlink->devlink_ctx,
102+
size, "FILE SIZE",
103+
0, 0);
104+
}
105+
}
106+
107+
cd_init_fail:
108+
kfree(cd_table);
109+
return ret;
110+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only
2+
*
3+
* Copyright (C) 2020-2021 Intel Corporation.
4+
*/
5+
6+
#ifndef _IOSM_IPC_COREDUMP_H_
7+
#define _IOSM_IPC_COREDUMP_H_
8+
9+
#include "iosm_ipc_devlink.h"
10+
11+
/* Max number of bytes to receive for Coredump list structure */
12+
#define MAX_CD_LIST_SIZE 0x1000
13+
14+
/* Max buffer allocated to receive coredump data */
15+
#define MAX_DATA_SIZE 0x00010000
16+
17+
/* Max number of file entries */
18+
#define MAX_NOF_ENTRY 256
19+
20+
/* Max length */
21+
#define MAX_SIZE_LEN 32
22+
23+
/**
24+
* struct iosm_cd_list_entry - Structure to hold coredump file info.
25+
* @size: Number of bytes for the entry
26+
* @filename: Coredump filename to be generated on host
27+
*/
28+
struct iosm_cd_list_entry {
29+
__le32 size;
30+
char filename[IOSM_MAX_FILENAME_LEN];
31+
} __packed;
32+
33+
/**
34+
* struct iosm_cd_list - Structure to hold list of coredump files
35+
* to be collected.
36+
* @num_entries: Number of entries to be received
37+
* @entry: Contains File info
38+
*/
39+
struct iosm_cd_list {
40+
__le32 num_entries;
41+
struct iosm_cd_list_entry entry[MAX_NOF_ENTRY];
42+
} __packed;
43+
44+
/**
45+
* struct iosm_cd_table - Common Coredump table
46+
* @version: Version of coredump structure
47+
* @list: Coredump list structure
48+
*/
49+
struct iosm_cd_table {
50+
__le32 version;
51+
struct iosm_cd_list list;
52+
} __packed;
53+
54+
/**
55+
* ipc_coredump_collect - To collect coredump
56+
* @devlink: Pointer to devlink instance.
57+
* @data: Pointer to snapshot
58+
* @entry: ID of requested snapshot
59+
* @region_size: Region size
60+
*
61+
* Returns: 0 on success, error on failure
62+
*/
63+
int ipc_coredump_collect(struct iosm_devlink *devlink, u8 **data, int entry,
64+
u32 region_size);
65+
66+
/**
67+
* ipc_coredump_get_list - Get coredump list
68+
* @devlink: Pointer to devlink instance.
69+
* @cmd: RPSI command to be sent
70+
*
71+
* Returns: 0 on success, error on failure
72+
*/
73+
int ipc_coredump_get_list(struct iosm_devlink *devlink, u16 cmd);
74+
75+
#endif /* _IOSM_IPC_COREDUMP_H_ */

0 commit comments

Comments
 (0)