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