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