xref: /linux/drivers/hid/intel-ish-hid/ishtp/loader.h (revision 0e8655b4e852ef97655648b91ce780384a073ff4)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * ISHTP firmware loader header
4  *
5  * Copyright (c) 2024, Intel Corporation.
6  */
7 
8 #ifndef _ISHTP_LOADER_H_
9 #define _ISHTP_LOADER_H_
10 
11 #include <linux/bits.h>
12 #include <linux/jiffies.h>
13 #include <linux/types.h>
14 
15 #include "ishtp-dev.h"
16 
17 struct work_struct;
18 
19 #define LOADER_MSG_SIZE \
20 	(IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr))
21 
22 /*
23  * ISHTP firmware loader protocol definition
24  */
25 #define LOADER_CMD_XFER_QUERY		0	/* SW -> FW */
26 #define LOADER_CMD_XFER_FRAGMENT	1	/* SW -> FW */
27 #define LOADER_CMD_START		2	/* SW -> FW */
28 
29 /* Only support DMA mode */
30 #define LOADER_XFER_MODE_DMA BIT(0)
31 
32 /**
33  * union loader_msg_header - ISHTP firmware loader message header
34  * @command: Command type
35  * @is_response: Indicates if the message is a response
36  * @has_next: Indicates if there is a next message
37  * @reserved: Reserved for future use
38  * @status: Status of the message
39  * @val32: entire header as a 32-bit value
40  */
41 union loader_msg_header {
42 	struct {
43 		__u32 command:7;
44 		__u32 is_response:1;
45 		__u32 has_next:1;
46 		__u32 reserved:15;
47 		__u32 status:8;
48 	};
49 	__u32 val32;
50 };
51 
52 /**
53  * struct loader_xfer_query - ISHTP firmware loader transfer query packet
54  * @header: Header of the message
55  * @image_size: Size of the image
56  */
57 struct loader_xfer_query {
58 	__le32 header;
59 	__le32 image_size;
60 };
61 
62 /**
63  * struct loader_version - ISHTP firmware loader version
64  * @value: Value of the version
65  * @major: Major version
66  * @minor: Minor version
67  * @hotfix: Hotfix version
68  * @build: Build version
69  */
70 struct loader_version {
71 	union {
72 		__le32 value;
73 		struct {
74 			__u8 major;
75 			__u8 minor;
76 			__u8 hotfix;
77 			__u8 build;
78 		};
79 	};
80 };
81 
82 /**
83  * struct loader_capability - ISHTP firmware loader capability
84  * @max_fw_image_size: Maximum firmware image size
85  * @support_mode: Support mode
86  * @reserved: Reserved for future use
87  * @platform: Platform
88  * @max_dma_buf_size: Maximum DMA buffer size, multiples of 4096
89  */
90 struct loader_capability {
91 	__le32 max_fw_image_size;
92 	__le16 support_mode;
93 	__u8 reserved;
94 	__u8 platform;
95 	__le32 max_dma_buf_size;
96 };
97 
98 /**
99  * struct loader_xfer_query_ack - ISHTP firmware loader transfer query acknowledgment
100  * @header: Header of the message
101  * @version_major: ISH Major version
102  * @version_minor: ISH Minor version
103  * @version_hotfix: ISH Hotfix version
104  * @version_build: ISH Build version
105  * @protocol_version: Protocol version
106  * @loader_version: Loader version
107  * @capability: Loader capability
108  */
109 struct loader_xfer_query_ack {
110 	__le32 header;
111 	__le16 version_major;
112 	__le16 version_minor;
113 	__le16 version_hotfix;
114 	__le16 version_build;
115 	__le32 protocol_version;
116 	struct loader_version loader_version;
117 	struct loader_capability capability;
118 };
119 
120 /**
121  * struct loader_xfer_fragment - ISHTP firmware loader transfer fragment
122  * @header: Header of the message
123  * @xfer_mode: Transfer mode
124  * @offset: Offset
125  * @size: Size
126  * @is_last: Is last
127  */
128 struct loader_xfer_fragment {
129 	__le32 header;
130 	__le32 xfer_mode;
131 	__le32 offset;
132 	__le32 size;
133 	__le32 is_last;
134 };
135 
136 /**
137  * struct loader_xfer_fragment_ack - ISHTP firmware loader transfer fragment acknowledgment
138  * @header: Header of the message
139  */
140 struct loader_xfer_fragment_ack {
141 	__le32 header;
142 };
143 
144 /**
145  * struct fragment_dscrpt - ISHTP firmware loader fragment descriptor
146  * @ddr_adrs: The address in host DDR
147  * @fw_off: The offset of the fragment in the fw image
148  * @length: The length of the fragment
149  */
150 struct fragment_dscrpt {
151 	__le64 ddr_adrs;
152 	__le32 fw_off;
153 	__le32 length;
154 };
155 
156 #define FRAGMENT_MAX_NUM \
157 	((LOADER_MSG_SIZE - sizeof(struct loader_xfer_dma_fragment)) / \
158 	 sizeof(struct fragment_dscrpt))
159 
160 /**
161  * struct loader_xfer_dma_fragment - ISHTP firmware loader transfer DMA fragment
162  * @fragment: Fragment
163  * @fragment_cnt: How many descriptors in the fragment_tbl
164  * @fragment_tbl: Fragment table
165  */
166 struct loader_xfer_dma_fragment {
167 	struct loader_xfer_fragment fragment;
168 	__le32 fragment_cnt;
169 	struct fragment_dscrpt fragment_tbl[] __counted_by(fragment_cnt);
170 };
171 
172 /**
173  * struct loader_start - ISHTP firmware loader start
174  * @header: Header of the message
175  */
176 struct loader_start {
177 	__le32 header;
178 };
179 
180 /**
181  * struct loader_start_ack - ISHTP firmware loader start acknowledgment
182  * @header: Header of the message
183  */
184 struct loader_start_ack {
185 	__le32 header;
186 };
187 
188 union loader_recv_message {
189 	__le32 header;
190 	struct loader_xfer_query_ack query_ack;
191 	struct loader_xfer_fragment_ack fragment_ack;
192 	struct loader_start_ack start_ack;
193 	__u8 raw_data[LOADER_MSG_SIZE];
194 };
195 
196 /*
197  * ISHTP firmware loader internal use
198  */
199 /* ISHTP firmware loader command timeout */
200 #define ISHTP_LOADER_TIMEOUT msecs_to_jiffies(100)
201 
202 /* ISHTP firmware loader retry times */
203 #define ISHTP_LOADER_RETRY_TIMES 3
204 
205 /**
206  * struct ish_firmware_variant - ISH firmware variant
207  * @device: PCI Device ID
208  * @filename: The firmware file name
209  */
210 struct ish_firmware_variant {
211 	unsigned short device;
212 	const char *filename;
213 };
214 
215 /*
216  * ISHTP firmware loader API for ISHTP hbm
217  */
218 
219 /* ISHTP capability bit for firmware loader */
220 #define ISHTP_SUPPORT_CAP_LOADER BIT(4)
221 
222 /* Firmware loader address */
223 #define ISHTP_LOADER_CLIENT_ADDR 16
224 
225 /**
226  * ishtp_loader_work - The work function to start the firmware loading process
227  * @work: The work structure
228  */
229 void ishtp_loader_work(struct work_struct *work);
230 
231 #endif /* _ISHTP_LOADER_H_ */
232