net/sfc/base: implement proxy auth MCDI event handling
[dpdk.git] / drivers / net / sfc / base / efx_mcdi.h
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
13 #if EFSYS_OPT_NAMES
14 #include "efx_regs_mcdi_strs.h"
15 #endif /* EFSYS_OPT_NAMES */
16
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 #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
91 extern                  void
92 efx_mcdi_ev_proxy_request(
93         __in            efx_nic_t *enp,
94         __in            unsigned int index);
95 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
96
97 extern                  void
98 efx_mcdi_ev_death(
99         __in            efx_nic_t *enp,
100         __in            int rc);
101
102 extern  __checkReturn   efx_rc_t
103 efx_mcdi_request_errcode(
104         __in            unsigned int err);
105
106 extern                  void
107 efx_mcdi_raise_exception(
108         __in            efx_nic_t *enp,
109         __in_opt        efx_mcdi_req_t *emrp,
110         __in            int rc);
111
112 typedef enum efx_mcdi_boot_e {
113         EFX_MCDI_BOOT_PRIMARY,
114         EFX_MCDI_BOOT_SECONDARY,
115         EFX_MCDI_BOOT_ROM,
116 } efx_mcdi_boot_t;
117
118 extern  __checkReturn           efx_rc_t
119 efx_mcdi_version(
120         __in                    efx_nic_t *enp,
121         __out_ecount_opt(4)     uint16_t versionp[4],
122         __out_opt               uint32_t *buildp,
123         __out_opt               efx_mcdi_boot_t *statusp);
124
125 extern  __checkReturn   efx_rc_t
126 efx_mcdi_get_capabilities(
127         __in            efx_nic_t *enp,
128         __out_opt       uint32_t *flagsp,
129         __out_opt       uint16_t *rx_dpcpu_fw_idp,
130         __out_opt       uint16_t *tx_dpcpu_fw_idp,
131         __out_opt       uint32_t *flags2p,
132         __out_opt       uint32_t *tso2ncp);
133
134 extern  __checkReturn           efx_rc_t
135 efx_mcdi_read_assertion(
136         __in                    efx_nic_t *enp);
137
138 extern  __checkReturn           efx_rc_t
139 efx_mcdi_exit_assertion_handler(
140         __in                    efx_nic_t *enp);
141
142 extern  __checkReturn           efx_rc_t
143 efx_mcdi_drv_attach(
144         __in                    efx_nic_t *enp,
145         __in                    boolean_t attach);
146
147 extern  __checkReturn           efx_rc_t
148 efx_mcdi_get_board_cfg(
149         __in                    efx_nic_t *enp,
150         __out_opt               uint32_t *board_typep,
151         __out_opt               efx_dword_t *capabilitiesp,
152         __out_ecount_opt(6)     uint8_t mac_addrp[6]);
153
154 extern  __checkReturn           efx_rc_t
155 efx_mcdi_get_phy_cfg(
156         __in                    efx_nic_t *enp);
157
158 extern  __checkReturn           efx_rc_t
159 efx_mcdi_firmware_update_supported(
160         __in                    efx_nic_t *enp,
161         __out                   boolean_t *supportedp);
162
163 extern  __checkReturn           efx_rc_t
164 efx_mcdi_macaddr_change_supported(
165         __in                    efx_nic_t *enp,
166         __out                   boolean_t *supportedp);
167
168 extern  __checkReturn           efx_rc_t
169 efx_mcdi_link_control_supported(
170         __in                    efx_nic_t *enp,
171         __out                   boolean_t *supportedp);
172
173 extern  __checkReturn           efx_rc_t
174 efx_mcdi_mac_spoofing_supported(
175         __in                    efx_nic_t *enp,
176         __out                   boolean_t *supportedp);
177
178
179 #if EFSYS_OPT_BIST
180 #if EFX_OPTS_EF10()
181 extern  __checkReturn           efx_rc_t
182 efx_mcdi_bist_enable_offline(
183         __in                    efx_nic_t *enp);
184 #endif /* EFX_OPTS_EF10() */
185 extern  __checkReturn           efx_rc_t
186 efx_mcdi_bist_start(
187         __in                    efx_nic_t *enp,
188         __in                    efx_bist_type_t type);
189 #endif /* EFSYS_OPT_BIST */
190
191 extern  __checkReturn           efx_rc_t
192 efx_mcdi_get_resource_limits(
193         __in                    efx_nic_t *enp,
194         __out_opt               uint32_t *nevqp,
195         __out_opt               uint32_t *nrxqp,
196         __out_opt               uint32_t *ntxqp);
197
198 extern  __checkReturn   efx_rc_t
199 efx_mcdi_log_ctrl(
200         __in            efx_nic_t *enp);
201
202 extern  __checkReturn   efx_rc_t
203 efx_mcdi_mac_stats_clear(
204         __in            efx_nic_t *enp);
205
206 extern  __checkReturn   efx_rc_t
207 efx_mcdi_mac_stats_upload(
208         __in            efx_nic_t *enp,
209         __in            efsys_mem_t *esmp);
210
211 extern  __checkReturn   efx_rc_t
212 efx_mcdi_mac_stats_periodic(
213         __in            efx_nic_t *enp,
214         __in            efsys_mem_t *esmp,
215         __in            uint16_t period_ms,
216         __in            boolean_t events);
217
218
219 #if EFSYS_OPT_LOOPBACK
220 extern  __checkReturn   efx_rc_t
221 efx_mcdi_get_loopback_modes(
222         __in            efx_nic_t *enp);
223 #endif /* EFSYS_OPT_LOOPBACK */
224
225 extern  __checkReturn   efx_rc_t
226 efx_mcdi_phy_module_get_info(
227         __in                    efx_nic_t *enp,
228         __in                    uint8_t dev_addr,
229         __in                    size_t offset,
230         __in                    size_t len,
231         __out_bcount(len)       uint8_t *data);
232
233 #define MCDI_IN(_emr, _type, _ofst)                                     \
234         ((_type *)((_emr).emr_in_buf + (_ofst)))
235
236 #define MCDI_IN2(_emr, _type, _ofst)                                    \
237         MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST)
238
239 #define MCDI_IN_SET_BYTE(_emr, _ofst, _value)                           \
240         EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst),         \
241                 EFX_BYTE_0, _value)
242
243 #define MCDI_IN_SET_WORD(_emr, _ofst, _value)                           \
244         EFX_POPULATE_WORD_1(*MCDI_IN2(_emr, efx_word_t, _ofst),         \
245                 EFX_WORD_0, _value)
246
247 #define MCDI_IN_SET_DWORD(_emr, _ofst, _value)                          \
248         EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
249                 EFX_DWORD_0, _value)
250
251 #define MCDI_IN_SET_DWORD_FIELD(_emr, _ofst, _field, _value)            \
252         EFX_SET_DWORD_FIELD(*MCDI_IN2(_emr, efx_dword_t, _ofst),        \
253                 MC_CMD_ ## _field, _value)
254
255 #define MCDI_IN_POPULATE_DWORD_1(_emr, _ofst, _field1, _value1)         \
256         EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
257                 MC_CMD_ ## _field1, _value1)
258
259 #define MCDI_IN_POPULATE_DWORD_2(_emr, _ofst, _field1, _value1,         \
260                 _field2, _value2)                                       \
261         EFX_POPULATE_DWORD_2(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
262                 MC_CMD_ ## _field1, _value1,                            \
263                 MC_CMD_ ## _field2, _value2)
264
265 #define MCDI_IN_POPULATE_DWORD_3(_emr, _ofst, _field1, _value1,         \
266                 _field2, _value2, _field3, _value3)                     \
267         EFX_POPULATE_DWORD_3(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
268                 MC_CMD_ ## _field1, _value1,                            \
269                 MC_CMD_ ## _field2, _value2,                            \
270                 MC_CMD_ ## _field3, _value3)
271
272 #define MCDI_IN_POPULATE_DWORD_4(_emr, _ofst, _field1, _value1,         \
273                 _field2, _value2, _field3, _value3, _field4, _value4)   \
274         EFX_POPULATE_DWORD_4(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
275                 MC_CMD_ ## _field1, _value1,                            \
276                 MC_CMD_ ## _field2, _value2,                            \
277                 MC_CMD_ ## _field3, _value3,                            \
278                 MC_CMD_ ## _field4, _value4)
279
280 #define MCDI_IN_POPULATE_DWORD_5(_emr, _ofst, _field1, _value1,         \
281                 _field2, _value2, _field3, _value3, _field4, _value4,   \
282                 _field5, _value5)                                       \
283         EFX_POPULATE_DWORD_5(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
284                 MC_CMD_ ## _field1, _value1,                            \
285                 MC_CMD_ ## _field2, _value2,                            \
286                 MC_CMD_ ## _field3, _value3,                            \
287                 MC_CMD_ ## _field4, _value4,                            \
288                 MC_CMD_ ## _field5, _value5)
289
290 #define MCDI_IN_POPULATE_DWORD_6(_emr, _ofst, _field1, _value1,         \
291                 _field2, _value2, _field3, _value3, _field4, _value4,   \
292                 _field5, _value5, _field6, _value6)                     \
293         EFX_POPULATE_DWORD_6(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
294                 MC_CMD_ ## _field1, _value1,                            \
295                 MC_CMD_ ## _field2, _value2,                            \
296                 MC_CMD_ ## _field3, _value3,                            \
297                 MC_CMD_ ## _field4, _value4,                            \
298                 MC_CMD_ ## _field5, _value5,                            \
299                 MC_CMD_ ## _field6, _value6)
300
301 #define MCDI_IN_POPULATE_DWORD_7(_emr, _ofst, _field1, _value1,         \
302                 _field2, _value2, _field3, _value3, _field4, _value4,   \
303                 _field5, _value5, _field6, _value6, _field7, _value7)   \
304         EFX_POPULATE_DWORD_7(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
305                 MC_CMD_ ## _field1, _value1,                            \
306                 MC_CMD_ ## _field2, _value2,                            \
307                 MC_CMD_ ## _field3, _value3,                            \
308                 MC_CMD_ ## _field4, _value4,                            \
309                 MC_CMD_ ## _field5, _value5,                            \
310                 MC_CMD_ ## _field6, _value6,                            \
311                 MC_CMD_ ## _field7, _value7)
312
313 #define MCDI_IN_POPULATE_DWORD_8(_emr, _ofst, _field1, _value1,         \
314                 _field2, _value2, _field3, _value3, _field4, _value4,   \
315                 _field5, _value5, _field6, _value6, _field7, _value7,   \
316                 _field8, _value8)                                       \
317         EFX_POPULATE_DWORD_8(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
318                 MC_CMD_ ## _field1, _value1,                            \
319                 MC_CMD_ ## _field2, _value2,                            \
320                 MC_CMD_ ## _field3, _value3,                            \
321                 MC_CMD_ ## _field4, _value4,                            \
322                 MC_CMD_ ## _field5, _value5,                            \
323                 MC_CMD_ ## _field6, _value6,                            \
324                 MC_CMD_ ## _field7, _value7,                            \
325                 MC_CMD_ ## _field8, _value8)
326
327 #define MCDI_IN_POPULATE_DWORD_9(_emr, _ofst, _field1, _value1,         \
328                 _field2, _value2, _field3, _value3, _field4, _value4,   \
329                 _field5, _value5, _field6, _value6, _field7, _value7,   \
330                 _field8, _value8, _field9, _value9)                     \
331         EFX_POPULATE_DWORD_9(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
332                 MC_CMD_ ## _field1, _value1,                            \
333                 MC_CMD_ ## _field2, _value2,                            \
334                 MC_CMD_ ## _field3, _value3,                            \
335                 MC_CMD_ ## _field4, _value4,                            \
336                 MC_CMD_ ## _field5, _value5,                            \
337                 MC_CMD_ ## _field6, _value6,                            \
338                 MC_CMD_ ## _field7, _value7,                            \
339                 MC_CMD_ ## _field8, _value8,                            \
340                 MC_CMD_ ## _field9, _value9)
341
342 #define MCDI_IN_POPULATE_DWORD_10(_emr, _ofst, _field1, _value1,        \
343                 _field2, _value2, _field3, _value3, _field4, _value4,   \
344                 _field5, _value5, _field6, _value6, _field7, _value7,   \
345                 _field8, _value8, _field9, _value9, _field10, _value10) \
346         EFX_POPULATE_DWORD_10(*MCDI_IN2(_emr, efx_dword_t, _ofst),      \
347                 MC_CMD_ ## _field1, _value1,                            \
348                 MC_CMD_ ## _field2, _value2,                            \
349                 MC_CMD_ ## _field3, _value3,                            \
350                 MC_CMD_ ## _field4, _value4,                            \
351                 MC_CMD_ ## _field5, _value5,                            \
352                 MC_CMD_ ## _field6, _value6,                            \
353                 MC_CMD_ ## _field7, _value7,                            \
354                 MC_CMD_ ## _field8, _value8,                            \
355                 MC_CMD_ ## _field9, _value9,                            \
356                 MC_CMD_ ## _field10, _value10)
357
358 #define MCDI_OUT(_emr, _type, _ofst)                                    \
359         ((_type *)((_emr).emr_out_buf + (_ofst)))
360
361 #define MCDI_OUT2(_emr, _type, _ofst)                                   \
362         MCDI_OUT(_emr, _type, MC_CMD_ ## _ofst ## _OFST)
363
364 #define MCDI_OUT_BYTE(_emr, _ofst)                                      \
365         EFX_BYTE_FIELD(*MCDI_OUT2(_emr, efx_byte_t, _ofst),             \
366                     EFX_BYTE_0)
367
368 #define MCDI_OUT_WORD(_emr, _ofst)                                      \
369         EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst),             \
370                     EFX_WORD_0)
371
372 #define MCDI_OUT_WORD_FIELD(_emr, _ofst, _field)                        \
373         EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst),             \
374                        MC_CMD_ ## _field)
375
376 #define MCDI_OUT_DWORD(_emr, _ofst)                                     \
377         EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst),           \
378                         EFX_DWORD_0)
379
380 #define MCDI_OUT_DWORD_FIELD(_emr, _ofst, _field)                       \
381         EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst),           \
382                         MC_CMD_ ## _field)
383
384 #define MCDI_EV_FIELD(_eqp, _field)                                     \
385         EFX_QWORD_FIELD(*_eqp, MCDI_EVENT_ ## _field)
386
387 #define MCDI_CMD_DWORD_FIELD(_edp, _field)                              \
388         EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field)
389
390 #define EFX_MCDI_HAVE_PRIVILEGE(mask, priv)                             \
391         (((mask) & (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) ==          \
392         (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv))
393
394 /*
395  * The buffer size must be a multiple of dword to ensure that MCDI works
396  * properly with Siena based boards (which use on-chip buffer). Also, it
397  * should be at minimum the size of two dwords to allow space for extended
398  * error responses if the request/response buffer sizes are smaller.
399  */
400 #define EFX_MCDI_DECLARE_BUF(_name, _in_len, _out_len)                  \
401         uint8_t _name[P2ROUNDUP(MAX(MAX(_in_len, _out_len),             \
402                                     (2 * sizeof (efx_dword_t))),        \
403                                 sizeof (efx_dword_t))] = {0}
404
405 typedef enum efx_mcdi_feature_id_e {
406         EFX_MCDI_FEATURE_FW_UPDATE = 0,
407         EFX_MCDI_FEATURE_LINK_CONTROL,
408         EFX_MCDI_FEATURE_MACADDR_CHANGE,
409         EFX_MCDI_FEATURE_MAC_SPOOFING,
410         EFX_MCDI_FEATURE_NIDS
411 } efx_mcdi_feature_id_t;
412
413 #ifdef  __cplusplus
414 }
415 #endif
416
417 #endif  /* _SYS_EFX_MCDI_H */