xref: /linux-6.15/include/linux/firmware.h (revision 11c63e57)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef _LINUX_FIRMWARE_H
31da177e4SLinus Torvalds #define _LINUX_FIRMWARE_H
45658c769SDavid Woodhouse 
51da177e4SLinus Torvalds #include <linux/types.h>
65658c769SDavid Woodhouse #include <linux/compiler.h>
78dde8fa0SDmitry Torokhov #include <linux/cleanup.h>
89ebfbd45SJohannes Berg #include <linux/gfp.h>
95658c769SDavid Woodhouse 
100733d839SShawn Guo #define FW_ACTION_NOUEVENT 0
110733d839SShawn Guo #define FW_ACTION_UEVENT 1
126e3eaab0SAbhay Salunke 
131da177e4SLinus Torvalds struct firmware {
141da177e4SLinus Torvalds 	size_t size;
15b7a39bd0SDavid Woodhouse 	const u8 *data;
161f2b7959SMing Lei 
171f2b7959SMing Lei 	/* firmware loader private fields */
181f2b7959SMing Lei 	void *priv;
191da177e4SLinus Torvalds };
20fbab976dSJames Bottomley 
2197730bbbSRuss Weight /**
2297730bbbSRuss Weight  * enum fw_upload_err - firmware upload error codes
2397730bbbSRuss Weight  * @FW_UPLOAD_ERR_NONE: returned to indicate success
2497730bbbSRuss Weight  * @FW_UPLOAD_ERR_HW_ERROR: error signalled by hardware, see kernel log
2597730bbbSRuss Weight  * @FW_UPLOAD_ERR_TIMEOUT: SW timed out on handshake with HW/firmware
2697730bbbSRuss Weight  * @FW_UPLOAD_ERR_CANCELED: upload was cancelled by the user
2797730bbbSRuss Weight  * @FW_UPLOAD_ERR_BUSY: there is an upload operation already in progress
2897730bbbSRuss Weight  * @FW_UPLOAD_ERR_INVALID_SIZE: invalid firmware image size
2997730bbbSRuss Weight  * @FW_UPLOAD_ERR_RW_ERROR: read or write to HW failed, see kernel log
3097730bbbSRuss Weight  * @FW_UPLOAD_ERR_WEAROUT: FLASH device is approaching wear-out, wait & retry
31a066f906SKory Maincent  * @FW_UPLOAD_ERR_FW_INVALID: invalid firmware file
3297730bbbSRuss Weight  * @FW_UPLOAD_ERR_MAX: Maximum error code marker
3397730bbbSRuss Weight  */
3497730bbbSRuss Weight enum fw_upload_err {
3597730bbbSRuss Weight 	FW_UPLOAD_ERR_NONE,
3697730bbbSRuss Weight 	FW_UPLOAD_ERR_HW_ERROR,
3797730bbbSRuss Weight 	FW_UPLOAD_ERR_TIMEOUT,
3897730bbbSRuss Weight 	FW_UPLOAD_ERR_CANCELED,
3997730bbbSRuss Weight 	FW_UPLOAD_ERR_BUSY,
4097730bbbSRuss Weight 	FW_UPLOAD_ERR_INVALID_SIZE,
4197730bbbSRuss Weight 	FW_UPLOAD_ERR_RW_ERROR,
4297730bbbSRuss Weight 	FW_UPLOAD_ERR_WEAROUT,
43a066f906SKory Maincent 	FW_UPLOAD_ERR_FW_INVALID,
4497730bbbSRuss Weight 	FW_UPLOAD_ERR_MAX
4597730bbbSRuss Weight };
4697730bbbSRuss Weight 
4797730bbbSRuss Weight struct fw_upload {
4897730bbbSRuss Weight 	void *dd_handle; /* reference to parent driver */
4997730bbbSRuss Weight 	void *priv;	 /* firmware loader private fields */
5097730bbbSRuss Weight };
5197730bbbSRuss Weight 
5297730bbbSRuss Weight /**
5397730bbbSRuss Weight  * struct fw_upload_ops - device specific operations to support firmware upload
5497730bbbSRuss Weight  * @prepare:		  Required: Prepare secure update
5597730bbbSRuss Weight  * @write:		  Required: The write() op receives the remaining
5697730bbbSRuss Weight  *			  size to be written and must return the actual
5797730bbbSRuss Weight  *			  size written or a negative error code. The write()
5897730bbbSRuss Weight  *			  op will be called repeatedly until all data is
5997730bbbSRuss Weight  *			  written.
6097730bbbSRuss Weight  * @poll_complete:	  Required: Check for the completion of the
6197730bbbSRuss Weight  *			  HW authentication/programming process.
6297730bbbSRuss Weight  * @cancel:		  Required: Request cancellation of update. This op
6397730bbbSRuss Weight  *			  is called from the context of a different kernel
6497730bbbSRuss Weight  *			  thread, so race conditions need to be considered.
6597730bbbSRuss Weight  * @cleanup:		  Optional: Complements the prepare()
6697730bbbSRuss Weight  *			  function and is called at the completion
6797730bbbSRuss Weight  *			  of the update, on success or failure, if the
6897730bbbSRuss Weight  *			  prepare function succeeded.
6997730bbbSRuss Weight  */
7097730bbbSRuss Weight struct fw_upload_ops {
7197730bbbSRuss Weight 	enum fw_upload_err (*prepare)(struct fw_upload *fw_upload,
7297730bbbSRuss Weight 				      const u8 *data, u32 size);
7397730bbbSRuss Weight 	enum fw_upload_err (*write)(struct fw_upload *fw_upload,
7497730bbbSRuss Weight 				    const u8 *data, u32 offset,
7597730bbbSRuss Weight 				    u32 size, u32 *written);
7697730bbbSRuss Weight 	enum fw_upload_err (*poll_complete)(struct fw_upload *fw_upload);
7797730bbbSRuss Weight 	void (*cancel)(struct fw_upload *fw_upload);
7897730bbbSRuss Weight 	void (*cleanup)(struct fw_upload *fw_upload);
7997730bbbSRuss Weight };
8097730bbbSRuss Weight 
81de477254SPaul Gortmaker struct module;
821da177e4SLinus Torvalds struct device;
83fbab976dSJames Bottomley 
8448d09e97SLuis Chamberlain /*
8548d09e97SLuis Chamberlain  * Built-in firmware functionality is only available if FW_LOADER=y, but not
8648d09e97SLuis Chamberlain  * FW_LOADER=m
8748d09e97SLuis Chamberlain  */
8848d09e97SLuis Chamberlain #ifdef CONFIG_FW_LOADER
8948d09e97SLuis Chamberlain bool firmware_request_builtin(struct firmware *fw, const char *name);
9048d09e97SLuis Chamberlain #else
firmware_request_builtin(struct firmware * fw,const char * name)9148d09e97SLuis Chamberlain static inline bool firmware_request_builtin(struct firmware *fw,
9248d09e97SLuis Chamberlain 					    const char *name)
9348d09e97SLuis Chamberlain {
9448d09e97SLuis Chamberlain 	return false;
9548d09e97SLuis Chamberlain }
9648d09e97SLuis Chamberlain #endif
9748d09e97SLuis Chamberlain 
98bb6e8c28SLuis Chamberlain #if IS_REACHABLE(CONFIG_FW_LOADER)
991da177e4SLinus Torvalds int request_firmware(const struct firmware **fw, const char *name,
1001da177e4SLinus Torvalds 		     struct device *device);
101*11c63e57SLucas Stach int firmware_request_nowait_nowarn(
102*11c63e57SLucas Stach 	struct module *module, const char *name,
103*11c63e57SLucas Stach 	struct device *device, gfp_t gfp, void *context,
104*11c63e57SLucas Stach 	void (*cont)(const struct firmware *fw, void *context));
1057dcc0134SAndres Rodriguez int firmware_request_nowarn(const struct firmware **fw, const char *name,
1067dcc0134SAndres Rodriguez 			    struct device *device);
107e4c2c0ffSHans de Goede int firmware_request_platform(const struct firmware **fw, const char *name,
108e4c2c0ffSHans de Goede 			      struct device *device);
1091da177e4SLinus Torvalds int request_firmware_nowait(
110072fc8f0SBob Liu 	struct module *module, bool uevent,
1119ebfbd45SJohannes Berg 	const char *name, struct device *device, gfp_t gfp, void *context,
1121da177e4SLinus Torvalds 	void (*cont)(const struct firmware *fw, void *context));
113c868edf4SLuis R. Rodriguez int request_firmware_direct(const struct firmware **fw, const char *name,
114c868edf4SLuis R. Rodriguez 			    struct device *device);
115a098ecd2SStephen Boyd int request_firmware_into_buf(const struct firmware **firmware_p,
116a098ecd2SStephen Boyd 	const char *name, struct device *device, void *buf, size_t size);
11759cdb23cSScott Branden int request_partial_firmware_into_buf(const struct firmware **firmware_p,
11859cdb23cSScott Branden 				      const char *name, struct device *device,
11959cdb23cSScott Branden 				      void *buf, size_t size, size_t offset);
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds void release_firmware(const struct firmware *fw);
122fbab976dSJames Bottomley #else
request_firmware(const struct firmware ** fw,const char * name,struct device * device)123fbab976dSJames Bottomley static inline int request_firmware(const struct firmware **fw,
124fbab976dSJames Bottomley 				   const char *name,
125fbab976dSJames Bottomley 				   struct device *device)
126fbab976dSJames Bottomley {
127fbab976dSJames Bottomley 	return -EINVAL;
128fbab976dSJames Bottomley }
1297dcc0134SAndres Rodriguez 
firmware_request_nowait_nowarn(struct module * module,const char * name,struct device * device,gfp_t gfp,void * context,void (* cont)(const struct firmware * fw,void * context))130*11c63e57SLucas Stach static inline int firmware_request_nowait_nowarn(
131*11c63e57SLucas Stach 	struct module *module, const char *name,
132*11c63e57SLucas Stach 	struct device *device, gfp_t gfp, void *context,
133*11c63e57SLucas Stach 	void (*cont)(const struct firmware *fw, void *context))
134*11c63e57SLucas Stach {
135*11c63e57SLucas Stach 	return -EINVAL;
136*11c63e57SLucas Stach }
137*11c63e57SLucas Stach 
firmware_request_nowarn(const struct firmware ** fw,const char * name,struct device * device)1387dcc0134SAndres Rodriguez static inline int firmware_request_nowarn(const struct firmware **fw,
1397dcc0134SAndres Rodriguez 					  const char *name,
1407dcc0134SAndres Rodriguez 					  struct device *device)
1417dcc0134SAndres Rodriguez {
1427dcc0134SAndres Rodriguez 	return -EINVAL;
1437dcc0134SAndres Rodriguez }
1447dcc0134SAndres Rodriguez 
firmware_request_platform(const struct firmware ** fw,const char * name,struct device * device)145e4c2c0ffSHans de Goede static inline int firmware_request_platform(const struct firmware **fw,
146e4c2c0ffSHans de Goede 					    const char *name,
147e4c2c0ffSHans de Goede 					    struct device *device)
148e4c2c0ffSHans de Goede {
149e4c2c0ffSHans de Goede 	return -EINVAL;
150e4c2c0ffSHans de Goede }
151e4c2c0ffSHans de Goede 
request_firmware_nowait(struct module * module,bool uevent,const char * name,struct device * device,gfp_t gfp,void * context,void (* cont)(const struct firmware * fw,void * context))152fbab976dSJames Bottomley static inline int request_firmware_nowait(
153072fc8f0SBob Liu 	struct module *module, bool uevent,
1549ebfbd45SJohannes Berg 	const char *name, struct device *device, gfp_t gfp, void *context,
155fbab976dSJames Bottomley 	void (*cont)(const struct firmware *fw, void *context))
156fbab976dSJames Bottomley {
157fbab976dSJames Bottomley 	return -EINVAL;
158fbab976dSJames Bottomley }
159fbab976dSJames Bottomley 
release_firmware(const struct firmware * fw)160fbab976dSJames Bottomley static inline void release_firmware(const struct firmware *fw)
161fbab976dSJames Bottomley {
162fbab976dSJames Bottomley }
1632887b395SMing Lei 
request_firmware_direct(const struct firmware ** fw,const char * name,struct device * device)164c868edf4SLuis R. Rodriguez static inline int request_firmware_direct(const struct firmware **fw,
165c868edf4SLuis R. Rodriguez 					  const char *name,
166c868edf4SLuis R. Rodriguez 					  struct device *device)
167c868edf4SLuis R. Rodriguez {
168c868edf4SLuis R. Rodriguez 	return -EINVAL;
169c868edf4SLuis R. Rodriguez }
170fbab976dSJames Bottomley 
request_firmware_into_buf(const struct firmware ** firmware_p,const char * name,struct device * device,void * buf,size_t size)171a098ecd2SStephen Boyd static inline int request_firmware_into_buf(const struct firmware **firmware_p,
172a098ecd2SStephen Boyd 	const char *name, struct device *device, void *buf, size_t size)
173a098ecd2SStephen Boyd {
174a098ecd2SStephen Boyd 	return -EINVAL;
175a098ecd2SStephen Boyd }
176a098ecd2SStephen Boyd 
request_partial_firmware_into_buf(const struct firmware ** firmware_p,const char * name,struct device * device,void * buf,size_t size,size_t offset)17759cdb23cSScott Branden static inline int request_partial_firmware_into_buf
17859cdb23cSScott Branden 					(const struct firmware **firmware_p,
17959cdb23cSScott Branden 					 const char *name,
18059cdb23cSScott Branden 					 struct device *device,
18159cdb23cSScott Branden 					 void *buf, size_t size, size_t offset)
18259cdb23cSScott Branden {
18359cdb23cSScott Branden 	return -EINVAL;
18459cdb23cSScott Branden }
18559cdb23cSScott Branden 
186bba3a87eSTakashi Iwai #endif
1875d42c96eSLuis R. Rodriguez 
18897730bbbSRuss Weight #ifdef CONFIG_FW_UPLOAD
18997730bbbSRuss Weight 
19097730bbbSRuss Weight struct fw_upload *
19197730bbbSRuss Weight firmware_upload_register(struct module *module, struct device *parent,
19297730bbbSRuss Weight 			 const char *name, const struct fw_upload_ops *ops,
19397730bbbSRuss Weight 			 void *dd_handle);
19497730bbbSRuss Weight void firmware_upload_unregister(struct fw_upload *fw_upload);
19597730bbbSRuss Weight 
19697730bbbSRuss Weight #else
19797730bbbSRuss Weight 
19897730bbbSRuss Weight static inline struct fw_upload *
firmware_upload_register(struct module * module,struct device * parent,const char * name,const struct fw_upload_ops * ops,void * dd_handle)19997730bbbSRuss Weight firmware_upload_register(struct module *module, struct device *parent,
20097730bbbSRuss Weight 			 const char *name, const struct fw_upload_ops *ops,
20197730bbbSRuss Weight 			 void *dd_handle)
20297730bbbSRuss Weight {
20397730bbbSRuss Weight 		return ERR_PTR(-EINVAL);
20497730bbbSRuss Weight }
20597730bbbSRuss Weight 
firmware_upload_unregister(struct fw_upload * fw_upload)20697730bbbSRuss Weight static inline void firmware_upload_unregister(struct fw_upload *fw_upload)
20797730bbbSRuss Weight {
20897730bbbSRuss Weight }
20997730bbbSRuss Weight 
21097730bbbSRuss Weight #endif
21197730bbbSRuss Weight 
2125d42c96eSLuis R. Rodriguez int firmware_request_cache(struct device *device, const char *name);
2135d42c96eSLuis R. Rodriguez 
2148dde8fa0SDmitry Torokhov DEFINE_FREE(firmware, struct firmware *, release_firmware(_T))
2158dde8fa0SDmitry Torokhov 
2161da177e4SLinus Torvalds #endif
217