aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/coredump.h
blob: 09de41922f97060f9615bf81f0344bb338bd7e62 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/* SPDX-License-Identifier: ISC */
/*
 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
 */

#ifndef _COREDUMP_H_
#define _COREDUMP_H_

#include "core.h"

#define ATH10K_FW_CRASH_DUMP_VERSION 1

/**
 * enum ath10k_fw_crash_dump_type - types of data in the dump file
 * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format
 */
enum ath10k_fw_crash_dump_type {
	ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
	ATH10K_FW_CRASH_DUMP_CE_DATA = 1,

	/* contains multiple struct ath10k_dump_ram_data_hdr */
	ATH10K_FW_CRASH_DUMP_RAM_DATA = 2,

	ATH10K_FW_CRASH_DUMP_MAX,
};

struct ath10k_tlv_dump_data {
	/* see ath10k_fw_crash_dump_type above */
	__le32 type;

	/* in bytes */
	__le32 tlv_len;

	/* pad to 32-bit boundaries as needed */
	u8 tlv_data[];
} __packed;

struct ath10k_dump_file_data {
	/* dump file information */

	/* "ATH10K-FW-DUMP" */
	char df_magic[16];

	__le32 len;

	/* file dump version */
	__le32 version;

	/* some info we can get from ath10k struct that might help */

	guid_t guid;

	__le32 chip_id;

	/* 0 for now, in place for later hardware */
	__le32 bus_type;

	__le32 target_version;
	__le32 fw_version_major;
	__le32 fw_version_minor;
	__le32 fw_version_release;
	__le32 fw_version_build;
	__le32 phy_capability;
	__le32 hw_min_tx_power;
	__le32 hw_max_tx_power;
	__le32 ht_cap_info;
	__le32 vht_cap_info;
	__le32 num_rf_chains;

	/* firmware version string */
	char fw_ver[ETHTOOL_FWVERS_LEN];

	/* Kernel related information */

	/* time-of-day stamp */
	__le64 tv_sec;

	/* time-of-day stamp, nano-seconds */
	__le64 tv_nsec;

	/* LINUX_VERSION_CODE */
	__le32 kernel_ver_code;

	/* VERMAGIC_STRING */
	char kernel_ver[64];

	/* room for growth w/out changing binary format */
	u8 unused[128];

	/* struct ath10k_tlv_dump_data + more */
	u8 data[0];
} __packed;

struct ath10k_dump_ram_data_hdr {
	/* enum ath10k_mem_region_type */
	__le32 region_type;

	__le32 start;

	/* length of payload data, not including this header */
	__le32 length;

	u8 data[0];
};

/* magic number to fill the holes not copied due to sections in regions */
#define ATH10K_MAGIC_NOT_COPIED		0xAA

/* part of user space ABI */
enum ath10k_mem_region_type {
	ATH10K_MEM_REGION_TYPE_REG	= 1,
	ATH10K_MEM_REGION_TYPE_DRAM	= 2,
	ATH10K_MEM_REGION_TYPE_AXI	= 3,
	ATH10K_MEM_REGION_TYPE_IRAM1	= 4,
	ATH10K_MEM_REGION_TYPE_IRAM2	= 5,
	ATH10K_MEM_REGION_TYPE_IOSRAM	= 6,
	ATH10K_MEM_REGION_TYPE_IOREG	= 7,
};

/* Define a section of the region which should be copied. As not all parts
 * of the memory is possible to copy, for example some of the registers can
 * be like that, sections can be used to define what is safe to copy.
 *
 * To minimize the size of the array, the list must obey the format:
 * '{start0,stop0},{start1,stop1},{start2,stop2}....' The values below must
 * also obey to 'start0 < stop0 < start1 < stop1 < start2 < ...', otherwise
 * we may encouter error in the dump processing.
 */
struct ath10k_mem_section {
	u32 start;
	u32 end;
};

/* One region of a memory layout. If the sections field is null entire
 * region is copied. If sections is non-null only the areas specified in
 * sections are copied and rest of the areas are filled with
 * ATH10K_MAGIC_NOT_COPIED.
 */
struct ath10k_mem_region {
	enum ath10k_mem_region_type type;
	u32 start;
	u32 len;

	const char *name;

	struct {
		const struct ath10k_mem_section *sections;
		u32 size;
	} section_table;
};

/* Contains the memory layout of a hardware version identified with the
 * hardware id, split into regions.
 */
struct ath10k_hw_mem_layout {
	u32 hw_id;
	u32 hw_rev;

	struct {
		const struct ath10k_mem_region *regions;
		int size;
	} region_table;
};

/* FIXME: where to put this? */
extern unsigned long ath10k_coredump_mask;

#ifdef CONFIG_DEV_COREDUMP

int ath10k_coredump_submit(struct ath10k *ar);
struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar);
int ath10k_coredump_create(struct ath10k *ar);
int ath10k_coredump_register(struct ath10k *ar);
void ath10k_coredump_unregister(struct ath10k *ar);
void ath10k_coredump_destroy(struct ath10k *ar);

const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar);

#else /* CONFIG_DEV_COREDUMP */

static inline int ath10k_coredump_submit(struct ath10k *ar)
{
	return 0;
}

static inline struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
{
	return NULL;
}

static inline int ath10k_coredump_create(struct ath10k *ar)
{
	return 0;
}

static inline int ath10k_coredump_register(struct ath10k *ar)
{
	return 0;
}

static inline void ath10k_coredump_unregister(struct ath10k *ar)
{
}

static inline void ath10k_coredump_destroy(struct ath10k *ar)
{
}

static inline const struct ath10k_hw_mem_layout *
ath10k_coredump_get_mem_layout(struct ath10k *ar)
{
	return NULL;
}

#endif /* CONFIG_DEV_COREDUMP */

#endif /* _COREDUMP_H_ */