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