1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_FIRMWARE_H |
3 | #define _LINUX_FIRMWARE_H |
4 | |
5 | #include <linux/types.h> |
6 | #include <linux/compiler.h> |
7 | #include <linux/cleanup.h> |
8 | #include <linux/gfp.h> |
9 | |
10 | #define FW_ACTION_NOUEVENT 0 |
11 | #define FW_ACTION_UEVENT 1 |
12 | |
13 | struct firmware { |
14 | size_t size; |
15 | const u8 *data; |
16 | |
17 | /* firmware loader private fields */ |
18 | void *priv; |
19 | }; |
20 | |
21 | /** |
22 | * enum fw_upload_err - firmware upload error codes |
23 | * @FW_UPLOAD_ERR_NONE: returned to indicate success |
24 | * @FW_UPLOAD_ERR_HW_ERROR: error signalled by hardware, see kernel log |
25 | * @FW_UPLOAD_ERR_TIMEOUT: SW timed out on handshake with HW/firmware |
26 | * @FW_UPLOAD_ERR_CANCELED: upload was cancelled by the user |
27 | * @FW_UPLOAD_ERR_BUSY: there is an upload operation already in progress |
28 | * @FW_UPLOAD_ERR_INVALID_SIZE: invalid firmware image size |
29 | * @FW_UPLOAD_ERR_RW_ERROR: read or write to HW failed, see kernel log |
30 | * @FW_UPLOAD_ERR_WEAROUT: FLASH device is approaching wear-out, wait & retry |
31 | * @FW_UPLOAD_ERR_FW_INVALID: invalid firmware file |
32 | * @FW_UPLOAD_ERR_MAX: Maximum error code marker |
33 | */ |
34 | enum fw_upload_err { |
35 | FW_UPLOAD_ERR_NONE, |
36 | FW_UPLOAD_ERR_HW_ERROR, |
37 | FW_UPLOAD_ERR_TIMEOUT, |
38 | FW_UPLOAD_ERR_CANCELED, |
39 | FW_UPLOAD_ERR_BUSY, |
40 | FW_UPLOAD_ERR_INVALID_SIZE, |
41 | FW_UPLOAD_ERR_RW_ERROR, |
42 | FW_UPLOAD_ERR_WEAROUT, |
43 | FW_UPLOAD_ERR_FW_INVALID, |
44 | FW_UPLOAD_ERR_MAX |
45 | }; |
46 | |
47 | struct fw_upload { |
48 | void *dd_handle; /* reference to parent driver */ |
49 | void *priv; /* firmware loader private fields */ |
50 | }; |
51 | |
52 | /** |
53 | * struct fw_upload_ops - device specific operations to support firmware upload |
54 | * @prepare: Required: Prepare secure update |
55 | * @write: Required: The write() op receives the remaining |
56 | * size to be written and must return the actual |
57 | * size written or a negative error code. The write() |
58 | * op will be called repeatedly until all data is |
59 | * written. |
60 | * @poll_complete: Required: Check for the completion of the |
61 | * HW authentication/programming process. |
62 | * @cancel: Required: Request cancellation of update. This op |
63 | * is called from the context of a different kernel |
64 | * thread, so race conditions need to be considered. |
65 | * @cleanup: Optional: Complements the prepare() |
66 | * function and is called at the completion |
67 | * of the update, on success or failure, if the |
68 | * prepare function succeeded. |
69 | */ |
70 | struct fw_upload_ops { |
71 | enum fw_upload_err (*prepare)(struct fw_upload *fw_upload, |
72 | const u8 *data, u32 size); |
73 | enum fw_upload_err (*write)(struct fw_upload *fw_upload, |
74 | const u8 *data, u32 offset, |
75 | u32 size, u32 *written); |
76 | enum fw_upload_err (*poll_complete)(struct fw_upload *fw_upload); |
77 | void (*cancel)(struct fw_upload *fw_upload); |
78 | void (*cleanup)(struct fw_upload *fw_upload); |
79 | }; |
80 | |
81 | struct module; |
82 | struct device; |
83 | |
84 | /* |
85 | * Built-in firmware functionality is only available if FW_LOADER=y, but not |
86 | * FW_LOADER=m |
87 | */ |
88 | #ifdef CONFIG_FW_LOADER |
89 | bool firmware_request_builtin(struct firmware *fw, const char *name); |
90 | #else |
91 | static inline bool firmware_request_builtin(struct firmware *fw, |
92 | const char *name) |
93 | { |
94 | return false; |
95 | } |
96 | #endif |
97 | |
98 | #if IS_REACHABLE(CONFIG_FW_LOADER) |
99 | int request_firmware(const struct firmware **fw, const char *name, |
100 | struct device *device); |
101 | int firmware_request_nowarn(const struct firmware **fw, const char *name, |
102 | struct device *device); |
103 | int firmware_request_platform(const struct firmware **fw, const char *name, |
104 | struct device *device); |
105 | int request_firmware_nowait( |
106 | struct module *module, bool uevent, |
107 | const char *name, struct device *device, gfp_t gfp, void *context, |
108 | void (*cont)(const struct firmware *fw, void *context)); |
109 | int request_firmware_direct(const struct firmware **fw, const char *name, |
110 | struct device *device); |
111 | int request_firmware_into_buf(const struct firmware **firmware_p, |
112 | const char *name, struct device *device, void *buf, size_t size); |
113 | int request_partial_firmware_into_buf(const struct firmware **firmware_p, |
114 | const char *name, struct device *device, |
115 | void *buf, size_t size, size_t offset); |
116 | |
117 | void release_firmware(const struct firmware *fw); |
118 | #else |
119 | static inline int request_firmware(const struct firmware **fw, |
120 | const char *name, |
121 | struct device *device) |
122 | { |
123 | return -EINVAL; |
124 | } |
125 | |
126 | static inline int firmware_request_nowarn(const struct firmware **fw, |
127 | const char *name, |
128 | struct device *device) |
129 | { |
130 | return -EINVAL; |
131 | } |
132 | |
133 | static inline int firmware_request_platform(const struct firmware **fw, |
134 | const char *name, |
135 | struct device *device) |
136 | { |
137 | return -EINVAL; |
138 | } |
139 | |
140 | static inline int request_firmware_nowait( |
141 | struct module *module, bool uevent, |
142 | const char *name, struct device *device, gfp_t gfp, void *context, |
143 | void (*cont)(const struct firmware *fw, void *context)) |
144 | { |
145 | return -EINVAL; |
146 | } |
147 | |
148 | static inline void release_firmware(const struct firmware *fw) |
149 | { |
150 | } |
151 | |
152 | static inline int request_firmware_direct(const struct firmware **fw, |
153 | const char *name, |
154 | struct device *device) |
155 | { |
156 | return -EINVAL; |
157 | } |
158 | |
159 | static inline int request_firmware_into_buf(const struct firmware **firmware_p, |
160 | const char *name, struct device *device, void *buf, size_t size) |
161 | { |
162 | return -EINVAL; |
163 | } |
164 | |
165 | static inline int request_partial_firmware_into_buf |
166 | (const struct firmware **firmware_p, |
167 | const char *name, |
168 | struct device *device, |
169 | void *buf, size_t size, size_t offset) |
170 | { |
171 | return -EINVAL; |
172 | } |
173 | |
174 | #endif |
175 | |
176 | #ifdef CONFIG_FW_UPLOAD |
177 | |
178 | struct fw_upload * |
179 | firmware_upload_register(struct module *module, struct device *parent, |
180 | const char *name, const struct fw_upload_ops *ops, |
181 | void *dd_handle); |
182 | void firmware_upload_unregister(struct fw_upload *fw_upload); |
183 | |
184 | #else |
185 | |
186 | static inline struct fw_upload * |
187 | firmware_upload_register(struct module *module, struct device *parent, |
188 | const char *name, const struct fw_upload_ops *ops, |
189 | void *dd_handle) |
190 | { |
191 | return ERR_PTR(-EINVAL); |
192 | } |
193 | |
194 | static inline void firmware_upload_unregister(struct fw_upload *fw_upload) |
195 | { |
196 | } |
197 | |
198 | #endif |
199 | |
200 | int firmware_request_cache(struct device *device, const char *name); |
201 | |
202 | DEFINE_FREE(firmware, struct firmware *, release_firmware(_T)) |
203 | |
204 | #endif |
205 | |