xref: /openbmc/linux/include/linux/pldmfw.h (revision b8265621)
1b8265621SJacob Keller /* SPDX-License-Identifier: GPL-2.0 */
2b8265621SJacob Keller /* Copyright (C) 2018-2019, Intel Corporation. */
3b8265621SJacob Keller 
4b8265621SJacob Keller #ifndef _PLDMFW_H_
5b8265621SJacob Keller #define _PLDMFW_H_
6b8265621SJacob Keller 
7b8265621SJacob Keller #include <linux/list.h>
8b8265621SJacob Keller #include <linux/firmware.h>
9b8265621SJacob Keller 
10b8265621SJacob Keller #define PLDM_DEVICE_UPDATE_CONTINUE_AFTER_FAIL BIT(0)
11b8265621SJacob Keller 
12b8265621SJacob Keller #define PLDM_STRING_TYPE_UNKNOWN	0
13b8265621SJacob Keller #define PLDM_STRING_TYPE_ASCII		1
14b8265621SJacob Keller #define PLDM_STRING_TYPE_UTF8		2
15b8265621SJacob Keller #define PLDM_STRING_TYPE_UTF16		3
16b8265621SJacob Keller #define PLDM_STRING_TYPE_UTF16LE	4
17b8265621SJacob Keller #define PLDM_STRING_TYPE_UTF16BE	5
18b8265621SJacob Keller 
19b8265621SJacob Keller struct pldmfw_record {
20b8265621SJacob Keller 	struct list_head entry;
21b8265621SJacob Keller 
22b8265621SJacob Keller 	/* List of descriptor TLVs */
23b8265621SJacob Keller 	struct list_head descs;
24b8265621SJacob Keller 
25b8265621SJacob Keller 	/* Component Set version string*/
26b8265621SJacob Keller 	const u8 *version_string;
27b8265621SJacob Keller 	u8 version_type;
28b8265621SJacob Keller 	u8 version_len;
29b8265621SJacob Keller 
30b8265621SJacob Keller 	/* Package Data length */
31b8265621SJacob Keller 	u16 package_data_len;
32b8265621SJacob Keller 
33b8265621SJacob Keller 	/* Bitfield of Device Update Flags */
34b8265621SJacob Keller 	u32 device_update_flags;
35b8265621SJacob Keller 
36b8265621SJacob Keller 	/* Package Data block */
37b8265621SJacob Keller 	const u8 *package_data;
38b8265621SJacob Keller 
39b8265621SJacob Keller 	/* Bitmap of components applicable to this record */
40b8265621SJacob Keller 	unsigned long *component_bitmap;
41b8265621SJacob Keller 	u16 component_bitmap_len;
42b8265621SJacob Keller };
43b8265621SJacob Keller 
44b8265621SJacob Keller /* Standard descriptor TLV identifiers */
45b8265621SJacob Keller #define PLDM_DESC_ID_PCI_VENDOR_ID	0x0000
46b8265621SJacob Keller #define PLDM_DESC_ID_IANA_ENTERPRISE_ID	0x0001
47b8265621SJacob Keller #define PLDM_DESC_ID_UUID		0x0002
48b8265621SJacob Keller #define PLDM_DESC_ID_PNP_VENDOR_ID	0x0003
49b8265621SJacob Keller #define PLDM_DESC_ID_ACPI_VENDOR_ID	0x0004
50b8265621SJacob Keller #define PLDM_DESC_ID_PCI_DEVICE_ID	0x0100
51b8265621SJacob Keller #define PLDM_DESC_ID_PCI_SUBVENDOR_ID	0x0101
52b8265621SJacob Keller #define PLDM_DESC_ID_PCI_SUBDEV_ID	0x0102
53b8265621SJacob Keller #define PLDM_DESC_ID_PCI_REVISION_ID	0x0103
54b8265621SJacob Keller #define PLDM_DESC_ID_PNP_PRODUCT_ID	0x0104
55b8265621SJacob Keller #define PLDM_DESC_ID_ACPI_PRODUCT_ID	0x0105
56b8265621SJacob Keller #define PLDM_DESC_ID_VENDOR_DEFINED	0xFFFF
57b8265621SJacob Keller 
58b8265621SJacob Keller struct pldmfw_desc_tlv {
59b8265621SJacob Keller 	struct list_head entry;
60b8265621SJacob Keller 
61b8265621SJacob Keller 	const u8 *data;
62b8265621SJacob Keller 	u16 type;
63b8265621SJacob Keller 	u16 size;
64b8265621SJacob Keller };
65b8265621SJacob Keller 
66b8265621SJacob Keller #define PLDM_CLASSIFICATION_UNKNOWN		0x0000
67b8265621SJacob Keller #define PLDM_CLASSIFICATION_OTHER		0x0001
68b8265621SJacob Keller #define PLDM_CLASSIFICATION_DRIVER		0x0002
69b8265621SJacob Keller #define PLDM_CLASSIFICATION_CONFIG_SW		0x0003
70b8265621SJacob Keller #define PLDM_CLASSIFICATION_APP_SW		0x0004
71b8265621SJacob Keller #define PLDM_CLASSIFICATION_INSTRUMENTATION	0x0005
72b8265621SJacob Keller #define PLDM_CLASSIFICATION_BIOS		0x0006
73b8265621SJacob Keller #define PLDM_CLASSIFICATION_DIAGNOSTIC_SW	0x0007
74b8265621SJacob Keller #define PLDM_CLASSIFICATION_OS			0x0008
75b8265621SJacob Keller #define PLDM_CLASSIFICATION_MIDDLEWARE		0x0009
76b8265621SJacob Keller #define PLDM_CLASSIFICATION_FIRMWARE		0x000A
77b8265621SJacob Keller #define PLDM_CLASSIFICATION_CODE		0x000B
78b8265621SJacob Keller #define PLDM_CLASSIFICATION_SERVICE_PACK	0x000C
79b8265621SJacob Keller #define PLDM_CLASSIFICATION_SOFTWARE_BUNDLE	0x000D
80b8265621SJacob Keller 
81b8265621SJacob Keller #define PLDM_ACTIVATION_METHOD_AUTO		BIT(0)
82b8265621SJacob Keller #define PLDM_ACTIVATION_METHOD_SELF_CONTAINED	BIT(1)
83b8265621SJacob Keller #define PLDM_ACTIVATION_METHOD_MEDIUM_SPECIFIC	BIT(2)
84b8265621SJacob Keller #define PLDM_ACTIVATION_METHOD_REBOOT		BIT(3)
85b8265621SJacob Keller #define PLDM_ACTIVATION_METHOD_DC_CYCLE		BIT(4)
86b8265621SJacob Keller #define PLDM_ACTIVATION_METHOD_AC_CYCLE		BIT(5)
87b8265621SJacob Keller 
88b8265621SJacob Keller #define PLDMFW_COMPONENT_OPTION_FORCE_UPDATE		BIT(0)
89b8265621SJacob Keller #define PLDMFW_COMPONENT_OPTION_USE_COMPARISON_STAMP	BIT(1)
90b8265621SJacob Keller 
91b8265621SJacob Keller struct pldmfw_component {
92b8265621SJacob Keller 	struct list_head entry;
93b8265621SJacob Keller 
94b8265621SJacob Keller 	/* component identifier */
95b8265621SJacob Keller 	u16 classification;
96b8265621SJacob Keller 	u16 identifier;
97b8265621SJacob Keller 
98b8265621SJacob Keller 	u16 options;
99b8265621SJacob Keller 	u16 activation_method;
100b8265621SJacob Keller 
101b8265621SJacob Keller 	u32 comparison_stamp;
102b8265621SJacob Keller 
103b8265621SJacob Keller 	u32 component_size;
104b8265621SJacob Keller 	const u8 *component_data;
105b8265621SJacob Keller 
106b8265621SJacob Keller 	/* Component version string */
107b8265621SJacob Keller 	const u8 *version_string;
108b8265621SJacob Keller 	u8 version_type;
109b8265621SJacob Keller 	u8 version_len;
110b8265621SJacob Keller 
111b8265621SJacob Keller 	/* component index */
112b8265621SJacob Keller 	u8 index;
113b8265621SJacob Keller 
114b8265621SJacob Keller };
115b8265621SJacob Keller 
116b8265621SJacob Keller /* Transfer flag used for sending components to the firmware */
117b8265621SJacob Keller #define PLDM_TRANSFER_FLAG_START		BIT(0)
118b8265621SJacob Keller #define PLDM_TRANSFER_FLAG_MIDDLE		BIT(1)
119b8265621SJacob Keller #define PLDM_TRANSFER_FLAG_END			BIT(2)
120b8265621SJacob Keller 
121b8265621SJacob Keller struct pldmfw_ops;
122b8265621SJacob Keller 
123b8265621SJacob Keller /* Main entry point to the PLDM firmware update engine. Device drivers
124b8265621SJacob Keller  * should embed this in a private structure and use container_of to obtain
125b8265621SJacob Keller  * a pointer to their own data, used to implement the device specific
126b8265621SJacob Keller  * operations.
127b8265621SJacob Keller  */
128b8265621SJacob Keller struct pldmfw {
129b8265621SJacob Keller 	const struct pldmfw_ops *ops;
130b8265621SJacob Keller 	struct device *dev;
131b8265621SJacob Keller };
132b8265621SJacob Keller 
133b8265621SJacob Keller bool pldmfw_op_pci_match_record(struct pldmfw *context, struct pldmfw_record *record);
134b8265621SJacob Keller 
135b8265621SJacob Keller /* Operations invoked by the generic PLDM firmware update engine. Used to
136b8265621SJacob Keller  * implement device specific logic.
137b8265621SJacob Keller  *
138b8265621SJacob Keller  * @match_record: check if the device matches the given record. For
139b8265621SJacob Keller  * convenience, a standard implementation is provided for PCI devices.
140b8265621SJacob Keller  *
141b8265621SJacob Keller  * @send_package_data: send the package data associated with the matching
142b8265621SJacob Keller  * record to firmware.
143b8265621SJacob Keller  *
144b8265621SJacob Keller  * @send_component_table: send the component data associated with a given
145b8265621SJacob Keller  * component to firmware. Called once for each applicable component.
146b8265621SJacob Keller  *
147b8265621SJacob Keller  * @flash_component: Flash the data for a given component to the device.
148b8265621SJacob Keller  * Called once for each applicable component, after all component tables have
149b8265621SJacob Keller  * been sent.
150b8265621SJacob Keller  *
151b8265621SJacob Keller  * @finalize_update: (optional) Finish the update. Called after all components
152b8265621SJacob Keller  * have been flashed.
153b8265621SJacob Keller  */
154b8265621SJacob Keller struct pldmfw_ops {
155b8265621SJacob Keller 	bool (*match_record)(struct pldmfw *context, struct pldmfw_record *record);
156b8265621SJacob Keller 	int (*send_package_data)(struct pldmfw *context, const u8 *data, u16 length);
157b8265621SJacob Keller 	int (*send_component_table)(struct pldmfw *context, struct pldmfw_component *component,
158b8265621SJacob Keller 				    u8 transfer_flag);
159b8265621SJacob Keller 	int (*flash_component)(struct pldmfw *context, struct pldmfw_component *component);
160b8265621SJacob Keller 	int (*finalize_update)(struct pldmfw *context);
161b8265621SJacob Keller };
162b8265621SJacob Keller 
163b8265621SJacob Keller int pldmfw_flash_image(struct pldmfw *context, const struct firmware *fw);
164b8265621SJacob Keller 
165b8265621SJacob Keller #endif
166