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
17struct 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 */
41union 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 */
57struct 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 */
70struct 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 */
90struct 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 */
109struct 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 */
128struct 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 */
140struct 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 */
150struct 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 */
166struct 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 */
176struct 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 */
184struct loader_start_ack {
185	__le32 header;
186};
187
188union 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 */
210struct 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 */
229void ishtp_loader_work(struct work_struct *work);
230
231#endif /* _ISHTP_LOADER_H_ */
232