]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sfxge/common/ef10_nic.c
sfxge(4): fix PreFAST warnings because of unused return
[FreeBSD/FreeBSD.git] / sys / dev / sfxge / common / ef10_nic.c
1 /*-
2  * Copyright (c) 2012-2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include "efx.h"
35 #include "efx_impl.h"
36 #if EFSYS_OPT_MON_MCDI
37 #include "mcdi_mon.h"
38 #endif
39
40 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
41
42 #include "ef10_tlv_layout.h"
43
44         __checkReturn   efx_rc_t
45 efx_mcdi_get_port_assignment(
46         __in            efx_nic_t *enp,
47         __out           uint32_t *portp)
48 {
49         efx_mcdi_req_t req;
50         uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
51                             MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
52         efx_rc_t rc;
53
54         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
55             enp->en_family == EFX_FAMILY_MEDFORD ||
56             enp->en_family == EFX_FAMILY_MEDFORD2);
57
58         (void) memset(payload, 0, sizeof (payload));
59         req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
60         req.emr_in_buf = payload;
61         req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
62         req.emr_out_buf = payload;
63         req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN;
64
65         efx_mcdi_execute(enp, &req);
66
67         if (req.emr_rc != 0) {
68                 rc = req.emr_rc;
69                 goto fail1;
70         }
71
72         if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) {
73                 rc = EMSGSIZE;
74                 goto fail2;
75         }
76
77         *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT);
78
79         return (0);
80
81 fail2:
82         EFSYS_PROBE(fail2);
83 fail1:
84         EFSYS_PROBE1(fail1, efx_rc_t, rc);
85
86         return (rc);
87 }
88
89         __checkReturn   efx_rc_t
90 efx_mcdi_get_port_modes(
91         __in            efx_nic_t *enp,
92         __out           uint32_t *modesp,
93         __out_opt       uint32_t *current_modep)
94 {
95         efx_mcdi_req_t req;
96         uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
97                             MC_CMD_GET_PORT_MODES_OUT_LEN)];
98         efx_rc_t rc;
99
100         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
101             enp->en_family == EFX_FAMILY_MEDFORD ||
102             enp->en_family == EFX_FAMILY_MEDFORD2);
103
104         (void) memset(payload, 0, sizeof (payload));
105         req.emr_cmd = MC_CMD_GET_PORT_MODES;
106         req.emr_in_buf = payload;
107         req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
108         req.emr_out_buf = payload;
109         req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN;
110
111         efx_mcdi_execute(enp, &req);
112
113         if (req.emr_rc != 0) {
114                 rc = req.emr_rc;
115                 goto fail1;
116         }
117
118         /*
119          * Require only Modes and DefaultMode fields, unless the current mode
120          * was requested (CurrentMode field was added for Medford).
121          */
122         if (req.emr_out_length_used <
123             MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) {
124                 rc = EMSGSIZE;
125                 goto fail2;
126         }
127         if ((current_modep != NULL) && (req.emr_out_length_used <
128             MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST + 4)) {
129                 rc = EMSGSIZE;
130                 goto fail3;
131         }
132
133         *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES);
134
135         if (current_modep != NULL) {
136                 *current_modep = MCDI_OUT_DWORD(req,
137                                             GET_PORT_MODES_OUT_CURRENT_MODE);
138         }
139
140         return (0);
141
142 fail3:
143         EFSYS_PROBE(fail3);
144 fail2:
145         EFSYS_PROBE(fail2);
146 fail1:
147         EFSYS_PROBE1(fail1, efx_rc_t, rc);
148
149         return (rc);
150 }
151
152         __checkReturn   efx_rc_t
153 ef10_nic_get_port_mode_bandwidth(
154         __in            uint32_t port_mode,
155         __out           uint32_t *bandwidth_mbpsp)
156 {
157         uint32_t bandwidth;
158         efx_rc_t rc;
159
160         switch (port_mode) {
161         case TLV_PORT_MODE_10G:
162                 bandwidth = 10000;
163                 break;
164         case TLV_PORT_MODE_10G_10G:
165                 bandwidth = 10000 * 2;
166                 break;
167         case TLV_PORT_MODE_10G_10G_10G_10G:
168         case TLV_PORT_MODE_10G_10G_10G_10G_Q:
169         case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2:
170         case TLV_PORT_MODE_10G_10G_10G_10G_Q2:
171                 bandwidth = 10000 * 4;
172                 break;
173         case TLV_PORT_MODE_40G:
174                 bandwidth = 40000;
175                 break;
176         case TLV_PORT_MODE_40G_40G:
177                 bandwidth = 40000 * 2;
178                 break;
179         case TLV_PORT_MODE_40G_10G_10G:
180         case TLV_PORT_MODE_10G_10G_40G:
181                 bandwidth = 40000 + (10000 * 2);
182                 break;
183         default:
184                 rc = EINVAL;
185                 goto fail1;
186         }
187
188         *bandwidth_mbpsp = bandwidth;
189
190         return (0);
191
192 fail1:
193         EFSYS_PROBE1(fail1, efx_rc_t, rc);
194
195         return (rc);
196 }
197
198 static  __checkReturn           efx_rc_t
199 efx_mcdi_vadaptor_alloc(
200         __in                    efx_nic_t *enp,
201         __in                    uint32_t port_id)
202 {
203         efx_mcdi_req_t req;
204         uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
205                             MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
206         efx_rc_t rc;
207
208         EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
209
210         (void) memset(payload, 0, sizeof (payload));
211         req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
212         req.emr_in_buf = payload;
213         req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
214         req.emr_out_buf = payload;
215         req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN;
216
217         MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id);
218         MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS,
219             VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED,
220             enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0);
221
222         efx_mcdi_execute(enp, &req);
223
224         if (req.emr_rc != 0) {
225                 rc = req.emr_rc;
226                 goto fail1;
227         }
228
229         return (0);
230
231 fail1:
232         EFSYS_PROBE1(fail1, efx_rc_t, rc);
233
234         return (rc);
235 }
236
237 static  __checkReturn           efx_rc_t
238 efx_mcdi_vadaptor_free(
239         __in                    efx_nic_t *enp,
240         __in                    uint32_t port_id)
241 {
242         efx_mcdi_req_t req;
243         uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
244                             MC_CMD_VADAPTOR_FREE_OUT_LEN)];
245         efx_rc_t rc;
246
247         (void) memset(payload, 0, sizeof (payload));
248         req.emr_cmd = MC_CMD_VADAPTOR_FREE;
249         req.emr_in_buf = payload;
250         req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
251         req.emr_out_buf = payload;
252         req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN;
253
254         MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id);
255
256         efx_mcdi_execute(enp, &req);
257
258         if (req.emr_rc != 0) {
259                 rc = req.emr_rc;
260                 goto fail1;
261         }
262
263         return (0);
264
265 fail1:
266         EFSYS_PROBE1(fail1, efx_rc_t, rc);
267
268         return (rc);
269 }
270
271         __checkReturn   efx_rc_t
272 efx_mcdi_get_mac_address_pf(
273         __in                    efx_nic_t *enp,
274         __out_ecount_opt(6)     uint8_t mac_addrp[6])
275 {
276         efx_mcdi_req_t req;
277         uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
278                             MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
279         efx_rc_t rc;
280
281         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
282             enp->en_family == EFX_FAMILY_MEDFORD ||
283             enp->en_family == EFX_FAMILY_MEDFORD2);
284
285         (void) memset(payload, 0, sizeof (payload));
286         req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
287         req.emr_in_buf = payload;
288         req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
289         req.emr_out_buf = payload;
290         req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
291
292         efx_mcdi_execute(enp, &req);
293
294         if (req.emr_rc != 0) {
295                 rc = req.emr_rc;
296                 goto fail1;
297         }
298
299         if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) {
300                 rc = EMSGSIZE;
301                 goto fail2;
302         }
303
304         if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) {
305                 rc = ENOENT;
306                 goto fail3;
307         }
308
309         if (mac_addrp != NULL) {
310                 uint8_t *addrp;
311
312                 addrp = MCDI_OUT2(req, uint8_t,
313                     GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE);
314
315                 EFX_MAC_ADDR_COPY(mac_addrp, addrp);
316         }
317
318         return (0);
319
320 fail3:
321         EFSYS_PROBE(fail3);
322 fail2:
323         EFSYS_PROBE(fail2);
324 fail1:
325         EFSYS_PROBE1(fail1, efx_rc_t, rc);
326
327         return (rc);
328 }
329
330         __checkReturn   efx_rc_t
331 efx_mcdi_get_mac_address_vf(
332         __in                    efx_nic_t *enp,
333         __out_ecount_opt(6)     uint8_t mac_addrp[6])
334 {
335         efx_mcdi_req_t req;
336         uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
337                             MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
338         efx_rc_t rc;
339
340         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
341             enp->en_family == EFX_FAMILY_MEDFORD ||
342             enp->en_family == EFX_FAMILY_MEDFORD2);
343
344         (void) memset(payload, 0, sizeof (payload));
345         req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
346         req.emr_in_buf = payload;
347         req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
348         req.emr_out_buf = payload;
349         req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX;
350
351         MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
352             EVB_PORT_ID_ASSIGNED);
353
354         efx_mcdi_execute(enp, &req);
355
356         if (req.emr_rc != 0) {
357                 rc = req.emr_rc;
358                 goto fail1;
359         }
360
361         if (req.emr_out_length_used <
362             MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) {
363                 rc = EMSGSIZE;
364                 goto fail2;
365         }
366
367         if (MCDI_OUT_DWORD(req,
368                 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) {
369                 rc = ENOENT;
370                 goto fail3;
371         }
372
373         if (mac_addrp != NULL) {
374                 uint8_t *addrp;
375
376                 addrp = MCDI_OUT2(req, uint8_t,
377                     VPORT_GET_MAC_ADDRESSES_OUT_MACADDR);
378
379                 EFX_MAC_ADDR_COPY(mac_addrp, addrp);
380         }
381
382         return (0);
383
384 fail3:
385         EFSYS_PROBE(fail3);
386 fail2:
387         EFSYS_PROBE(fail2);
388 fail1:
389         EFSYS_PROBE1(fail1, efx_rc_t, rc);
390
391         return (rc);
392 }
393
394         __checkReturn   efx_rc_t
395 efx_mcdi_get_clock(
396         __in            efx_nic_t *enp,
397         __out           uint32_t *sys_freqp,
398         __out           uint32_t *dpcpu_freqp)
399 {
400         efx_mcdi_req_t req;
401         uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
402                             MC_CMD_GET_CLOCK_OUT_LEN)];
403         efx_rc_t rc;
404
405         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
406             enp->en_family == EFX_FAMILY_MEDFORD ||
407             enp->en_family == EFX_FAMILY_MEDFORD2);
408
409         (void) memset(payload, 0, sizeof (payload));
410         req.emr_cmd = MC_CMD_GET_CLOCK;
411         req.emr_in_buf = payload;
412         req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
413         req.emr_out_buf = payload;
414         req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN;
415
416         efx_mcdi_execute(enp, &req);
417
418         if (req.emr_rc != 0) {
419                 rc = req.emr_rc;
420                 goto fail1;
421         }
422
423         if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) {
424                 rc = EMSGSIZE;
425                 goto fail2;
426         }
427
428         *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ);
429         if (*sys_freqp == 0) {
430                 rc = EINVAL;
431                 goto fail3;
432         }
433         *dpcpu_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_DPCPU_FREQ);
434         if (*dpcpu_freqp == 0) {
435                 rc = EINVAL;
436                 goto fail4;
437         }
438
439         return (0);
440
441 fail4:
442         EFSYS_PROBE(fail4);
443 fail3:
444         EFSYS_PROBE(fail3);
445 fail2:
446         EFSYS_PROBE(fail2);
447 fail1:
448         EFSYS_PROBE1(fail1, efx_rc_t, rc);
449
450         return (rc);
451 }
452
453         __checkReturn   efx_rc_t
454 efx_mcdi_get_rxdp_config(
455         __in            efx_nic_t *enp,
456         __out           uint32_t *end_paddingp)
457 {
458         efx_mcdi_req_t req;
459         uint8_t payload[MAX(MC_CMD_GET_RXDP_CONFIG_IN_LEN,
460                             MC_CMD_GET_RXDP_CONFIG_OUT_LEN)];
461         uint32_t end_padding;
462         efx_rc_t rc;
463
464         memset(payload, 0, sizeof (payload));
465         req.emr_cmd = MC_CMD_GET_RXDP_CONFIG;
466         req.emr_in_buf = payload;
467         req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN;
468         req.emr_out_buf = payload;
469         req.emr_out_length = MC_CMD_GET_RXDP_CONFIG_OUT_LEN;
470
471         efx_mcdi_execute(enp, &req);
472         if (req.emr_rc != 0) {
473                 rc = req.emr_rc;
474                 goto fail1;
475         }
476
477         if (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
478                                     GET_RXDP_CONFIG_OUT_PAD_HOST_DMA) == 0) {
479                 /* RX DMA end padding is disabled */
480                 end_padding = 0;
481         } else {
482                 switch (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
483                                             GET_RXDP_CONFIG_OUT_PAD_HOST_LEN)) {
484                 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64:
485                         end_padding = 64;
486                         break;
487                 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128:
488                         end_padding = 128;
489                         break;
490                 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256:
491                         end_padding = 256;
492                         break;
493                 default:
494                         rc = ENOTSUP;
495                         goto fail2;
496                 }
497         }
498
499         *end_paddingp = end_padding;
500
501         return (0);
502
503 fail2:
504         EFSYS_PROBE(fail2);
505 fail1:
506         EFSYS_PROBE1(fail1, efx_rc_t, rc);
507
508         return (rc);
509 }
510
511         __checkReturn   efx_rc_t
512 efx_mcdi_get_vector_cfg(
513         __in            efx_nic_t *enp,
514         __out_opt       uint32_t *vec_basep,
515         __out_opt       uint32_t *pf_nvecp,
516         __out_opt       uint32_t *vf_nvecp)
517 {
518         efx_mcdi_req_t req;
519         uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
520                             MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
521         efx_rc_t rc;
522
523         (void) memset(payload, 0, sizeof (payload));
524         req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
525         req.emr_in_buf = payload;
526         req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
527         req.emr_out_buf = payload;
528         req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN;
529
530         efx_mcdi_execute(enp, &req);
531
532         if (req.emr_rc != 0) {
533                 rc = req.emr_rc;
534                 goto fail1;
535         }
536
537         if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) {
538                 rc = EMSGSIZE;
539                 goto fail2;
540         }
541
542         if (vec_basep != NULL)
543                 *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE);
544         if (pf_nvecp != NULL)
545                 *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF);
546         if (vf_nvecp != NULL)
547                 *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF);
548
549         return (0);
550
551 fail2:
552         EFSYS_PROBE(fail2);
553 fail1:
554         EFSYS_PROBE1(fail1, efx_rc_t, rc);
555
556         return (rc);
557 }
558
559 static  __checkReturn   efx_rc_t
560 efx_mcdi_alloc_vis(
561         __in            efx_nic_t *enp,
562         __in            uint32_t min_vi_count,
563         __in            uint32_t max_vi_count,
564         __out           uint32_t *vi_basep,
565         __out           uint32_t *vi_countp,
566         __out           uint32_t *vi_shiftp)
567 {
568         efx_mcdi_req_t req;
569         uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
570                             MC_CMD_ALLOC_VIS_EXT_OUT_LEN)];
571         efx_rc_t rc;
572
573         if (vi_countp == NULL) {
574                 rc = EINVAL;
575                 goto fail1;
576         }
577
578         (void) memset(payload, 0, sizeof (payload));
579         req.emr_cmd = MC_CMD_ALLOC_VIS;
580         req.emr_in_buf = payload;
581         req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
582         req.emr_out_buf = payload;
583         req.emr_out_length = MC_CMD_ALLOC_VIS_EXT_OUT_LEN;
584
585         MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count);
586         MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count);
587
588         efx_mcdi_execute(enp, &req);
589
590         if (req.emr_rc != 0) {
591                 rc = req.emr_rc;
592                 goto fail2;
593         }
594
595         if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) {
596                 rc = EMSGSIZE;
597                 goto fail3;
598         }
599
600         *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE);
601         *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT);
602
603         /* Report VI_SHIFT if available (always zero for Huntington) */
604         if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN)
605                 *vi_shiftp = 0;
606         else
607                 *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT);
608
609         return (0);
610
611 fail3:
612         EFSYS_PROBE(fail3);
613 fail2:
614         EFSYS_PROBE(fail2);
615 fail1:
616         EFSYS_PROBE1(fail1, efx_rc_t, rc);
617
618         return (rc);
619 }
620
621
622 static  __checkReturn   efx_rc_t
623 efx_mcdi_free_vis(
624         __in            efx_nic_t *enp)
625 {
626         efx_mcdi_req_t req;
627         efx_rc_t rc;
628
629         EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0);
630         EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0);
631
632         req.emr_cmd = MC_CMD_FREE_VIS;
633         req.emr_in_buf = NULL;
634         req.emr_in_length = 0;
635         req.emr_out_buf = NULL;
636         req.emr_out_length = 0;
637
638         efx_mcdi_execute_quiet(enp, &req);
639
640         /* Ignore ELREADY (no allocated VIs, so nothing to free) */
641         if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) {
642                 rc = req.emr_rc;
643                 goto fail1;
644         }
645
646         return (0);
647
648 fail1:
649         EFSYS_PROBE1(fail1, efx_rc_t, rc);
650
651         return (rc);
652 }
653
654
655 static  __checkReturn   efx_rc_t
656 efx_mcdi_alloc_piobuf(
657         __in            efx_nic_t *enp,
658         __out           efx_piobuf_handle_t *handlep)
659 {
660         efx_mcdi_req_t req;
661         uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
662                             MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
663         efx_rc_t rc;
664
665         if (handlep == NULL) {
666                 rc = EINVAL;
667                 goto fail1;
668         }
669
670         (void) memset(payload, 0, sizeof (payload));
671         req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
672         req.emr_in_buf = payload;
673         req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
674         req.emr_out_buf = payload;
675         req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN;
676
677         efx_mcdi_execute_quiet(enp, &req);
678
679         if (req.emr_rc != 0) {
680                 rc = req.emr_rc;
681                 goto fail2;
682         }
683
684         if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) {
685                 rc = EMSGSIZE;
686                 goto fail3;
687         }
688
689         *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE);
690
691         return (0);
692
693 fail3:
694         EFSYS_PROBE(fail3);
695 fail2:
696         EFSYS_PROBE(fail2);
697 fail1:
698         EFSYS_PROBE1(fail1, efx_rc_t, rc);
699
700         return (rc);
701 }
702
703 static  __checkReturn   efx_rc_t
704 efx_mcdi_free_piobuf(
705         __in            efx_nic_t *enp,
706         __in            efx_piobuf_handle_t handle)
707 {
708         efx_mcdi_req_t req;
709         uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
710                             MC_CMD_FREE_PIOBUF_OUT_LEN)];
711         efx_rc_t rc;
712
713         (void) memset(payload, 0, sizeof (payload));
714         req.emr_cmd = MC_CMD_FREE_PIOBUF;
715         req.emr_in_buf = payload;
716         req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
717         req.emr_out_buf = payload;
718         req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN;
719
720         MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle);
721
722         efx_mcdi_execute_quiet(enp, &req);
723
724         if (req.emr_rc != 0) {
725                 rc = req.emr_rc;
726                 goto fail1;
727         }
728
729         return (0);
730
731 fail1:
732         EFSYS_PROBE1(fail1, efx_rc_t, rc);
733
734         return (rc);
735 }
736
737 static  __checkReturn   efx_rc_t
738 efx_mcdi_link_piobuf(
739         __in            efx_nic_t *enp,
740         __in            uint32_t vi_index,
741         __in            efx_piobuf_handle_t handle)
742 {
743         efx_mcdi_req_t req;
744         uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
745                             MC_CMD_LINK_PIOBUF_OUT_LEN)];
746         efx_rc_t rc;
747
748         (void) memset(payload, 0, sizeof (payload));
749         req.emr_cmd = MC_CMD_LINK_PIOBUF;
750         req.emr_in_buf = payload;
751         req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
752         req.emr_out_buf = payload;
753         req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN;
754
755         MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle);
756         MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
757
758         efx_mcdi_execute(enp, &req);
759
760         if (req.emr_rc != 0) {
761                 rc = req.emr_rc;
762                 goto fail1;
763         }
764
765         return (0);
766
767 fail1:
768         EFSYS_PROBE1(fail1, efx_rc_t, rc);
769
770         return (rc);
771 }
772
773 static  __checkReturn   efx_rc_t
774 efx_mcdi_unlink_piobuf(
775         __in            efx_nic_t *enp,
776         __in            uint32_t vi_index)
777 {
778         efx_mcdi_req_t req;
779         uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
780                             MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
781         efx_rc_t rc;
782
783         (void) memset(payload, 0, sizeof (payload));
784         req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
785         req.emr_in_buf = payload;
786         req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
787         req.emr_out_buf = payload;
788         req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN;
789
790         MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
791
792         efx_mcdi_execute_quiet(enp, &req);
793
794         if (req.emr_rc != 0) {
795                 rc = req.emr_rc;
796                 goto fail1;
797         }
798
799         return (0);
800
801 fail1:
802         EFSYS_PROBE1(fail1, efx_rc_t, rc);
803
804         return (rc);
805 }
806
807 static                  void
808 ef10_nic_alloc_piobufs(
809         __in            efx_nic_t *enp,
810         __in            uint32_t max_piobuf_count)
811 {
812         efx_piobuf_handle_t *handlep;
813         unsigned int i;
814
815         EFSYS_ASSERT3U(max_piobuf_count, <=,
816             EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle));
817
818         enp->en_arch.ef10.ena_piobuf_count = 0;
819
820         for (i = 0; i < max_piobuf_count; i++) {
821                 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
822
823                 if (efx_mcdi_alloc_piobuf(enp, handlep) != 0)
824                         goto fail1;
825
826                 enp->en_arch.ef10.ena_pio_alloc_map[i] = 0;
827                 enp->en_arch.ef10.ena_piobuf_count++;
828         }
829
830         return;
831
832 fail1:
833         for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
834                 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
835
836                 (void) efx_mcdi_free_piobuf(enp, *handlep);
837                 *handlep = EFX_PIOBUF_HANDLE_INVALID;
838         }
839         enp->en_arch.ef10.ena_piobuf_count = 0;
840 }
841
842
843 static                  void
844 ef10_nic_free_piobufs(
845         __in            efx_nic_t *enp)
846 {
847         efx_piobuf_handle_t *handlep;
848         unsigned int i;
849
850         for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
851                 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
852
853                 (void) efx_mcdi_free_piobuf(enp, *handlep);
854                 *handlep = EFX_PIOBUF_HANDLE_INVALID;
855         }
856         enp->en_arch.ef10.ena_piobuf_count = 0;
857 }
858
859 /* Sub-allocate a block from a piobuf */
860         __checkReturn   efx_rc_t
861 ef10_nic_pio_alloc(
862         __inout         efx_nic_t *enp,
863         __out           uint32_t *bufnump,
864         __out           efx_piobuf_handle_t *handlep,
865         __out           uint32_t *blknump,
866         __out           uint32_t *offsetp,
867         __out           size_t *sizep)
868 {
869         efx_nic_cfg_t *encp = &enp->en_nic_cfg;
870         efx_drv_cfg_t *edcp = &enp->en_drv_cfg;
871         uint32_t blk_per_buf;
872         uint32_t buf, blk;
873         efx_rc_t rc;
874
875         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
876             enp->en_family == EFX_FAMILY_MEDFORD ||
877             enp->en_family == EFX_FAMILY_MEDFORD2);
878         EFSYS_ASSERT(bufnump);
879         EFSYS_ASSERT(handlep);
880         EFSYS_ASSERT(blknump);
881         EFSYS_ASSERT(offsetp);
882         EFSYS_ASSERT(sizep);
883
884         if ((edcp->edc_pio_alloc_size == 0) ||
885             (enp->en_arch.ef10.ena_piobuf_count == 0)) {
886                 rc = ENOMEM;
887                 goto fail1;
888         }
889         blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size;
890
891         for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) {
892                 uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf];
893
894                 if (~(*map) == 0)
895                         continue;
896
897                 EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map)));
898                 for (blk = 0; blk < blk_per_buf; blk++) {
899                         if ((*map & (1u << blk)) == 0) {
900                                 *map |= (1u << blk);
901                                 goto done;
902                         }
903                 }
904         }
905         rc = ENOMEM;
906         goto fail2;
907
908 done:
909         *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf];
910         *bufnump = buf;
911         *blknump = blk;
912         *sizep = edcp->edc_pio_alloc_size;
913         *offsetp = blk * (*sizep);
914
915         return (0);
916
917 fail2:
918         EFSYS_PROBE(fail2);
919 fail1:
920         EFSYS_PROBE1(fail1, efx_rc_t, rc);
921
922         return (rc);
923 }
924
925 /* Free a piobuf sub-allocated block */
926         __checkReturn   efx_rc_t
927 ef10_nic_pio_free(
928         __inout         efx_nic_t *enp,
929         __in            uint32_t bufnum,
930         __in            uint32_t blknum)
931 {
932         uint32_t *map;
933         efx_rc_t rc;
934
935         if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) ||
936             (blknum >= (8 * sizeof (*map)))) {
937                 rc = EINVAL;
938                 goto fail1;
939         }
940
941         map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum];
942         if ((*map & (1u << blknum)) == 0) {
943                 rc = ENOENT;
944                 goto fail2;
945         }
946         *map &= ~(1u << blknum);
947
948         return (0);
949
950 fail2:
951         EFSYS_PROBE(fail2);
952 fail1:
953         EFSYS_PROBE1(fail1, efx_rc_t, rc);
954
955         return (rc);
956 }
957
958         __checkReturn   efx_rc_t
959 ef10_nic_pio_link(
960         __inout         efx_nic_t *enp,
961         __in            uint32_t vi_index,
962         __in            efx_piobuf_handle_t handle)
963 {
964         return (efx_mcdi_link_piobuf(enp, vi_index, handle));
965 }
966
967         __checkReturn   efx_rc_t
968 ef10_nic_pio_unlink(
969         __inout         efx_nic_t *enp,
970         __in            uint32_t vi_index)
971 {
972         return (efx_mcdi_unlink_piobuf(enp, vi_index));
973 }
974
975 static  __checkReturn   efx_rc_t
976 ef10_mcdi_get_pf_count(
977         __in            efx_nic_t *enp,
978         __out           uint32_t *pf_countp)
979 {
980         efx_mcdi_req_t req;
981         uint8_t payload[MAX(MC_CMD_GET_PF_COUNT_IN_LEN,
982                             MC_CMD_GET_PF_COUNT_OUT_LEN)];
983         efx_rc_t rc;
984
985         (void) memset(payload, 0, sizeof (payload));
986         req.emr_cmd = MC_CMD_GET_PF_COUNT;
987         req.emr_in_buf = payload;
988         req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN;
989         req.emr_out_buf = payload;
990         req.emr_out_length = MC_CMD_GET_PF_COUNT_OUT_LEN;
991
992         efx_mcdi_execute(enp, &req);
993
994         if (req.emr_rc != 0) {
995                 rc = req.emr_rc;
996                 goto fail1;
997         }
998
999         if (req.emr_out_length_used < MC_CMD_GET_PF_COUNT_OUT_LEN) {
1000                 rc = EMSGSIZE;
1001                 goto fail2;
1002         }
1003
1004         *pf_countp = *MCDI_OUT(req, uint8_t,
1005                                 MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST);
1006
1007         EFSYS_ASSERT(*pf_countp != 0);
1008
1009         return (0);
1010
1011 fail2:
1012         EFSYS_PROBE(fail2);
1013 fail1:
1014         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1015
1016         return (rc);
1017 }
1018
1019 static  __checkReturn   efx_rc_t
1020 ef10_get_datapath_caps(
1021         __in            efx_nic_t *enp)
1022 {
1023         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1024         efx_mcdi_req_t req;
1025         uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
1026                             MC_CMD_GET_CAPABILITIES_V5_OUT_LEN)];
1027         efx_rc_t rc;
1028
1029         if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
1030                 goto fail1;
1031
1032
1033         (void) memset(payload, 0, sizeof (payload));
1034         req.emr_cmd = MC_CMD_GET_CAPABILITIES;
1035         req.emr_in_buf = payload;
1036         req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
1037         req.emr_out_buf = payload;
1038         req.emr_out_length = MC_CMD_GET_CAPABILITIES_V5_OUT_LEN;
1039
1040         efx_mcdi_execute_quiet(enp, &req);
1041
1042         if (req.emr_rc != 0) {
1043                 rc = req.emr_rc;
1044                 goto fail2;
1045         }
1046
1047         if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
1048                 rc = EMSGSIZE;
1049                 goto fail3;
1050         }
1051
1052 #define CAP_FLAGS1(_req, _flag)                                         \
1053         (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_OUT_FLAGS1) &          \
1054         (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN)))
1055
1056 #define CAP_FLAGS2(_req, _flag)                                         \
1057         (((_req).emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) && \
1058             (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_V2_OUT_FLAGS2) &   \
1059             (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN))))
1060
1061         /*
1062          * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
1063          * We only support the 14 byte prefix here.
1064          */
1065         if (CAP_FLAGS1(req, RX_PREFIX_LEN_14) == 0) {
1066                 rc = ENOTSUP;
1067                 goto fail4;
1068         }
1069         encp->enc_rx_prefix_size = 14;
1070
1071         /* Check if the firmware supports additional RSS modes */
1072         if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES))
1073                 encp->enc_rx_scale_additional_modes_supported = B_TRUE;
1074         else
1075                 encp->enc_rx_scale_additional_modes_supported = B_FALSE;
1076
1077         /* Check if the firmware supports TSO */
1078         if (CAP_FLAGS1(req, TX_TSO))
1079                 encp->enc_fw_assisted_tso_enabled = B_TRUE;
1080         else
1081                 encp->enc_fw_assisted_tso_enabled = B_FALSE;
1082
1083         /* Check if the firmware supports FATSOv2 */
1084         if (CAP_FLAGS2(req, TX_TSO_V2)) {
1085                 encp->enc_fw_assisted_tso_v2_enabled = B_TRUE;
1086                 encp->enc_fw_assisted_tso_v2_n_contexts = MCDI_OUT_WORD(req,
1087                     GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS);
1088         } else {
1089                 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
1090                 encp->enc_fw_assisted_tso_v2_n_contexts = 0;
1091         }
1092
1093         /* Check if the firmware supports FATSOv2 encap */
1094         if (CAP_FLAGS2(req, TX_TSO_V2_ENCAP))
1095                 encp->enc_fw_assisted_tso_v2_encap_enabled = B_TRUE;
1096         else
1097                 encp->enc_fw_assisted_tso_v2_encap_enabled = B_FALSE;
1098
1099         /* Check if the firmware has vadapter/vport/vswitch support */
1100         if (CAP_FLAGS1(req, EVB))
1101                 encp->enc_datapath_cap_evb = B_TRUE;
1102         else
1103                 encp->enc_datapath_cap_evb = B_FALSE;
1104
1105         /* Check if the firmware supports VLAN insertion */
1106         if (CAP_FLAGS1(req, TX_VLAN_INSERTION))
1107                 encp->enc_hw_tx_insert_vlan_enabled = B_TRUE;
1108         else
1109                 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
1110
1111         /* Check if the firmware supports RX event batching */
1112         if (CAP_FLAGS1(req, RX_BATCHING))
1113                 encp->enc_rx_batching_enabled = B_TRUE;
1114         else
1115                 encp->enc_rx_batching_enabled = B_FALSE;
1116
1117         /*
1118          * Even if batching isn't reported as supported, we may still get
1119          * batched events.
1120          */
1121         encp->enc_rx_batch_max = 16;
1122
1123         /* Check if the firmware supports disabling scatter on RXQs */
1124         if (CAP_FLAGS1(req, RX_DISABLE_SCATTER))
1125                 encp->enc_rx_disable_scatter_supported = B_TRUE;
1126         else
1127                 encp->enc_rx_disable_scatter_supported = B_FALSE;
1128
1129         /* Check if the firmware supports packed stream mode */
1130         if (CAP_FLAGS1(req, RX_PACKED_STREAM))
1131                 encp->enc_rx_packed_stream_supported = B_TRUE;
1132         else
1133                 encp->enc_rx_packed_stream_supported = B_FALSE;
1134
1135         /*
1136          * Check if the firmware supports configurable buffer sizes
1137          * for packed stream mode (otherwise buffer size is 1Mbyte)
1138          */
1139         if (CAP_FLAGS1(req, RX_PACKED_STREAM_VAR_BUFFERS))
1140                 encp->enc_rx_var_packed_stream_supported = B_TRUE;
1141         else
1142                 encp->enc_rx_var_packed_stream_supported = B_FALSE;
1143
1144         /* Check if the firmware supports equal stride super-buffer mode */
1145         if (CAP_FLAGS2(req, EQUAL_STRIDE_SUPER_BUFFER))
1146                 encp->enc_rx_es_super_buffer_supported = B_TRUE;
1147         else
1148                 encp->enc_rx_es_super_buffer_supported = B_FALSE;
1149
1150         /* Check if the firmware supports FW subvariant w/o Tx checksumming */
1151         if (CAP_FLAGS2(req, FW_SUBVARIANT_NO_TX_CSUM))
1152                 encp->enc_fw_subvariant_no_tx_csum_supported = B_TRUE;
1153         else
1154                 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
1155
1156         /* Check if the firmware supports set mac with running filters */
1157         if (CAP_FLAGS1(req, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED))
1158                 encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
1159         else
1160                 encp->enc_allow_set_mac_with_installed_filters = B_FALSE;
1161
1162         /*
1163          * Check if firmware supports the extended MC_CMD_SET_MAC, which allows
1164          * specifying which parameters to configure.
1165          */
1166         if (CAP_FLAGS1(req, SET_MAC_ENHANCED))
1167                 encp->enc_enhanced_set_mac_supported = B_TRUE;
1168         else
1169                 encp->enc_enhanced_set_mac_supported = B_FALSE;
1170
1171         /*
1172          * Check if firmware supports version 2 of MC_CMD_INIT_EVQ, which allows
1173          * us to let the firmware choose the settings to use on an EVQ.
1174          */
1175         if (CAP_FLAGS2(req, INIT_EVQ_V2))
1176                 encp->enc_init_evq_v2_supported = B_TRUE;
1177         else
1178                 encp->enc_init_evq_v2_supported = B_FALSE;
1179
1180         /*
1181          * Check if firmware-verified NVRAM updates must be used.
1182          *
1183          * The firmware trusted installer requires all NVRAM updates to use
1184          * version 2 of MC_CMD_NVRAM_UPDATE_START (to enable verified update)
1185          * and version 2 of MC_CMD_NVRAM_UPDATE_FINISH (to verify the updated
1186          * partition and report the result).
1187          */
1188         if (CAP_FLAGS2(req, NVRAM_UPDATE_REPORT_VERIFY_RESULT))
1189                 encp->enc_nvram_update_verify_result_supported = B_TRUE;
1190         else
1191                 encp->enc_nvram_update_verify_result_supported = B_FALSE;
1192
1193         /*
1194          * Check if firmware provides packet memory and Rx datapath
1195          * counters.
1196          */
1197         if (CAP_FLAGS1(req, PM_AND_RXDP_COUNTERS))
1198                 encp->enc_pm_and_rxdp_counters = B_TRUE;
1199         else
1200                 encp->enc_pm_and_rxdp_counters = B_FALSE;
1201
1202         /*
1203          * Check if the 40G MAC hardware is capable of reporting
1204          * statistics for Tx size bins.
1205          */
1206         if (CAP_FLAGS2(req, MAC_STATS_40G_TX_SIZE_BINS))
1207                 encp->enc_mac_stats_40g_tx_size_bins = B_TRUE;
1208         else
1209                 encp->enc_mac_stats_40g_tx_size_bins = B_FALSE;
1210
1211         /*
1212          * Check if firmware supports VXLAN and NVGRE tunnels.
1213          * The capability indicates Geneve protocol support as well.
1214          */
1215         if (CAP_FLAGS1(req, VXLAN_NVGRE)) {
1216                 encp->enc_tunnel_encapsulations_supported =
1217                     (1u << EFX_TUNNEL_PROTOCOL_VXLAN) |
1218                     (1u << EFX_TUNNEL_PROTOCOL_GENEVE) |
1219                     (1u << EFX_TUNNEL_PROTOCOL_NVGRE);
1220
1221                 EFX_STATIC_ASSERT(EFX_TUNNEL_MAXNENTRIES ==
1222                     MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM);
1223                 encp->enc_tunnel_config_udp_entries_max =
1224                     EFX_TUNNEL_MAXNENTRIES;
1225         } else {
1226                 encp->enc_tunnel_config_udp_entries_max = 0;
1227         }
1228
1229         /*
1230          * Check if firmware reports the VI window mode.
1231          * Medford2 has a variable VI window size (8K, 16K or 64K).
1232          * Medford and Huntington have a fixed 8K VI window size.
1233          */
1234         if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) {
1235                 uint8_t mode =
1236                     MCDI_OUT_BYTE(req, GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE);
1237
1238                 switch (mode) {
1239                 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K:
1240                         encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
1241                         break;
1242                 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K:
1243                         encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_16K;
1244                         break;
1245                 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K:
1246                         encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_64K;
1247                         break;
1248                 default:
1249                         encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID;
1250                         break;
1251                 }
1252         } else if ((enp->en_family == EFX_FAMILY_HUNTINGTON) ||
1253                     (enp->en_family == EFX_FAMILY_MEDFORD)) {
1254                 /* Huntington and Medford have fixed 8K window size */
1255                 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
1256         } else {
1257                 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID;
1258         }
1259
1260         /* Check if firmware supports extended MAC stats. */
1261         if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) {
1262                 /* Extended stats buffer supported */
1263                 encp->enc_mac_stats_nstats = MCDI_OUT_WORD(req,
1264                     GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS);
1265         } else {
1266                 /* Use Siena-compatible legacy MAC stats */
1267                 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
1268         }
1269
1270         if (encp->enc_mac_stats_nstats >= MC_CMD_MAC_NSTATS_V2)
1271                 encp->enc_fec_counters = B_TRUE;
1272         else
1273                 encp->enc_fec_counters = B_FALSE;
1274
1275         /* Check if the firmware provides head-of-line blocking counters */
1276         if (CAP_FLAGS2(req, RXDP_HLB_IDLE))
1277                 encp->enc_hlb_counters = B_TRUE;
1278         else
1279                 encp->enc_hlb_counters = B_FALSE;
1280
1281         if (CAP_FLAGS1(req, RX_RSS_LIMITED)) {
1282                 /* Only one exclusive RSS context is available per port. */
1283                 encp->enc_rx_scale_max_exclusive_contexts = 1;
1284
1285                 switch (enp->en_family) {
1286                 case EFX_FAMILY_MEDFORD2:
1287                         encp->enc_rx_scale_hash_alg_mask =
1288                             (1U << EFX_RX_HASHALG_TOEPLITZ);
1289                         break;
1290
1291                 case EFX_FAMILY_MEDFORD:
1292                 case EFX_FAMILY_HUNTINGTON:
1293                         /*
1294                          * Packed stream firmware variant maintains a
1295                          * non-standard algorithm for hash computation.
1296                          * It implies explicit XORing together
1297                          * source + destination IP addresses (or last
1298                          * four bytes in the case of IPv6) and using the
1299                          * resulting value as the input to a Toeplitz hash.
1300                          */
1301                         encp->enc_rx_scale_hash_alg_mask =
1302                             (1U << EFX_RX_HASHALG_PACKED_STREAM);
1303                         break;
1304
1305                 default:
1306                         rc = EINVAL;
1307                         goto fail5;
1308                 }
1309
1310                 /* Port numbers cannot contribute to the hash value */
1311                 encp->enc_rx_scale_l4_hash_supported = B_FALSE;
1312         } else {
1313                 /*
1314                  * Maximum number of exclusive RSS contexts.
1315                  * EF10 hardware supports 64 in total, but 6 are reserved
1316                  * for shared contexts. They are a global resource so
1317                  * not all may be available.
1318                  */
1319                 encp->enc_rx_scale_max_exclusive_contexts = 64 - 6;
1320
1321                 encp->enc_rx_scale_hash_alg_mask =
1322                     (1U << EFX_RX_HASHALG_TOEPLITZ);
1323
1324                 /*
1325                  * It is possible to use port numbers as
1326                  * the input data for hash computation.
1327                  */
1328                 encp->enc_rx_scale_l4_hash_supported = B_TRUE;
1329         }
1330         /* Check if the firmware supports "FLAG" and "MARK" filter actions */
1331         if (CAP_FLAGS2(req, FILTER_ACTION_FLAG))
1332                 encp->enc_filter_action_flag_supported = B_TRUE;
1333         else
1334                 encp->enc_filter_action_flag_supported = B_FALSE;
1335
1336         if (CAP_FLAGS2(req, FILTER_ACTION_MARK))
1337                 encp->enc_filter_action_mark_supported = B_TRUE;
1338         else
1339                 encp->enc_filter_action_mark_supported = B_FALSE;
1340
1341         /* Get maximum supported value for "MARK" filter action */
1342         if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V5_OUT_LEN)
1343                 encp->enc_filter_action_mark_max = MCDI_OUT_DWORD(req,
1344                     GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_MAX);
1345         else
1346                 encp->enc_filter_action_mark_max = 0;
1347
1348 #undef CAP_FLAGS1
1349 #undef CAP_FLAGS2
1350
1351         return (0);
1352
1353 fail5:
1354         EFSYS_PROBE(fail5);
1355 fail4:
1356         EFSYS_PROBE(fail4);
1357 fail3:
1358         EFSYS_PROBE(fail3);
1359 fail2:
1360         EFSYS_PROBE(fail2);
1361 fail1:
1362         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1363
1364         return (rc);
1365 }
1366
1367
1368 #define EF10_LEGACY_PF_PRIVILEGE_MASK                                   \
1369         (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN                     |       \
1370         MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK                       |       \
1371         MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD                     |       \
1372         MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP                        |       \
1373         MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS           |       \
1374         MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING               |       \
1375         MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST                    |       \
1376         MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST                  |       \
1377         MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST                  |       \
1378         MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST              |       \
1379         MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS)
1380
1381 #define EF10_LEGACY_VF_PRIVILEGE_MASK   0
1382
1383
1384         __checkReturn           efx_rc_t
1385 ef10_get_privilege_mask(
1386         __in                    efx_nic_t *enp,
1387         __out                   uint32_t *maskp)
1388 {
1389         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1390         uint32_t mask;
1391         efx_rc_t rc;
1392
1393         if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf,
1394                                             &mask)) != 0) {
1395                 if (rc != ENOTSUP)
1396                         goto fail1;
1397
1398                 /* Fallback for old firmware without privilege mask support */
1399                 if (EFX_PCI_FUNCTION_IS_PF(encp)) {
1400                         /* Assume PF has admin privilege */
1401                         mask = EF10_LEGACY_PF_PRIVILEGE_MASK;
1402                 } else {
1403                         /* VF is always unprivileged by default */
1404                         mask = EF10_LEGACY_VF_PRIVILEGE_MASK;
1405                 }
1406         }
1407
1408         *maskp = mask;
1409
1410         return (0);
1411
1412 fail1:
1413         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1414
1415         return (rc);
1416 }
1417
1418
1419 /*
1420  * Table of mapping schemes from port number to external number.
1421  *
1422  * Each port number ultimately corresponds to a connector: either as part of
1423  * a cable assembly attached to a module inserted in an SFP+/QSFP+ cage on
1424  * the board, or fixed to the board (e.g. 10GBASE-T magjack on SFN5121T
1425  * "Salina"). In general:
1426  *
1427  * Port number (0-based)
1428  *     |
1429  *   port mapping (n:1)
1430  *     |
1431  *     v
1432  * External port number (normally 1-based)
1433  *     |
1434  *   fixed (1:1) or cable assembly (1:m)
1435  *     |
1436  *     v
1437  * Connector
1438  *
1439  * The external numbering refers to the cages or magjacks on the board,
1440  * as visibly annotated on the board or back panel. This table describes
1441  * how to determine which external cage/magjack corresponds to the port
1442  * numbers used by the driver.
1443  *
1444  * The count of adjacent port numbers that map to each external number,
1445  * and the offset in the numbering, is determined by the chip family and
1446  * current port mode.
1447  *
1448  * For the Huntington family, the current port mode cannot be discovered,
1449  * but a single mapping is used by all modes for a given chip variant,
1450  * so the mapping used is instead the last match in the table to the full
1451  * set of port modes to which the NIC can be configured. Therefore the
1452  * ordering of entries in the mapping table is significant.
1453  */
1454 static struct ef10_external_port_map_s {
1455         efx_family_t    family;
1456         uint32_t        modes_mask;
1457         int32_t         count;
1458         int32_t         offset;
1459 }       __ef10_external_port_mappings[] = {
1460         /*
1461          * Modes used by Huntington family controllers where each port
1462          * number maps to a separate cage.
1463          * SFN7x22F (Torino):
1464          *      port 0 -> cage 1
1465          *      port 1 -> cage 2
1466          * SFN7xx4F (Pavia):
1467          *      port 0 -> cage 1
1468          *      port 1 -> cage 2
1469          *      port 2 -> cage 3
1470          *      port 3 -> cage 4
1471          */
1472         {
1473                 EFX_FAMILY_HUNTINGTON,
1474                 (1U << TLV_PORT_MODE_10G) |                     /* mode 0 */
1475                 (1U << TLV_PORT_MODE_10G_10G) |                 /* mode 2 */
1476                 (1U << TLV_PORT_MODE_10G_10G_10G_10G),          /* mode 4 */
1477                 1,      /* ports per cage */
1478                 1       /* first cage */
1479         },
1480         /*
1481          * Modes which for Huntington identify a chip variant where 2
1482          * adjacent port numbers map to each cage.
1483          * SFN7x42Q (Monza):
1484          *      port 0 -> cage 1
1485          *      port 1 -> cage 1
1486          *      port 2 -> cage 2
1487          *      port 3 -> cage 2
1488          */
1489         {
1490                 EFX_FAMILY_HUNTINGTON,
1491                 (1U << TLV_PORT_MODE_40G) |                     /* mode 1 */
1492                 (1U << TLV_PORT_MODE_40G_40G) |                 /* mode 3 */
1493                 (1U << TLV_PORT_MODE_40G_10G_10G) |             /* mode 6 */
1494                 (1U << TLV_PORT_MODE_10G_10G_40G),              /* mode 7 */
1495                 2,      /* ports per cage */
1496                 1       /* first cage */
1497         },
1498         /*
1499          * Modes that on Medford allocate each port number to a separate
1500          * cage.
1501          *      port 0 -> cage 1
1502          *      port 1 -> cage 2
1503          *      port 2 -> cage 3
1504          *      port 3 -> cage 4
1505          */
1506         {
1507                 EFX_FAMILY_MEDFORD,
1508                 (1U << TLV_PORT_MODE_10G) |                     /* mode 0 */
1509                 (1U << TLV_PORT_MODE_10G_10G),                  /* mode 2 */
1510                 1,      /* ports per cage */
1511                 1       /* first cage */
1512         },
1513         /*
1514          * Modes that on Medford allocate 2 adjacent port numbers to each
1515          * cage.
1516          *      port 0 -> cage 1
1517          *      port 1 -> cage 1
1518          *      port 2 -> cage 2
1519          *      port 3 -> cage 2
1520          */
1521         {
1522                 EFX_FAMILY_MEDFORD,
1523                 (1U << TLV_PORT_MODE_40G) |                     /* mode 1 */
1524                 (1U << TLV_PORT_MODE_40G_40G) |                 /* mode 3 */
1525                 (1U << TLV_PORT_MODE_40G_10G_10G) |             /* mode 6 */
1526                 (1U << TLV_PORT_MODE_10G_10G_40G) |             /* mode 7 */
1527                 /* Do not use 10G_10G_10G_10G_Q1_Q2 (see bug63270) */
1528                 (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2),    /* mode 9 */
1529                 2,      /* ports per cage */
1530                 1       /* first cage */
1531         },
1532         /*
1533          * Modes that on Medford allocate 4 adjacent port numbers to each
1534          * connector, starting on cage 1.
1535          *      port 0 -> cage 1
1536          *      port 1 -> cage 1
1537          *      port 2 -> cage 1
1538          *      port 3 -> cage 1
1539          */
1540         {
1541                 EFX_FAMILY_MEDFORD,
1542                 (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q) |       /* mode 5 */
1543                 /* Do not use 10G_10G_10G_10G_Q1 (see bug63270) */
1544                 (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1),       /* mode 4 */
1545                 4,      /* ports per cage */
1546                 1       /* first cage */
1547         },
1548         /*
1549          * Modes that on Medford allocate 4 adjacent port numbers to each
1550          * connector, starting on cage 2.
1551          *      port 0 -> cage 2
1552          *      port 1 -> cage 2
1553          *      port 2 -> cage 2
1554          *      port 3 -> cage 2
1555          */
1556         {
1557                 EFX_FAMILY_MEDFORD,
1558                 (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q2),       /* mode 8 */
1559                 4,      /* ports per cage */
1560                 2       /* first cage */
1561         },
1562         /*
1563          * Modes that on Medford2 allocate each port number to a separate
1564          * cage.
1565          *      port 0 -> cage 1
1566          *      port 1 -> cage 2
1567          *      port 2 -> cage 3
1568          *      port 3 -> cage 4
1569          */
1570         {
1571                 EFX_FAMILY_MEDFORD2,
1572                 (1U << TLV_PORT_MODE_1x1_NA) |                  /* mode 0 */
1573                 (1U << TLV_PORT_MODE_1x4_NA) |                  /* mode 1 */
1574                 (1U << TLV_PORT_MODE_1x1_1x1) |                 /* mode 2 */
1575                 (1U << TLV_PORT_MODE_1x2_NA) |                  /* mode 10 */
1576                 (1U << TLV_PORT_MODE_1x2_1x2) |                 /* mode 12 */
1577                 (1U << TLV_PORT_MODE_1x4_1x2) |                 /* mode 15 */
1578                 (1U << TLV_PORT_MODE_1x2_1x4),                  /* mode 16 */
1579                 1,      /* ports per cage */
1580                 1       /* first cage */
1581         },
1582         /*
1583          * FIXME: Some port modes are not representable in this mapping:
1584          *  - TLV_PORT_MODE_1x2_2x1 (mode 17):
1585          *      port 0 -> cage 1
1586          *      port 1 -> cage 2
1587          *      port 2 -> cage 2
1588          */
1589         /*
1590          * Modes that on Medford2 allocate 2 adjacent port numbers to each
1591          * cage, starting on cage 1.
1592          *      port 0 -> cage 1
1593          *      port 1 -> cage 1
1594          *      port 2 -> cage 2
1595          *      port 3 -> cage 2
1596          */
1597         {
1598                 EFX_FAMILY_MEDFORD2,
1599                 (1U << TLV_PORT_MODE_1x4_1x4) |                 /* mode 3 */
1600                 (1U << TLV_PORT_MODE_2x1_2x1) |                 /* mode 4 */
1601                 (1U << TLV_PORT_MODE_1x4_2x1) |                 /* mode 6 */
1602                 (1U << TLV_PORT_MODE_2x1_1x4) |                 /* mode 7 */
1603                 (1U << TLV_PORT_MODE_2x2_NA) |                  /* mode 13 */
1604                 (1U << TLV_PORT_MODE_2x1_1x2),                  /* mode 18 */
1605                 2,      /* ports per cage */
1606                 1       /* first cage */
1607         },
1608         /*
1609          * Modes that on Medford2 allocate 2 adjacent port numbers to each
1610          * cage, starting on cage 2.
1611          *      port 0 -> cage 2
1612          *      port 1 -> cage 2
1613          */
1614         {
1615                 EFX_FAMILY_MEDFORD2,
1616                 (1U << TLV_PORT_MODE_NA_2x2),                   /* mode 14 */
1617                 2,      /* ports per cage */
1618                 2       /* first cage */
1619         },
1620         /*
1621          * Modes that on Medford2 allocate 4 adjacent port numbers to each
1622          * connector, starting on cage 1.
1623          *      port 0 -> cage 1
1624          *      port 1 -> cage 1
1625          *      port 2 -> cage 1
1626          *      port 3 -> cage 1
1627          */
1628         {
1629                 EFX_FAMILY_MEDFORD2,
1630                 (1U << TLV_PORT_MODE_4x1_NA),                   /* mode 5 */
1631                 4,      /* ports per cage */
1632                 1       /* first cage */
1633         },
1634         /*
1635          * Modes that on Medford2 allocate 4 adjacent port numbers to each
1636          * connector, starting on cage 2.
1637          *      port 0 -> cage 2
1638          *      port 1 -> cage 2
1639          *      port 2 -> cage 2
1640          *      port 3 -> cage 2
1641          */
1642         {
1643                 EFX_FAMILY_MEDFORD2,
1644                 (1U << TLV_PORT_MODE_NA_4x1) |                  /* mode 8 */
1645                 (1U << TLV_PORT_MODE_NA_1x2),                   /* mode 11 */
1646                 4,      /* ports per cage */
1647                 2       /* first cage */
1648         },
1649 };
1650
1651 static  __checkReturn   efx_rc_t
1652 ef10_external_port_mapping(
1653         __in            efx_nic_t *enp,
1654         __in            uint32_t port,
1655         __out           uint8_t *external_portp)
1656 {
1657         efx_rc_t rc;
1658         int i;
1659         uint32_t port_modes;
1660         uint32_t matches;
1661         uint32_t current;
1662         int32_t count = 1; /* Default 1-1 mapping */
1663         int32_t offset = 1; /* Default starting external port number */
1664
1665         if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current)) != 0) {
1666                 /*
1667                  * No current port mode information (i.e. Huntington)
1668                  * - infer mapping from available modes
1669                  */
1670                 if ((rc = efx_mcdi_get_port_modes(enp,
1671                             &port_modes, NULL)) != 0) {
1672                         /*
1673                          * No port mode information available
1674                          * - use default mapping
1675                          */
1676                         goto out;
1677                 }
1678         } else {
1679                 /* Only need to scan the current mode */
1680                 port_modes = 1 << current;
1681         }
1682
1683         /*
1684          * Infer the internal port -> external number mapping from
1685          * the possible port modes for this NIC.
1686          */
1687         for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) {
1688                 struct ef10_external_port_map_s *eepmp =
1689                     &__ef10_external_port_mappings[i];
1690                 if (eepmp->family != enp->en_family)
1691                         continue;
1692                 matches = (eepmp->modes_mask & port_modes);
1693                 if (matches != 0) {
1694                         /*
1695                          * Some modes match. For some Huntington boards
1696                          * there will be multiple matches. The mapping on the
1697                          * last match is used.
1698                          */
1699                         count = eepmp->count;
1700                         offset = eepmp->offset;
1701                         port_modes &= ~matches;
1702                 }
1703         }
1704
1705         if (port_modes != 0) {
1706                 /* Some advertised modes are not supported */
1707                 rc = ENOTSUP;
1708                 goto fail1;
1709         }
1710
1711 out:
1712         /*
1713          * Scale as required by last matched mode and then convert to
1714          * correctly offset numbering
1715          */
1716         *external_portp = (uint8_t)((port / count) + offset);
1717         return (0);
1718
1719 fail1:
1720         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1721
1722         return (rc);
1723 }
1724
1725 static  __checkReturn   efx_rc_t
1726 ef10_nic_board_cfg(
1727         __in            efx_nic_t *enp)
1728 {
1729         const efx_nic_ops_t *enop = enp->en_enop;
1730         efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
1731         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1732         ef10_link_state_t els;
1733         efx_port_t *epp = &(enp->en_port);
1734         uint32_t board_type = 0;
1735         uint32_t base, nvec;
1736         uint32_t port;
1737         uint32_t mask;
1738         uint32_t pf;
1739         uint32_t vf;
1740         uint8_t mac_addr[6] = { 0 };
1741         efx_rc_t rc;
1742
1743         /* Get the (zero-based) MCDI port number */
1744         if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0)
1745                 goto fail1;
1746
1747         /* EFX MCDI interface uses one-based port numbers */
1748         emip->emi_port = port + 1;
1749
1750         if ((rc = ef10_external_port_mapping(enp, port,
1751                     &encp->enc_external_port)) != 0)
1752                 goto fail2;
1753
1754         /*
1755          * Get PCIe function number from firmware (used for
1756          * per-function privilege and dynamic config info).
1757          *  - PCIe PF: pf = PF number, vf = 0xffff.
1758          *  - PCIe VF: pf = parent PF, vf = VF number.
1759          */
1760         if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0)
1761                 goto fail3;
1762
1763         encp->enc_pf = pf;
1764         encp->enc_vf = vf;
1765
1766         /* MAC address for this function */
1767         if (EFX_PCI_FUNCTION_IS_PF(encp)) {
1768                 rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
1769 #if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC
1770                 /*
1771                  * Disable static config checking, ONLY for manufacturing test
1772                  * and setup at the factory, to allow the static config to be
1773                  * installed.
1774                  */
1775 #else /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */
1776                 if ((rc == 0) && (mac_addr[0] & 0x02)) {
1777                         /*
1778                          * If the static config does not include a global MAC
1779                          * address pool then the board may return a locally
1780                          * administered MAC address (this should only happen on
1781                          * incorrectly programmed boards).
1782                          */
1783                         rc = EINVAL;
1784                 }
1785 #endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */
1786         } else {
1787                 rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
1788         }
1789         if (rc != 0)
1790                 goto fail4;
1791
1792         EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
1793
1794         /* Board configuration (legacy) */
1795         rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL);
1796         if (rc != 0) {
1797                 /* Unprivileged functions may not be able to read board cfg */
1798                 if (rc == EACCES)
1799                         board_type = 0;
1800                 else
1801                         goto fail5;
1802         }
1803
1804         encp->enc_board_type = board_type;
1805         encp->enc_clk_mult = 1; /* not used for EF10 */
1806
1807         /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
1808         if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
1809                 goto fail6;
1810
1811         /* Obtain the default PHY advertised capabilities */
1812         if ((rc = ef10_phy_get_link(enp, &els)) != 0)
1813                 goto fail7;
1814         epp->ep_default_adv_cap_mask = els.els_adv_cap_mask;
1815         epp->ep_adv_cap_mask = els.els_adv_cap_mask;
1816
1817         /* Check capabilities of running datapath firmware */
1818         if ((rc = ef10_get_datapath_caps(enp)) != 0)
1819                 goto fail8;
1820
1821         /* Alignment for WPTR updates */
1822         encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
1823
1824         encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT);
1825         /* No boundary crossing limits */
1826         encp->enc_tx_dma_desc_boundary = 0;
1827
1828         /*
1829          * Maximum number of bytes into the frame the TCP header can start for
1830          * firmware assisted TSO to work.
1831          */
1832         encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT;
1833
1834         /*
1835          * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
1836          * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
1837          * resources (allocated to this PCIe function), which is zero until
1838          * after we have allocated VIs.
1839          */
1840         encp->enc_evq_limit = 1024;
1841         encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
1842         encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
1843
1844         encp->enc_buftbl_limit = 0xFFFFFFFF;
1845
1846         /* Get interrupt vector limits */
1847         if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) {
1848                 if (EFX_PCI_FUNCTION_IS_PF(encp))
1849                         goto fail9;
1850
1851                 /* Ignore error (cannot query vector limits from a VF). */
1852                 base = 0;
1853                 nvec = 1024;
1854         }
1855         encp->enc_intr_vec_base = base;
1856         encp->enc_intr_limit = nvec;
1857
1858         /*
1859          * Get the current privilege mask. Note that this may be modified
1860          * dynamically, so this value is informational only. DO NOT use
1861          * the privilege mask to check for sufficient privileges, as that
1862          * can result in time-of-check/time-of-use bugs.
1863          */
1864         if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0)
1865                 goto fail10;
1866         encp->enc_privilege_mask = mask;
1867
1868         /* Get remaining controller-specific board config */
1869         if ((rc = enop->eno_board_cfg(enp)) != 0)
1870                 if (rc != EACCES)
1871                         goto fail11;
1872
1873         return (0);
1874
1875 fail11:
1876         EFSYS_PROBE(fail11);
1877 fail10:
1878         EFSYS_PROBE(fail10);
1879 fail9:
1880         EFSYS_PROBE(fail9);
1881 fail8:
1882         EFSYS_PROBE(fail8);
1883 fail7:
1884         EFSYS_PROBE(fail7);
1885 fail6:
1886         EFSYS_PROBE(fail6);
1887 fail5:
1888         EFSYS_PROBE(fail5);
1889 fail4:
1890         EFSYS_PROBE(fail4);
1891 fail3:
1892         EFSYS_PROBE(fail3);
1893 fail2:
1894         EFSYS_PROBE(fail2);
1895 fail1:
1896         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1897
1898         return (rc);
1899 }
1900
1901         __checkReturn   efx_rc_t
1902 ef10_nic_probe(
1903         __in            efx_nic_t *enp)
1904 {
1905         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1906         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
1907         efx_rc_t rc;
1908
1909         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
1910             enp->en_family == EFX_FAMILY_MEDFORD ||
1911             enp->en_family == EFX_FAMILY_MEDFORD2);
1912
1913         /* Read and clear any assertion state */
1914         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
1915                 goto fail1;
1916
1917         /* Exit the assertion handler */
1918         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
1919                 if (rc != EACCES)
1920                         goto fail2;
1921
1922         if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
1923                 goto fail3;
1924
1925         if ((rc = ef10_nic_board_cfg(enp)) != 0)
1926                 goto fail4;
1927
1928         /*
1929          * Set default driver config limits (based on board config).
1930          *
1931          * FIXME: For now allocate a fixed number of VIs which is likely to be
1932          * sufficient and small enough to allow multiple functions on the same
1933          * port.
1934          */
1935         edcp->edc_min_vi_count = edcp->edc_max_vi_count =
1936             MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
1937
1938         /* The client driver must configure and enable PIO buffer support */
1939         edcp->edc_max_piobuf_count = 0;
1940         edcp->edc_pio_alloc_size = 0;
1941
1942 #if EFSYS_OPT_MAC_STATS
1943         /* Wipe the MAC statistics */
1944         if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
1945                 goto fail5;
1946 #endif
1947
1948 #if EFSYS_OPT_LOOPBACK
1949         if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
1950                 goto fail6;
1951 #endif
1952
1953 #if EFSYS_OPT_MON_STATS
1954         if ((rc = mcdi_mon_cfg_build(enp)) != 0) {
1955                 /* Unprivileged functions do not have access to sensors */
1956                 if (rc != EACCES)
1957                         goto fail7;
1958         }
1959 #endif
1960
1961         encp->enc_features = enp->en_features;
1962
1963         return (0);
1964
1965 #if EFSYS_OPT_MON_STATS
1966 fail7:
1967         EFSYS_PROBE(fail7);
1968 #endif
1969 #if EFSYS_OPT_LOOPBACK
1970 fail6:
1971         EFSYS_PROBE(fail6);
1972 #endif
1973 #if EFSYS_OPT_MAC_STATS
1974 fail5:
1975         EFSYS_PROBE(fail5);
1976 #endif
1977 fail4:
1978         EFSYS_PROBE(fail4);
1979 fail3:
1980         EFSYS_PROBE(fail3);
1981 fail2:
1982         EFSYS_PROBE(fail2);
1983 fail1:
1984         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1985
1986         return (rc);
1987 }
1988
1989         __checkReturn   efx_rc_t
1990 ef10_nic_set_drv_limits(
1991         __inout         efx_nic_t *enp,
1992         __in            efx_drv_limits_t *edlp)
1993 {
1994         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1995         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
1996         uint32_t min_evq_count, max_evq_count;
1997         uint32_t min_rxq_count, max_rxq_count;
1998         uint32_t min_txq_count, max_txq_count;
1999         efx_rc_t rc;
2000
2001         if (edlp == NULL) {
2002                 rc = EINVAL;
2003                 goto fail1;
2004         }
2005
2006         /* Get minimum required and maximum usable VI limits */
2007         min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
2008         min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
2009         min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
2010
2011         edcp->edc_min_vi_count =
2012             MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
2013
2014         max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
2015         max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
2016         max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
2017
2018         edcp->edc_max_vi_count =
2019             MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
2020
2021         /*
2022          * Check limits for sub-allocated piobuf blocks.
2023          * PIO is optional, so don't fail if the limits are incorrect.
2024          */
2025         if ((encp->enc_piobuf_size == 0) ||
2026             (encp->enc_piobuf_limit == 0) ||
2027             (edlp->edl_min_pio_alloc_size == 0) ||
2028             (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) {
2029                 /* Disable PIO */
2030                 edcp->edc_max_piobuf_count = 0;
2031                 edcp->edc_pio_alloc_size = 0;
2032         } else {
2033                 uint32_t blk_size, blk_count, blks_per_piobuf;
2034
2035                 blk_size =
2036                     MAX(edlp->edl_min_pio_alloc_size,
2037                             encp->enc_piobuf_min_alloc_size);
2038
2039                 blks_per_piobuf = encp->enc_piobuf_size / blk_size;
2040                 EFSYS_ASSERT3U(blks_per_piobuf, <=, 32);
2041
2042                 blk_count = (encp->enc_piobuf_limit * blks_per_piobuf);
2043
2044                 /* A zero max pio alloc count means unlimited */
2045                 if ((edlp->edl_max_pio_alloc_count > 0) &&
2046                     (edlp->edl_max_pio_alloc_count < blk_count)) {
2047                         blk_count = edlp->edl_max_pio_alloc_count;
2048                 }
2049
2050                 edcp->edc_pio_alloc_size = blk_size;
2051                 edcp->edc_max_piobuf_count =
2052                     (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf;
2053         }
2054
2055         return (0);
2056
2057 fail1:
2058         EFSYS_PROBE1(fail1, efx_rc_t, rc);
2059
2060         return (rc);
2061 }
2062
2063
2064         __checkReturn   efx_rc_t
2065 ef10_nic_reset(
2066         __in            efx_nic_t *enp)
2067 {
2068         efx_mcdi_req_t req;
2069         uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
2070                             MC_CMD_ENTITY_RESET_OUT_LEN)];
2071         efx_rc_t rc;
2072
2073         /* ef10_nic_reset() is called to recover from BADASSERT failures. */
2074         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
2075                 goto fail1;
2076         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
2077                 goto fail2;
2078
2079         (void) memset(payload, 0, sizeof (payload));
2080         req.emr_cmd = MC_CMD_ENTITY_RESET;
2081         req.emr_in_buf = payload;
2082         req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
2083         req.emr_out_buf = payload;
2084         req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
2085
2086         MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
2087             ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
2088
2089         efx_mcdi_execute(enp, &req);
2090
2091         if (req.emr_rc != 0) {
2092                 rc = req.emr_rc;
2093                 goto fail3;
2094         }
2095
2096         /* Clear RX/TX DMA queue errors */
2097         enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
2098
2099         return (0);
2100
2101 fail3:
2102         EFSYS_PROBE(fail3);
2103 fail2:
2104         EFSYS_PROBE(fail2);
2105 fail1:
2106         EFSYS_PROBE1(fail1, efx_rc_t, rc);
2107
2108         return (rc);
2109 }
2110
2111         __checkReturn   efx_rc_t
2112 ef10_nic_init(
2113         __in            efx_nic_t *enp)
2114 {
2115         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
2116         uint32_t min_vi_count, max_vi_count;
2117         uint32_t vi_count, vi_base, vi_shift;
2118         uint32_t i;
2119         uint32_t retry;
2120         uint32_t delay_us;
2121         uint32_t vi_window_size;
2122         efx_rc_t rc;
2123
2124         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
2125             enp->en_family == EFX_FAMILY_MEDFORD ||
2126             enp->en_family == EFX_FAMILY_MEDFORD2);
2127
2128         /* Enable reporting of some events (e.g. link change) */
2129         if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
2130                 goto fail1;
2131
2132         /* Allocate (optional) on-chip PIO buffers */
2133         ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count);
2134
2135         /*
2136          * For best performance, PIO writes should use a write-combined
2137          * (WC) memory mapping. Using a separate WC mapping for the PIO
2138          * aperture of each VI would be a burden to drivers (and not
2139          * possible if the host page size is >4Kbyte).
2140          *
2141          * To avoid this we use a single uncached (UC) mapping for VI
2142          * register access, and a single WC mapping for extra VIs used
2143          * for PIO writes.
2144          *
2145          * Each piobuf must be linked to a VI in the WC mapping, and to
2146          * each VI that is using a sub-allocated block from the piobuf.
2147          */
2148         min_vi_count = edcp->edc_min_vi_count;
2149         max_vi_count =
2150             edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count;
2151
2152         /* Ensure that the previously attached driver's VIs are freed */
2153         if ((rc = efx_mcdi_free_vis(enp)) != 0)
2154                 goto fail2;
2155
2156         /*
2157          * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
2158          * fails then retrying the request for fewer VI resources may succeed.
2159          */
2160         vi_count = 0;
2161         if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
2162                     &vi_base, &vi_count, &vi_shift)) != 0)
2163                 goto fail3;
2164
2165         EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
2166
2167         if (vi_count < min_vi_count) {
2168                 rc = ENOMEM;
2169                 goto fail4;
2170         }
2171
2172         enp->en_arch.ef10.ena_vi_base = vi_base;
2173         enp->en_arch.ef10.ena_vi_count = vi_count;
2174         enp->en_arch.ef10.ena_vi_shift = vi_shift;
2175
2176         if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) {
2177                 /* Not enough extra VIs to map piobufs */
2178                 ef10_nic_free_piobufs(enp);
2179         }
2180
2181         enp->en_arch.ef10.ena_pio_write_vi_base =
2182             vi_count - enp->en_arch.ef10.ena_piobuf_count;
2183
2184         EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=,
2185             EFX_VI_WINDOW_SHIFT_INVALID);
2186         EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=,
2187             EFX_VI_WINDOW_SHIFT_64K);
2188         vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift;
2189
2190         /* Save UC memory mapping details */
2191         enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
2192         if (enp->en_arch.ef10.ena_piobuf_count > 0) {
2193                 enp->en_arch.ef10.ena_uc_mem_map_size =
2194                     (vi_window_size *
2195                     enp->en_arch.ef10.ena_pio_write_vi_base);
2196         } else {
2197                 enp->en_arch.ef10.ena_uc_mem_map_size =
2198                     (vi_window_size *
2199                     enp->en_arch.ef10.ena_vi_count);
2200         }
2201
2202         /* Save WC memory mapping details */
2203         enp->en_arch.ef10.ena_wc_mem_map_offset =
2204             enp->en_arch.ef10.ena_uc_mem_map_offset +
2205             enp->en_arch.ef10.ena_uc_mem_map_size;
2206
2207         enp->en_arch.ef10.ena_wc_mem_map_size =
2208             (vi_window_size *
2209             enp->en_arch.ef10.ena_piobuf_count);
2210
2211         /* Link piobufs to extra VIs in WC mapping */
2212         if (enp->en_arch.ef10.ena_piobuf_count > 0) {
2213                 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
2214                         rc = efx_mcdi_link_piobuf(enp,
2215                             enp->en_arch.ef10.ena_pio_write_vi_base + i,
2216                             enp->en_arch.ef10.ena_piobuf_handle[i]);
2217                         if (rc != 0)
2218                                 break;
2219                 }
2220         }
2221
2222         /*
2223          * Allocate a vAdaptor attached to our upstream vPort/pPort.
2224          *
2225          * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF
2226          * driver has yet to bring up the EVB port. See bug 56147. In this case,
2227          * retry the request several times after waiting a while. The wait time
2228          * between retries starts small (10ms) and exponentially increases.
2229          * Total wait time is a little over two seconds. Retry logic in the
2230          * client driver may mean this whole loop is repeated if it continues to
2231          * fail.
2232          */
2233         retry = 0;
2234         delay_us = 10000;
2235         while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) {
2236                 if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) ||
2237                     (rc != ENOENT)) {
2238                         /*
2239                          * Do not retry alloc for PF, or for other errors on
2240                          * a VF.
2241                          */
2242                         goto fail5;
2243                 }
2244
2245                 /* VF startup before PF is ready. Retry allocation. */
2246                 if (retry > 5) {
2247                         /* Too many attempts */
2248                         rc = EINVAL;
2249                         goto fail6;
2250                 }
2251                 EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry);
2252                 EFSYS_SLEEP(delay_us);
2253                 retry++;
2254                 if (delay_us < 500000)
2255                         delay_us <<= 2;
2256         }
2257
2258         enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
2259         enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
2260
2261         return (0);
2262
2263 fail6:
2264         EFSYS_PROBE(fail6);
2265 fail5:
2266         EFSYS_PROBE(fail5);
2267 fail4:
2268         EFSYS_PROBE(fail4);
2269 fail3:
2270         EFSYS_PROBE(fail3);
2271 fail2:
2272         EFSYS_PROBE(fail2);
2273
2274         ef10_nic_free_piobufs(enp);
2275
2276 fail1:
2277         EFSYS_PROBE1(fail1, efx_rc_t, rc);
2278
2279         return (rc);
2280 }
2281
2282         __checkReturn   efx_rc_t
2283 ef10_nic_get_vi_pool(
2284         __in            efx_nic_t *enp,
2285         __out           uint32_t *vi_countp)
2286 {
2287         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
2288             enp->en_family == EFX_FAMILY_MEDFORD ||
2289             enp->en_family == EFX_FAMILY_MEDFORD2);
2290
2291         /*
2292          * Report VIs that the client driver can use.
2293          * Do not include VIs used for PIO buffer writes.
2294          */
2295         *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base;
2296
2297         return (0);
2298 }
2299
2300         __checkReturn   efx_rc_t
2301 ef10_nic_get_bar_region(
2302         __in            efx_nic_t *enp,
2303         __in            efx_nic_region_t region,
2304         __out           uint32_t *offsetp,
2305         __out           size_t *sizep)
2306 {
2307         efx_rc_t rc;
2308
2309         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
2310             enp->en_family == EFX_FAMILY_MEDFORD ||
2311             enp->en_family == EFX_FAMILY_MEDFORD2);
2312
2313         /*
2314          * TODO: Specify host memory mapping alignment and granularity
2315          * in efx_drv_limits_t so that they can be taken into account
2316          * when allocating extra VIs for PIO writes.
2317          */
2318         switch (region) {
2319         case EFX_REGION_VI:
2320                 /* UC mapped memory BAR region for VI registers */
2321                 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
2322                 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
2323                 break;
2324
2325         case EFX_REGION_PIO_WRITE_VI:
2326                 /* WC mapped memory BAR region for piobuf writes */
2327                 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
2328                 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
2329                 break;
2330
2331         default:
2332                 rc = EINVAL;
2333                 goto fail1;
2334         }
2335
2336         return (0);
2337
2338 fail1:
2339         EFSYS_PROBE1(fail1, efx_rc_t, rc);
2340
2341         return (rc);
2342 }
2343
2344                         void
2345 ef10_nic_fini(
2346         __in            efx_nic_t *enp)
2347 {
2348         uint32_t i;
2349         efx_rc_t rc;
2350
2351         (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
2352         enp->en_vport_id = 0;
2353
2354         /* Unlink piobufs from extra VIs in WC mapping */
2355         if (enp->en_arch.ef10.ena_piobuf_count > 0) {
2356                 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
2357                         rc = efx_mcdi_unlink_piobuf(enp,
2358                             enp->en_arch.ef10.ena_pio_write_vi_base + i);
2359                         if (rc != 0)
2360                                 break;
2361                 }
2362         }
2363
2364         ef10_nic_free_piobufs(enp);
2365
2366         (void) efx_mcdi_free_vis(enp);
2367         enp->en_arch.ef10.ena_vi_count = 0;
2368 }
2369
2370                         void
2371 ef10_nic_unprobe(
2372         __in            efx_nic_t *enp)
2373 {
2374 #if EFSYS_OPT_MON_STATS
2375         mcdi_mon_cfg_free(enp);
2376 #endif /* EFSYS_OPT_MON_STATS */
2377         (void) efx_mcdi_drv_attach(enp, B_FALSE);
2378 }
2379
2380 #if EFSYS_OPT_DIAG
2381
2382         __checkReturn   efx_rc_t
2383 ef10_nic_register_test(
2384         __in            efx_nic_t *enp)
2385 {
2386         efx_rc_t rc;
2387
2388         /* FIXME */
2389         _NOTE(ARGUNUSED(enp))
2390         _NOTE(CONSTANTCONDITION)
2391         if (B_FALSE) {
2392                 rc = ENOTSUP;
2393                 goto fail1;
2394         }
2395         /* FIXME */
2396
2397         return (0);
2398
2399 fail1:
2400         EFSYS_PROBE1(fail1, efx_rc_t, rc);
2401
2402         return (rc);
2403 }
2404
2405 #endif  /* EFSYS_OPT_DIAG */
2406
2407 #if EFSYS_OPT_FW_SUBVARIANT_AWARE
2408
2409         __checkReturn   efx_rc_t
2410 efx_mcdi_get_nic_global(
2411         __in            efx_nic_t *enp,
2412         __in            uint32_t key,
2413         __out           uint32_t *valuep)
2414 {
2415         efx_mcdi_req_t req;
2416         uint8_t payload[MAX(MC_CMD_GET_NIC_GLOBAL_IN_LEN,
2417                             MC_CMD_GET_NIC_GLOBAL_OUT_LEN)];
2418         efx_rc_t rc;
2419
2420         (void) memset(payload, 0, sizeof (payload));
2421         req.emr_cmd = MC_CMD_GET_NIC_GLOBAL;
2422         req.emr_in_buf = payload;
2423         req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN;
2424         req.emr_out_buf = payload;
2425         req.emr_out_length = MC_CMD_GET_NIC_GLOBAL_OUT_LEN;
2426
2427         MCDI_IN_SET_DWORD(req, GET_NIC_GLOBAL_IN_KEY, key);
2428
2429         efx_mcdi_execute(enp, &req);
2430
2431         if (req.emr_rc != 0) {
2432                 rc = req.emr_rc;
2433                 goto fail1;
2434         }
2435
2436         if (req.emr_out_length_used != MC_CMD_GET_NIC_GLOBAL_OUT_LEN) {
2437                 rc = EMSGSIZE;
2438                 goto fail2;
2439         }
2440
2441         *valuep = MCDI_OUT_DWORD(req, GET_NIC_GLOBAL_OUT_VALUE);
2442
2443         return (0);
2444
2445 fail2:
2446         EFSYS_PROBE(fail2);
2447 fail1:
2448         EFSYS_PROBE1(fail1, efx_rc_t, rc);
2449
2450         return (rc);
2451 }
2452
2453         __checkReturn   efx_rc_t
2454 efx_mcdi_set_nic_global(
2455         __in            efx_nic_t *enp,
2456         __in            uint32_t key,
2457         __in            uint32_t value)
2458 {
2459         efx_mcdi_req_t req;
2460         uint8_t payload[MC_CMD_SET_NIC_GLOBAL_IN_LEN];
2461         efx_rc_t rc;
2462
2463         (void) memset(payload, 0, sizeof (payload));
2464         req.emr_cmd = MC_CMD_SET_NIC_GLOBAL;
2465         req.emr_in_buf = payload;
2466         req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN;
2467         req.emr_out_buf = NULL;
2468         req.emr_out_length = 0;
2469
2470         MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_KEY, key);
2471         MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_VALUE, value);
2472
2473         efx_mcdi_execute(enp, &req);
2474
2475         if (req.emr_rc != 0) {
2476                 rc = req.emr_rc;
2477                 goto fail1;
2478         }
2479
2480         return (0);
2481
2482 fail1:
2483         EFSYS_PROBE1(fail1, efx_rc_t, rc);
2484
2485         return (rc);
2486 }
2487
2488 #endif  /* EFSYS_OPT_FW_SUBVARIANT_AWARE */
2489
2490 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */