]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * | |
3 | * Copyright (c) 2009-2018 Solarflare Communications Inc. | |
4 | * All rights reserved. | |
5 | */ | |
6 | ||
7 | #ifndef _SYS_EFX_MCDI_H | |
8 | #define _SYS_EFX_MCDI_H | |
9 | ||
10 | #include "efx.h" | |
11 | #include "efx_regs_mcdi.h" | |
12 | ||
9f95a23c TL |
13 | #if EFSYS_OPT_NAMES |
14 | #include "efx_regs_mcdi_strs.h" | |
15 | #endif /* EFSYS_OPT_NAMES */ | |
16 | ||
11fdf7f2 TL |
17 | #ifdef __cplusplus |
18 | extern "C" { | |
19 | #endif | |
20 | ||
21 | /* | |
22 | * A reboot/assertion causes the MCDI status word to be set after the | |
23 | * command word is set or a REBOOT event is sent. If we notice a reboot | |
24 | * via these mechanisms then wait 10ms for the status word to be set. | |
25 | */ | |
26 | #define EFX_MCDI_STATUS_SLEEP_US 10000 | |
27 | ||
28 | struct efx_mcdi_req_s { | |
29 | boolean_t emr_quiet; | |
30 | /* Inputs: Command #, input buffer and length */ | |
31 | unsigned int emr_cmd; | |
32 | uint8_t *emr_in_buf; | |
33 | size_t emr_in_length; | |
34 | /* Outputs: retcode, buffer, length, and length used */ | |
35 | efx_rc_t emr_rc; | |
36 | uint8_t *emr_out_buf; | |
37 | size_t emr_out_length; | |
38 | size_t emr_out_length_used; | |
39 | /* Internals: low level transport details */ | |
40 | unsigned int emr_err_code; | |
41 | unsigned int emr_err_arg; | |
42 | #if EFSYS_OPT_MCDI_PROXY_AUTH | |
43 | uint32_t emr_proxy_handle; | |
44 | #endif | |
45 | }; | |
46 | ||
47 | typedef struct efx_mcdi_iface_s { | |
48 | unsigned int emi_port; | |
49 | unsigned int emi_max_version; | |
50 | unsigned int emi_seq; | |
51 | efx_mcdi_req_t *emi_pending_req; | |
52 | boolean_t emi_ev_cpl; | |
53 | boolean_t emi_new_epoch; | |
54 | int emi_aborted; | |
55 | uint32_t emi_poll_cnt; | |
56 | uint32_t emi_mc_reboot_status; | |
57 | } efx_mcdi_iface_t; | |
58 | ||
59 | extern void | |
60 | efx_mcdi_execute( | |
61 | __in efx_nic_t *enp, | |
62 | __inout efx_mcdi_req_t *emrp); | |
63 | ||
64 | extern void | |
65 | efx_mcdi_execute_quiet( | |
66 | __in efx_nic_t *enp, | |
67 | __inout efx_mcdi_req_t *emrp); | |
68 | ||
69 | extern void | |
70 | efx_mcdi_ev_cpl( | |
71 | __in efx_nic_t *enp, | |
72 | __in unsigned int seq, | |
73 | __in unsigned int outlen, | |
74 | __in int errcode); | |
75 | ||
76 | #if EFSYS_OPT_MCDI_PROXY_AUTH | |
77 | extern __checkReturn efx_rc_t | |
78 | efx_mcdi_get_proxy_handle( | |
79 | __in efx_nic_t *enp, | |
80 | __in efx_mcdi_req_t *emrp, | |
81 | __out uint32_t *handlep); | |
82 | ||
83 | extern void | |
84 | efx_mcdi_ev_proxy_response( | |
85 | __in efx_nic_t *enp, | |
86 | __in unsigned int handle, | |
87 | __in unsigned int status); | |
88 | #endif | |
89 | ||
90 | extern void | |
91 | efx_mcdi_ev_death( | |
92 | __in efx_nic_t *enp, | |
93 | __in int rc); | |
94 | ||
95 | extern __checkReturn efx_rc_t | |
96 | efx_mcdi_request_errcode( | |
97 | __in unsigned int err); | |
98 | ||
99 | extern void | |
100 | efx_mcdi_raise_exception( | |
101 | __in efx_nic_t *enp, | |
102 | __in_opt efx_mcdi_req_t *emrp, | |
103 | __in int rc); | |
104 | ||
105 | typedef enum efx_mcdi_boot_e { | |
106 | EFX_MCDI_BOOT_PRIMARY, | |
107 | EFX_MCDI_BOOT_SECONDARY, | |
108 | EFX_MCDI_BOOT_ROM, | |
109 | } efx_mcdi_boot_t; | |
110 | ||
111 | extern __checkReturn efx_rc_t | |
112 | efx_mcdi_version( | |
113 | __in efx_nic_t *enp, | |
114 | __out_ecount_opt(4) uint16_t versionp[4], | |
115 | __out_opt uint32_t *buildp, | |
116 | __out_opt efx_mcdi_boot_t *statusp); | |
117 | ||
118 | extern __checkReturn efx_rc_t | |
119 | efx_mcdi_get_capabilities( | |
120 | __in efx_nic_t *enp, | |
121 | __out_opt uint32_t *flagsp, | |
122 | __out_opt uint16_t *rx_dpcpu_fw_idp, | |
123 | __out_opt uint16_t *tx_dpcpu_fw_idp, | |
124 | __out_opt uint32_t *flags2p, | |
125 | __out_opt uint32_t *tso2ncp); | |
126 | ||
127 | extern __checkReturn efx_rc_t | |
128 | efx_mcdi_read_assertion( | |
129 | __in efx_nic_t *enp); | |
130 | ||
131 | extern __checkReturn efx_rc_t | |
132 | efx_mcdi_exit_assertion_handler( | |
133 | __in efx_nic_t *enp); | |
134 | ||
135 | extern __checkReturn efx_rc_t | |
136 | efx_mcdi_drv_attach( | |
137 | __in efx_nic_t *enp, | |
138 | __in boolean_t attach); | |
139 | ||
140 | extern __checkReturn efx_rc_t | |
141 | efx_mcdi_get_board_cfg( | |
142 | __in efx_nic_t *enp, | |
143 | __out_opt uint32_t *board_typep, | |
144 | __out_opt efx_dword_t *capabilitiesp, | |
145 | __out_ecount_opt(6) uint8_t mac_addrp[6]); | |
146 | ||
147 | extern __checkReturn efx_rc_t | |
148 | efx_mcdi_get_phy_cfg( | |
149 | __in efx_nic_t *enp); | |
150 | ||
151 | extern __checkReturn efx_rc_t | |
152 | efx_mcdi_firmware_update_supported( | |
153 | __in efx_nic_t *enp, | |
154 | __out boolean_t *supportedp); | |
155 | ||
156 | extern __checkReturn efx_rc_t | |
157 | efx_mcdi_macaddr_change_supported( | |
158 | __in efx_nic_t *enp, | |
159 | __out boolean_t *supportedp); | |
160 | ||
161 | extern __checkReturn efx_rc_t | |
162 | efx_mcdi_link_control_supported( | |
163 | __in efx_nic_t *enp, | |
164 | __out boolean_t *supportedp); | |
165 | ||
166 | extern __checkReturn efx_rc_t | |
167 | efx_mcdi_mac_spoofing_supported( | |
168 | __in efx_nic_t *enp, | |
169 | __out boolean_t *supportedp); | |
170 | ||
171 | ||
172 | #if EFSYS_OPT_BIST | |
9f95a23c | 173 | #if EFX_OPTS_EF10() |
11fdf7f2 TL |
174 | extern __checkReturn efx_rc_t |
175 | efx_mcdi_bist_enable_offline( | |
176 | __in efx_nic_t *enp); | |
9f95a23c | 177 | #endif /* EFX_OPTS_EF10() */ |
11fdf7f2 TL |
178 | extern __checkReturn efx_rc_t |
179 | efx_mcdi_bist_start( | |
180 | __in efx_nic_t *enp, | |
181 | __in efx_bist_type_t type); | |
182 | #endif /* EFSYS_OPT_BIST */ | |
183 | ||
184 | extern __checkReturn efx_rc_t | |
185 | efx_mcdi_get_resource_limits( | |
186 | __in efx_nic_t *enp, | |
187 | __out_opt uint32_t *nevqp, | |
188 | __out_opt uint32_t *nrxqp, | |
189 | __out_opt uint32_t *ntxqp); | |
190 | ||
191 | extern __checkReturn efx_rc_t | |
192 | efx_mcdi_log_ctrl( | |
193 | __in efx_nic_t *enp); | |
194 | ||
195 | extern __checkReturn efx_rc_t | |
196 | efx_mcdi_mac_stats_clear( | |
197 | __in efx_nic_t *enp); | |
198 | ||
199 | extern __checkReturn efx_rc_t | |
200 | efx_mcdi_mac_stats_upload( | |
201 | __in efx_nic_t *enp, | |
202 | __in efsys_mem_t *esmp); | |
203 | ||
204 | extern __checkReturn efx_rc_t | |
205 | efx_mcdi_mac_stats_periodic( | |
206 | __in efx_nic_t *enp, | |
207 | __in efsys_mem_t *esmp, | |
208 | __in uint16_t period_ms, | |
209 | __in boolean_t events); | |
210 | ||
211 | ||
212 | #if EFSYS_OPT_LOOPBACK | |
213 | extern __checkReturn efx_rc_t | |
214 | efx_mcdi_get_loopback_modes( | |
215 | __in efx_nic_t *enp); | |
216 | #endif /* EFSYS_OPT_LOOPBACK */ | |
217 | ||
218 | extern __checkReturn efx_rc_t | |
219 | efx_mcdi_phy_module_get_info( | |
220 | __in efx_nic_t *enp, | |
221 | __in uint8_t dev_addr, | |
9f95a23c TL |
222 | __in size_t offset, |
223 | __in size_t len, | |
11fdf7f2 TL |
224 | __out_bcount(len) uint8_t *data); |
225 | ||
226 | #define MCDI_IN(_emr, _type, _ofst) \ | |
227 | ((_type *)((_emr).emr_in_buf + (_ofst))) | |
228 | ||
229 | #define MCDI_IN2(_emr, _type, _ofst) \ | |
230 | MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST) | |
231 | ||
232 | #define MCDI_IN_SET_BYTE(_emr, _ofst, _value) \ | |
233 | EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst), \ | |
234 | EFX_BYTE_0, _value) | |
235 | ||
236 | #define MCDI_IN_SET_WORD(_emr, _ofst, _value) \ | |
237 | EFX_POPULATE_WORD_1(*MCDI_IN2(_emr, efx_word_t, _ofst), \ | |
238 | EFX_WORD_0, _value) | |
239 | ||
240 | #define MCDI_IN_SET_DWORD(_emr, _ofst, _value) \ | |
241 | EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
242 | EFX_DWORD_0, _value) | |
243 | ||
244 | #define MCDI_IN_SET_DWORD_FIELD(_emr, _ofst, _field, _value) \ | |
245 | EFX_SET_DWORD_FIELD(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
246 | MC_CMD_ ## _field, _value) | |
247 | ||
248 | #define MCDI_IN_POPULATE_DWORD_1(_emr, _ofst, _field1, _value1) \ | |
249 | EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
250 | MC_CMD_ ## _field1, _value1) | |
251 | ||
252 | #define MCDI_IN_POPULATE_DWORD_2(_emr, _ofst, _field1, _value1, \ | |
253 | _field2, _value2) \ | |
254 | EFX_POPULATE_DWORD_2(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
255 | MC_CMD_ ## _field1, _value1, \ | |
256 | MC_CMD_ ## _field2, _value2) | |
257 | ||
258 | #define MCDI_IN_POPULATE_DWORD_3(_emr, _ofst, _field1, _value1, \ | |
259 | _field2, _value2, _field3, _value3) \ | |
260 | EFX_POPULATE_DWORD_3(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
261 | MC_CMD_ ## _field1, _value1, \ | |
262 | MC_CMD_ ## _field2, _value2, \ | |
263 | MC_CMD_ ## _field3, _value3) | |
264 | ||
265 | #define MCDI_IN_POPULATE_DWORD_4(_emr, _ofst, _field1, _value1, \ | |
266 | _field2, _value2, _field3, _value3, _field4, _value4) \ | |
267 | EFX_POPULATE_DWORD_4(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
268 | MC_CMD_ ## _field1, _value1, \ | |
269 | MC_CMD_ ## _field2, _value2, \ | |
270 | MC_CMD_ ## _field3, _value3, \ | |
271 | MC_CMD_ ## _field4, _value4) | |
272 | ||
273 | #define MCDI_IN_POPULATE_DWORD_5(_emr, _ofst, _field1, _value1, \ | |
274 | _field2, _value2, _field3, _value3, _field4, _value4, \ | |
275 | _field5, _value5) \ | |
276 | EFX_POPULATE_DWORD_5(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
277 | MC_CMD_ ## _field1, _value1, \ | |
278 | MC_CMD_ ## _field2, _value2, \ | |
279 | MC_CMD_ ## _field3, _value3, \ | |
280 | MC_CMD_ ## _field4, _value4, \ | |
281 | MC_CMD_ ## _field5, _value5) | |
282 | ||
283 | #define MCDI_IN_POPULATE_DWORD_6(_emr, _ofst, _field1, _value1, \ | |
284 | _field2, _value2, _field3, _value3, _field4, _value4, \ | |
285 | _field5, _value5, _field6, _value6) \ | |
286 | EFX_POPULATE_DWORD_6(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
287 | MC_CMD_ ## _field1, _value1, \ | |
288 | MC_CMD_ ## _field2, _value2, \ | |
289 | MC_CMD_ ## _field3, _value3, \ | |
290 | MC_CMD_ ## _field4, _value4, \ | |
291 | MC_CMD_ ## _field5, _value5, \ | |
292 | MC_CMD_ ## _field6, _value6) | |
293 | ||
294 | #define MCDI_IN_POPULATE_DWORD_7(_emr, _ofst, _field1, _value1, \ | |
295 | _field2, _value2, _field3, _value3, _field4, _value4, \ | |
296 | _field5, _value5, _field6, _value6, _field7, _value7) \ | |
297 | EFX_POPULATE_DWORD_7(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
298 | MC_CMD_ ## _field1, _value1, \ | |
299 | MC_CMD_ ## _field2, _value2, \ | |
300 | MC_CMD_ ## _field3, _value3, \ | |
301 | MC_CMD_ ## _field4, _value4, \ | |
302 | MC_CMD_ ## _field5, _value5, \ | |
303 | MC_CMD_ ## _field6, _value6, \ | |
304 | MC_CMD_ ## _field7, _value7) | |
305 | ||
306 | #define MCDI_IN_POPULATE_DWORD_8(_emr, _ofst, _field1, _value1, \ | |
307 | _field2, _value2, _field3, _value3, _field4, _value4, \ | |
308 | _field5, _value5, _field6, _value6, _field7, _value7, \ | |
309 | _field8, _value8) \ | |
310 | EFX_POPULATE_DWORD_8(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
311 | MC_CMD_ ## _field1, _value1, \ | |
312 | MC_CMD_ ## _field2, _value2, \ | |
313 | MC_CMD_ ## _field3, _value3, \ | |
314 | MC_CMD_ ## _field4, _value4, \ | |
315 | MC_CMD_ ## _field5, _value5, \ | |
316 | MC_CMD_ ## _field6, _value6, \ | |
317 | MC_CMD_ ## _field7, _value7, \ | |
318 | MC_CMD_ ## _field8, _value8) | |
319 | ||
320 | #define MCDI_IN_POPULATE_DWORD_9(_emr, _ofst, _field1, _value1, \ | |
321 | _field2, _value2, _field3, _value3, _field4, _value4, \ | |
322 | _field5, _value5, _field6, _value6, _field7, _value7, \ | |
323 | _field8, _value8, _field9, _value9) \ | |
324 | EFX_POPULATE_DWORD_9(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
325 | MC_CMD_ ## _field1, _value1, \ | |
326 | MC_CMD_ ## _field2, _value2, \ | |
327 | MC_CMD_ ## _field3, _value3, \ | |
328 | MC_CMD_ ## _field4, _value4, \ | |
329 | MC_CMD_ ## _field5, _value5, \ | |
330 | MC_CMD_ ## _field6, _value6, \ | |
331 | MC_CMD_ ## _field7, _value7, \ | |
332 | MC_CMD_ ## _field8, _value8, \ | |
333 | MC_CMD_ ## _field9, _value9) | |
334 | ||
335 | #define MCDI_IN_POPULATE_DWORD_10(_emr, _ofst, _field1, _value1, \ | |
336 | _field2, _value2, _field3, _value3, _field4, _value4, \ | |
337 | _field5, _value5, _field6, _value6, _field7, _value7, \ | |
338 | _field8, _value8, _field9, _value9, _field10, _value10) \ | |
339 | EFX_POPULATE_DWORD_10(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ | |
340 | MC_CMD_ ## _field1, _value1, \ | |
341 | MC_CMD_ ## _field2, _value2, \ | |
342 | MC_CMD_ ## _field3, _value3, \ | |
343 | MC_CMD_ ## _field4, _value4, \ | |
344 | MC_CMD_ ## _field5, _value5, \ | |
345 | MC_CMD_ ## _field6, _value6, \ | |
346 | MC_CMD_ ## _field7, _value7, \ | |
347 | MC_CMD_ ## _field8, _value8, \ | |
348 | MC_CMD_ ## _field9, _value9, \ | |
349 | MC_CMD_ ## _field10, _value10) | |
350 | ||
351 | #define MCDI_OUT(_emr, _type, _ofst) \ | |
352 | ((_type *)((_emr).emr_out_buf + (_ofst))) | |
353 | ||
354 | #define MCDI_OUT2(_emr, _type, _ofst) \ | |
355 | MCDI_OUT(_emr, _type, MC_CMD_ ## _ofst ## _OFST) | |
356 | ||
357 | #define MCDI_OUT_BYTE(_emr, _ofst) \ | |
358 | EFX_BYTE_FIELD(*MCDI_OUT2(_emr, efx_byte_t, _ofst), \ | |
359 | EFX_BYTE_0) | |
360 | ||
361 | #define MCDI_OUT_WORD(_emr, _ofst) \ | |
362 | EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst), \ | |
363 | EFX_WORD_0) | |
364 | ||
365 | #define MCDI_OUT_WORD_FIELD(_emr, _ofst, _field) \ | |
366 | EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst), \ | |
367 | MC_CMD_ ## _field) | |
368 | ||
369 | #define MCDI_OUT_DWORD(_emr, _ofst) \ | |
370 | EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst), \ | |
371 | EFX_DWORD_0) | |
372 | ||
373 | #define MCDI_OUT_DWORD_FIELD(_emr, _ofst, _field) \ | |
374 | EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst), \ | |
375 | MC_CMD_ ## _field) | |
376 | ||
377 | #define MCDI_EV_FIELD(_eqp, _field) \ | |
378 | EFX_QWORD_FIELD(*_eqp, MCDI_EVENT_ ## _field) | |
379 | ||
380 | #define MCDI_CMD_DWORD_FIELD(_edp, _field) \ | |
381 | EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field) | |
382 | ||
383 | #define EFX_MCDI_HAVE_PRIVILEGE(mask, priv) \ | |
384 | (((mask) & (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) == \ | |
385 | (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) | |
386 | ||
9f95a23c TL |
387 | /* |
388 | * The buffer size must be a multiple of dword to ensure that MCDI works | |
389 | * properly with Siena based boards (which use on-chip buffer). Also, it | |
390 | * should be at minimum the size of two dwords to allow space for extended | |
391 | * error responses if the request/response buffer sizes are smaller. | |
392 | */ | |
393 | #define EFX_MCDI_DECLARE_BUF(_name, _in_len, _out_len) \ | |
394 | uint8_t _name[P2ROUNDUP(MAX(MAX(_in_len, _out_len), \ | |
395 | (2 * sizeof (efx_dword_t))), \ | |
396 | sizeof (efx_dword_t))] = {0} | |
397 | ||
11fdf7f2 TL |
398 | typedef enum efx_mcdi_feature_id_e { |
399 | EFX_MCDI_FEATURE_FW_UPDATE = 0, | |
400 | EFX_MCDI_FEATURE_LINK_CONTROL, | |
401 | EFX_MCDI_FEATURE_MACADDR_CHANGE, | |
402 | EFX_MCDI_FEATURE_MAC_SPOOFING, | |
403 | EFX_MCDI_FEATURE_NIDS | |
404 | } efx_mcdi_feature_id_t; | |
405 | ||
406 | #ifdef __cplusplus | |
407 | } | |
408 | #endif | |
409 | ||
410 | #endif /* _SYS_EFX_MCDI_H */ |