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