xref: /openbmc/linux/drivers/net/wireless/ath/wil6210/fw.h (revision 60772e48)
1 /*
2  * Copyright (c) 2014,2016 Qualcomm Atheros, Inc.
3  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #define WIL_FW_SIGNATURE (0x36323130) /* '0126' */
19 #define WIL_FW_FMT_VERSION (1) /* format version driver supports */
20 
21 enum wil_fw_record_type {
22 	wil_fw_type_comment = 1,
23 	wil_fw_type_data = 2,
24 	wil_fw_type_fill = 3,
25 	wil_fw_type_action = 4,
26 	wil_fw_type_verify = 5,
27 	wil_fw_type_file_header = 6,
28 	wil_fw_type_direct_write = 7,
29 	wil_fw_type_gateway_data = 8,
30 	wil_fw_type_gateway_data4 = 9,
31 };
32 
33 struct wil_fw_record_head {
34 	__le16 type; /* enum wil_fw_record_type */
35 	__le16 flags; /* to be defined */
36 	__le32 size; /* whole record, bytes after head */
37 } __packed;
38 
39 /* data block. write starting from @addr
40  * data_size inferred from the @head.size. For this case,
41  * data_size = @head.size - offsetof(struct wil_fw_record_data, data)
42  */
43 struct wil_fw_record_data { /* type == wil_fw_type_data */
44 	__le32 addr;
45 	__le32 data[0]; /* [data_size], see above */
46 } __packed;
47 
48 /* fill with constant @value, @size bytes starting from @addr */
49 struct wil_fw_record_fill { /* type == wil_fw_type_fill */
50 	__le32 addr;
51 	__le32 value;
52 	__le32 size;
53 } __packed;
54 
55 /* free-form comment
56  * for informational purpose, data_size is @head.size from record header
57  */
58 struct wil_fw_record_comment { /* type == wil_fw_type_comment */
59 	u8 data[0]; /* free-form data [data_size], see above */
60 } __packed;
61 
62 /* Comment header - common for all comment record types */
63 struct wil_fw_record_comment_hdr {
64 	__le32 magic;
65 };
66 
67 /* FW capabilities encoded inside a comment record */
68 #define WIL_FW_CAPABILITIES_MAGIC (0xabcddcba)
69 struct wil_fw_record_capabilities { /* type == wil_fw_type_comment */
70 	/* identifies capabilities record */
71 	struct wil_fw_record_comment_hdr hdr;
72 	/* capabilities (variable size), see enum wmi_fw_capability */
73 	u8 capabilities[0];
74 };
75 
76 /* brd file info encoded inside a comment record */
77 #define WIL_BRD_FILE_MAGIC (0xabcddcbb)
78 struct wil_fw_record_brd_file { /* type == wil_fw_type_comment */
79 	/* identifies brd file record */
80 	struct wil_fw_record_comment_hdr hdr;
81 	__le32 version;
82 	__le32 base_addr;
83 	__le32 max_size_bytes;
84 } __packed;
85 
86 /* perform action
87  * data_size = @head.size - offsetof(struct wil_fw_record_action, data)
88  */
89 struct wil_fw_record_action { /* type == wil_fw_type_action */
90 	__le32 action; /* action to perform: reset, wait for fw ready etc. */
91 	__le32 data[0]; /* action specific, [data_size], see above */
92 } __packed;
93 
94 /* data block for struct wil_fw_record_direct_write */
95 struct wil_fw_data_dwrite {
96 	__le32 addr;
97 	__le32 value;
98 	__le32 mask;
99 } __packed;
100 
101 /* write @value to the @addr,
102  * preserve original bits accordingly to the @mask
103  * data_size is @head.size where @head is record header
104  */
105 struct wil_fw_record_direct_write { /* type == wil_fw_type_direct_write */
106 	struct wil_fw_data_dwrite data[0];
107 } __packed;
108 
109 /* verify condition: [@addr] & @mask == @value
110  * if condition not met, firmware download fails
111  */
112 struct wil_fw_record_verify { /* type == wil_fw_verify */
113 	__le32 addr; /* read from this address */
114 	__le32 value; /* reference value */
115 	__le32 mask; /* mask for verification */
116 } __packed;
117 
118 /* file header
119  * First record of every file
120  */
121 /* the FW version prefix in the comment */
122 #define WIL_FW_VERSION_PREFIX "FW version: "
123 #define WIL_FW_VERSION_PREFIX_LEN (sizeof(WIL_FW_VERSION_PREFIX) - 1)
124 struct wil_fw_record_file_header {
125 	__le32 signature ; /* Wilocity signature */
126 	__le32 reserved;
127 	__le32 crc; /* crc32 of the following data  */
128 	__le32 version; /* format version */
129 	__le32 data_len; /* total data in file, including this record */
130 	u8 comment[32]; /* short description */
131 } __packed;
132 
133 /* 1-dword gateway */
134 /* data block for the struct wil_fw_record_gateway_data */
135 struct wil_fw_data_gw {
136 	__le32 addr;
137 	__le32 value;
138 } __packed;
139 
140 /* gateway write block.
141  * write starting address and values from the data buffer
142  * through the gateway
143  * data_size inferred from the @head.size. For this case,
144  * data_size = @head.size - offsetof(struct wil_fw_record_gateway_data, data)
145  */
146 struct wil_fw_record_gateway_data { /* type == wil_fw_type_gateway_data */
147 	__le32 gateway_addr_addr;
148 	__le32 gateway_value_addr;
149 	__le32 gateway_cmd_addr;
150 	__le32 gateway_ctrl_address;
151 #define WIL_FW_GW_CTL_BUSY	BIT(29) /* gateway busy performing operation */
152 #define WIL_FW_GW_CTL_RUN	BIT(30) /* start gateway operation */
153 	__le32 command;
154 	struct wil_fw_data_gw data[0]; /* total size [data_size], see above */
155 } __packed;
156 
157 /* 4-dword gateway */
158 /* data block for the struct wil_fw_record_gateway_data4 */
159 struct wil_fw_data_gw4 {
160 	__le32 addr;
161 	__le32 value[4];
162 } __packed;
163 
164 /* gateway write block.
165  * write starting address and values from the data buffer
166  * through the gateway
167  * data_size inferred from the @head.size. For this case,
168  * data_size = @head.size - offsetof(struct wil_fw_record_gateway_data4, data)
169  */
170 struct wil_fw_record_gateway_data4 { /* type == wil_fw_type_gateway_data4 */
171 	__le32 gateway_addr_addr;
172 	__le32 gateway_value_addr[4];
173 	__le32 gateway_cmd_addr;
174 	__le32 gateway_ctrl_address; /* same logic as for 1-dword gw */
175 	__le32 command;
176 	struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */
177 } __packed;
178