net/sfc/base: import SFN7xxx family support
[dpdk.git] / drivers / net / sfc / base / 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 "efx.h"
32 #include "efx_impl.h"
33
34 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
35
36 #include "ef10_tlv_layout.h"
37
38         __checkReturn   efx_rc_t
39 efx_mcdi_get_port_assignment(
40         __in            efx_nic_t *enp,
41         __out           uint32_t *portp)
42 {
43         efx_mcdi_req_t req;
44         uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
45                             MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
46         efx_rc_t rc;
47
48         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
49                     enp->en_family == EFX_FAMILY_MEDFORD);
50
51         (void) memset(payload, 0, sizeof (payload));
52         req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
53         req.emr_in_buf = payload;
54         req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
55         req.emr_out_buf = payload;
56         req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN;
57
58         efx_mcdi_execute(enp, &req);
59
60         if (req.emr_rc != 0) {
61                 rc = req.emr_rc;
62                 goto fail1;
63         }
64
65         if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) {
66                 rc = EMSGSIZE;
67                 goto fail2;
68         }
69
70         *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT);
71
72         return (0);
73
74 fail2:
75         EFSYS_PROBE(fail2);
76 fail1:
77         EFSYS_PROBE1(fail1, efx_rc_t, rc);
78
79         return (rc);
80 }
81
82         __checkReturn   efx_rc_t
83 efx_mcdi_get_port_modes(
84         __in            efx_nic_t *enp,
85         __out           uint32_t *modesp,
86         __out_opt       uint32_t *current_modep)
87 {
88         efx_mcdi_req_t req;
89         uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
90                             MC_CMD_GET_PORT_MODES_OUT_LEN)];
91         efx_rc_t rc;
92
93         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
94                     enp->en_family == EFX_FAMILY_MEDFORD);
95
96         (void) memset(payload, 0, sizeof (payload));
97         req.emr_cmd = MC_CMD_GET_PORT_MODES;
98         req.emr_in_buf = payload;
99         req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
100         req.emr_out_buf = payload;
101         req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN;
102
103         efx_mcdi_execute(enp, &req);
104
105         if (req.emr_rc != 0) {
106                 rc = req.emr_rc;
107                 goto fail1;
108         }
109
110         /*
111          * Require only Modes and DefaultMode fields, unless the current mode
112          * was requested (CurrentMode field was added for Medford).
113          */
114         if (req.emr_out_length_used <
115             MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) {
116                 rc = EMSGSIZE;
117                 goto fail2;
118         }
119         if ((current_modep != NULL) && (req.emr_out_length_used <
120             MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST + 4)) {
121                 rc = EMSGSIZE;
122                 goto fail3;
123         }
124
125         *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES);
126
127         if (current_modep != NULL) {
128                 *current_modep = MCDI_OUT_DWORD(req,
129                                             GET_PORT_MODES_OUT_CURRENT_MODE);
130         }
131
132         return (0);
133
134 fail3:
135         EFSYS_PROBE(fail3);
136 fail2:
137         EFSYS_PROBE(fail2);
138 fail1:
139         EFSYS_PROBE1(fail1, efx_rc_t, rc);
140
141         return (rc);
142 }
143
144         __checkReturn   efx_rc_t
145 ef10_nic_get_port_mode_bandwidth(
146         __in            uint32_t port_mode,
147         __out           uint32_t *bandwidth_mbpsp)
148 {
149         uint32_t bandwidth;
150         efx_rc_t rc;
151
152         switch (port_mode) {
153         case TLV_PORT_MODE_10G:
154                 bandwidth = 10000;
155                 break;
156         case TLV_PORT_MODE_10G_10G:
157                 bandwidth = 10000 * 2;
158                 break;
159         case TLV_PORT_MODE_10G_10G_10G_10G:
160         case TLV_PORT_MODE_10G_10G_10G_10G_Q:
161         case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2:
162         case TLV_PORT_MODE_10G_10G_10G_10G_Q2:
163                 bandwidth = 10000 * 4;
164                 break;
165         case TLV_PORT_MODE_40G:
166                 bandwidth = 40000;
167                 break;
168         case TLV_PORT_MODE_40G_40G:
169                 bandwidth = 40000 * 2;
170                 break;
171         case TLV_PORT_MODE_40G_10G_10G:
172         case TLV_PORT_MODE_10G_10G_40G:
173                 bandwidth = 40000 + (10000 * 2);
174                 break;
175         default:
176                 rc = EINVAL;
177                 goto fail1;
178         }
179
180         *bandwidth_mbpsp = bandwidth;
181
182         return (0);
183
184 fail1:
185         EFSYS_PROBE1(fail1, efx_rc_t, rc);
186
187         return (rc);
188 }
189
190 static  __checkReturn           efx_rc_t
191 efx_mcdi_vadaptor_alloc(
192         __in                    efx_nic_t *enp,
193         __in                    uint32_t port_id)
194 {
195         efx_mcdi_req_t req;
196         uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
197                             MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
198         efx_rc_t rc;
199
200         EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
201
202         (void) memset(payload, 0, sizeof (payload));
203         req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
204         req.emr_in_buf = payload;
205         req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
206         req.emr_out_buf = payload;
207         req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN;
208
209         MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id);
210         MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS,
211             VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED,
212             enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0);
213
214         efx_mcdi_execute(enp, &req);
215
216         if (req.emr_rc != 0) {
217                 rc = req.emr_rc;
218                 goto fail1;
219         }
220
221         return (0);
222
223 fail1:
224         EFSYS_PROBE1(fail1, efx_rc_t, rc);
225
226         return (rc);
227 }
228
229 static  __checkReturn           efx_rc_t
230 efx_mcdi_vadaptor_free(
231         __in                    efx_nic_t *enp,
232         __in                    uint32_t port_id)
233 {
234         efx_mcdi_req_t req;
235         uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
236                             MC_CMD_VADAPTOR_FREE_OUT_LEN)];
237         efx_rc_t rc;
238
239         (void) memset(payload, 0, sizeof (payload));
240         req.emr_cmd = MC_CMD_VADAPTOR_FREE;
241         req.emr_in_buf = payload;
242         req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
243         req.emr_out_buf = payload;
244         req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN;
245
246         MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id);
247
248         efx_mcdi_execute(enp, &req);
249
250         if (req.emr_rc != 0) {
251                 rc = req.emr_rc;
252                 goto fail1;
253         }
254
255         return (0);
256
257 fail1:
258         EFSYS_PROBE1(fail1, efx_rc_t, rc);
259
260         return (rc);
261 }
262
263         __checkReturn   efx_rc_t
264 efx_mcdi_get_mac_address_pf(
265         __in                    efx_nic_t *enp,
266         __out_ecount_opt(6)     uint8_t mac_addrp[6])
267 {
268         efx_mcdi_req_t req;
269         uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
270                             MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
271         efx_rc_t rc;
272
273         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
274                     enp->en_family == EFX_FAMILY_MEDFORD);
275
276         (void) memset(payload, 0, sizeof (payload));
277         req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
278         req.emr_in_buf = payload;
279         req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
280         req.emr_out_buf = payload;
281         req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
282
283         efx_mcdi_execute(enp, &req);
284
285         if (req.emr_rc != 0) {
286                 rc = req.emr_rc;
287                 goto fail1;
288         }
289
290         if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) {
291                 rc = EMSGSIZE;
292                 goto fail2;
293         }
294
295         if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) {
296                 rc = ENOENT;
297                 goto fail3;
298         }
299
300         if (mac_addrp != NULL) {
301                 uint8_t *addrp;
302
303                 addrp = MCDI_OUT2(req, uint8_t,
304                     GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE);
305
306                 EFX_MAC_ADDR_COPY(mac_addrp, addrp);
307         }
308
309         return (0);
310
311 fail3:
312         EFSYS_PROBE(fail3);
313 fail2:
314         EFSYS_PROBE(fail2);
315 fail1:
316         EFSYS_PROBE1(fail1, efx_rc_t, rc);
317
318         return (rc);
319 }
320
321         __checkReturn   efx_rc_t
322 efx_mcdi_get_mac_address_vf(
323         __in                    efx_nic_t *enp,
324         __out_ecount_opt(6)     uint8_t mac_addrp[6])
325 {
326         efx_mcdi_req_t req;
327         uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
328                             MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
329         efx_rc_t rc;
330
331         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
332                     enp->en_family == EFX_FAMILY_MEDFORD);
333
334         (void) memset(payload, 0, sizeof (payload));
335         req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
336         req.emr_in_buf = payload;
337         req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
338         req.emr_out_buf = payload;
339         req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX;
340
341         MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
342             EVB_PORT_ID_ASSIGNED);
343
344         efx_mcdi_execute(enp, &req);
345
346         if (req.emr_rc != 0) {
347                 rc = req.emr_rc;
348                 goto fail1;
349         }
350
351         if (req.emr_out_length_used <
352             MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) {
353                 rc = EMSGSIZE;
354                 goto fail2;
355         }
356
357         if (MCDI_OUT_DWORD(req,
358                 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) {
359                 rc = ENOENT;
360                 goto fail3;
361         }
362
363         if (mac_addrp != NULL) {
364                 uint8_t *addrp;
365
366                 addrp = MCDI_OUT2(req, uint8_t,
367                     VPORT_GET_MAC_ADDRESSES_OUT_MACADDR);
368
369                 EFX_MAC_ADDR_COPY(mac_addrp, addrp);
370         }
371
372         return (0);
373
374 fail3:
375         EFSYS_PROBE(fail3);
376 fail2:
377         EFSYS_PROBE(fail2);
378 fail1:
379         EFSYS_PROBE1(fail1, efx_rc_t, rc);
380
381         return (rc);
382 }
383
384         __checkReturn   efx_rc_t
385 efx_mcdi_get_clock(
386         __in            efx_nic_t *enp,
387         __out           uint32_t *sys_freqp,
388         __out           uint32_t *dpcpu_freqp)
389 {
390         efx_mcdi_req_t req;
391         uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
392                             MC_CMD_GET_CLOCK_OUT_LEN)];
393         efx_rc_t rc;
394
395         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
396                     enp->en_family == EFX_FAMILY_MEDFORD);
397
398         (void) memset(payload, 0, sizeof (payload));
399         req.emr_cmd = MC_CMD_GET_CLOCK;
400         req.emr_in_buf = payload;
401         req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
402         req.emr_out_buf = payload;
403         req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN;
404
405         efx_mcdi_execute(enp, &req);
406
407         if (req.emr_rc != 0) {
408                 rc = req.emr_rc;
409                 goto fail1;
410         }
411
412         if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) {
413                 rc = EMSGSIZE;
414                 goto fail2;
415         }
416
417         *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ);
418         if (*sys_freqp == 0) {
419                 rc = EINVAL;
420                 goto fail3;
421         }
422         *dpcpu_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_DPCPU_FREQ);
423         if (*dpcpu_freqp == 0) {
424                 rc = EINVAL;
425                 goto fail4;
426         }
427
428         return (0);
429
430 fail4:
431         EFSYS_PROBE(fail4);
432 fail3:
433         EFSYS_PROBE(fail3);
434 fail2:
435         EFSYS_PROBE(fail2);
436 fail1:
437         EFSYS_PROBE1(fail1, efx_rc_t, rc);
438
439         return (rc);
440 }
441
442         __checkReturn   efx_rc_t
443 efx_mcdi_get_vector_cfg(
444         __in            efx_nic_t *enp,
445         __out_opt       uint32_t *vec_basep,
446         __out_opt       uint32_t *pf_nvecp,
447         __out_opt       uint32_t *vf_nvecp)
448 {
449         efx_mcdi_req_t req;
450         uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
451                             MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
452         efx_rc_t rc;
453
454         (void) memset(payload, 0, sizeof (payload));
455         req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
456         req.emr_in_buf = payload;
457         req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
458         req.emr_out_buf = payload;
459         req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN;
460
461         efx_mcdi_execute(enp, &req);
462
463         if (req.emr_rc != 0) {
464                 rc = req.emr_rc;
465                 goto fail1;
466         }
467
468         if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) {
469                 rc = EMSGSIZE;
470                 goto fail2;
471         }
472
473         if (vec_basep != NULL)
474                 *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE);
475         if (pf_nvecp != NULL)
476                 *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF);
477         if (vf_nvecp != NULL)
478                 *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF);
479
480         return (0);
481
482 fail2:
483         EFSYS_PROBE(fail2);
484 fail1:
485         EFSYS_PROBE1(fail1, efx_rc_t, rc);
486
487         return (rc);
488 }
489
490 static  __checkReturn   efx_rc_t
491 efx_mcdi_get_capabilities(
492         __in            efx_nic_t *enp,
493         __out           uint32_t *flagsp,
494         __out           uint32_t *flags2p,
495         __out           uint32_t *tso2ncp)
496 {
497         efx_mcdi_req_t req;
498         uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
499                             MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)];
500         efx_rc_t rc;
501
502         (void) memset(payload, 0, sizeof (payload));
503         req.emr_cmd = MC_CMD_GET_CAPABILITIES;
504         req.emr_in_buf = payload;
505         req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
506         req.emr_out_buf = payload;
507         req.emr_out_length = MC_CMD_GET_CAPABILITIES_V2_OUT_LEN;
508
509         efx_mcdi_execute(enp, &req);
510
511         if (req.emr_rc != 0) {
512                 rc = req.emr_rc;
513                 goto fail1;
514         }
515
516         if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
517                 rc = EMSGSIZE;
518                 goto fail2;
519         }
520
521         *flagsp = MCDI_OUT_DWORD(req, GET_CAPABILITIES_OUT_FLAGS1);
522
523         if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) {
524                 *flags2p = 0;
525                 *tso2ncp = 0;
526         } else {
527                 *flags2p = MCDI_OUT_DWORD(req, GET_CAPABILITIES_V2_OUT_FLAGS2);
528                 *tso2ncp = MCDI_OUT_WORD(req,
529                                 GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS);
530         }
531
532         return (0);
533
534 fail2:
535         EFSYS_PROBE(fail2);
536 fail1:
537         EFSYS_PROBE1(fail1, efx_rc_t, rc);
538
539         return (rc);
540 }
541
542
543 static  __checkReturn   efx_rc_t
544 efx_mcdi_alloc_vis(
545         __in            efx_nic_t *enp,
546         __in            uint32_t min_vi_count,
547         __in            uint32_t max_vi_count,
548         __out           uint32_t *vi_basep,
549         __out           uint32_t *vi_countp,
550         __out           uint32_t *vi_shiftp)
551 {
552         efx_mcdi_req_t req;
553         uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
554                             MC_CMD_ALLOC_VIS_OUT_LEN)];
555         efx_rc_t rc;
556
557         if (vi_countp == NULL) {
558                 rc = EINVAL;
559                 goto fail1;
560         }
561
562         (void) memset(payload, 0, sizeof (payload));
563         req.emr_cmd = MC_CMD_ALLOC_VIS;
564         req.emr_in_buf = payload;
565         req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
566         req.emr_out_buf = payload;
567         req.emr_out_length = MC_CMD_ALLOC_VIS_OUT_LEN;
568
569         MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count);
570         MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count);
571
572         efx_mcdi_execute(enp, &req);
573
574         if (req.emr_rc != 0) {
575                 rc = req.emr_rc;
576                 goto fail2;
577         }
578
579         if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) {
580                 rc = EMSGSIZE;
581                 goto fail3;
582         }
583
584         *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE);
585         *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT);
586
587         /* Report VI_SHIFT if available (always zero for Huntington) */
588         if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN)
589                 *vi_shiftp = 0;
590         else
591                 *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT);
592
593         return (0);
594
595 fail3:
596         EFSYS_PROBE(fail3);
597 fail2:
598         EFSYS_PROBE(fail2);
599 fail1:
600         EFSYS_PROBE1(fail1, efx_rc_t, rc);
601
602         return (rc);
603 }
604
605
606 static  __checkReturn   efx_rc_t
607 efx_mcdi_free_vis(
608         __in            efx_nic_t *enp)
609 {
610         efx_mcdi_req_t req;
611         efx_rc_t rc;
612
613         EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0);
614         EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0);
615
616         req.emr_cmd = MC_CMD_FREE_VIS;
617         req.emr_in_buf = NULL;
618         req.emr_in_length = 0;
619         req.emr_out_buf = NULL;
620         req.emr_out_length = 0;
621
622         efx_mcdi_execute_quiet(enp, &req);
623
624         /* Ignore ELREADY (no allocated VIs, so nothing to free) */
625         if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) {
626                 rc = req.emr_rc;
627                 goto fail1;
628         }
629
630         return (0);
631
632 fail1:
633         EFSYS_PROBE1(fail1, efx_rc_t, rc);
634
635         return (rc);
636 }
637
638
639 static  __checkReturn   efx_rc_t
640 efx_mcdi_alloc_piobuf(
641         __in            efx_nic_t *enp,
642         __out           efx_piobuf_handle_t *handlep)
643 {
644         efx_mcdi_req_t req;
645         uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
646                             MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
647         efx_rc_t rc;
648
649         if (handlep == NULL) {
650                 rc = EINVAL;
651                 goto fail1;
652         }
653
654         (void) memset(payload, 0, sizeof (payload));
655         req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
656         req.emr_in_buf = payload;
657         req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
658         req.emr_out_buf = payload;
659         req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN;
660
661         efx_mcdi_execute_quiet(enp, &req);
662
663         if (req.emr_rc != 0) {
664                 rc = req.emr_rc;
665                 goto fail2;
666         }
667
668         if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) {
669                 rc = EMSGSIZE;
670                 goto fail3;
671         }
672
673         *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE);
674
675         return (0);
676
677 fail3:
678         EFSYS_PROBE(fail3);
679 fail2:
680         EFSYS_PROBE(fail2);
681 fail1:
682         EFSYS_PROBE1(fail1, efx_rc_t, rc);
683
684         return (rc);
685 }
686
687 static  __checkReturn   efx_rc_t
688 efx_mcdi_free_piobuf(
689         __in            efx_nic_t *enp,
690         __in            efx_piobuf_handle_t handle)
691 {
692         efx_mcdi_req_t req;
693         uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
694                             MC_CMD_FREE_PIOBUF_OUT_LEN)];
695         efx_rc_t rc;
696
697         (void) memset(payload, 0, sizeof (payload));
698         req.emr_cmd = MC_CMD_FREE_PIOBUF;
699         req.emr_in_buf = payload;
700         req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
701         req.emr_out_buf = payload;
702         req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN;
703
704         MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle);
705
706         efx_mcdi_execute_quiet(enp, &req);
707
708         if (req.emr_rc != 0) {
709                 rc = req.emr_rc;
710                 goto fail1;
711         }
712
713         return (0);
714
715 fail1:
716         EFSYS_PROBE1(fail1, efx_rc_t, rc);
717
718         return (rc);
719 }
720
721 static  __checkReturn   efx_rc_t
722 efx_mcdi_link_piobuf(
723         __in            efx_nic_t *enp,
724         __in            uint32_t vi_index,
725         __in            efx_piobuf_handle_t handle)
726 {
727         efx_mcdi_req_t req;
728         uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
729                             MC_CMD_LINK_PIOBUF_OUT_LEN)];
730         efx_rc_t rc;
731
732         (void) memset(payload, 0, sizeof (payload));
733         req.emr_cmd = MC_CMD_LINK_PIOBUF;
734         req.emr_in_buf = payload;
735         req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
736         req.emr_out_buf = payload;
737         req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN;
738
739         MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle);
740         MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
741
742         efx_mcdi_execute(enp, &req);
743
744         if (req.emr_rc != 0) {
745                 rc = req.emr_rc;
746                 goto fail1;
747         }
748
749         return (0);
750
751 fail1:
752         EFSYS_PROBE1(fail1, efx_rc_t, rc);
753
754         return (rc);
755 }
756
757 static  __checkReturn   efx_rc_t
758 efx_mcdi_unlink_piobuf(
759         __in            efx_nic_t *enp,
760         __in            uint32_t vi_index)
761 {
762         efx_mcdi_req_t req;
763         uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
764                             MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
765         efx_rc_t rc;
766
767         (void) memset(payload, 0, sizeof (payload));
768         req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
769         req.emr_in_buf = payload;
770         req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
771         req.emr_out_buf = payload;
772         req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN;
773
774         MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
775
776         efx_mcdi_execute_quiet(enp, &req);
777
778         if (req.emr_rc != 0) {
779                 rc = req.emr_rc;
780                 goto fail1;
781         }
782
783         return (0);
784
785 fail1:
786         EFSYS_PROBE1(fail1, efx_rc_t, rc);
787
788         return (rc);
789 }
790
791 static                  void
792 ef10_nic_alloc_piobufs(
793         __in            efx_nic_t *enp,
794         __in            uint32_t max_piobuf_count)
795 {
796         efx_piobuf_handle_t *handlep;
797         unsigned int i;
798
799         EFSYS_ASSERT3U(max_piobuf_count, <=,
800             EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle));
801
802         enp->en_arch.ef10.ena_piobuf_count = 0;
803
804         for (i = 0; i < max_piobuf_count; i++) {
805                 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
806
807                 if (efx_mcdi_alloc_piobuf(enp, handlep) != 0)
808                         goto fail1;
809
810                 enp->en_arch.ef10.ena_pio_alloc_map[i] = 0;
811                 enp->en_arch.ef10.ena_piobuf_count++;
812         }
813
814         return;
815
816 fail1:
817         for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
818                 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
819
820                 efx_mcdi_free_piobuf(enp, *handlep);
821                 *handlep = EFX_PIOBUF_HANDLE_INVALID;
822         }
823         enp->en_arch.ef10.ena_piobuf_count = 0;
824 }
825
826
827 static                  void
828 ef10_nic_free_piobufs(
829         __in            efx_nic_t *enp)
830 {
831         efx_piobuf_handle_t *handlep;
832         unsigned int i;
833
834         for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
835                 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
836
837                 efx_mcdi_free_piobuf(enp, *handlep);
838                 *handlep = EFX_PIOBUF_HANDLE_INVALID;
839         }
840         enp->en_arch.ef10.ena_piobuf_count = 0;
841 }
842
843 /* Sub-allocate a block from a piobuf */
844         __checkReturn   efx_rc_t
845 ef10_nic_pio_alloc(
846         __inout         efx_nic_t *enp,
847         __out           uint32_t *bufnump,
848         __out           efx_piobuf_handle_t *handlep,
849         __out           uint32_t *blknump,
850         __out           uint32_t *offsetp,
851         __out           size_t *sizep)
852 {
853         efx_nic_cfg_t *encp = &enp->en_nic_cfg;
854         efx_drv_cfg_t *edcp = &enp->en_drv_cfg;
855         uint32_t blk_per_buf;
856         uint32_t buf, blk;
857         efx_rc_t rc;
858
859         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
860                     enp->en_family == EFX_FAMILY_MEDFORD);
861         EFSYS_ASSERT(bufnump);
862         EFSYS_ASSERT(handlep);
863         EFSYS_ASSERT(blknump);
864         EFSYS_ASSERT(offsetp);
865         EFSYS_ASSERT(sizep);
866
867         if ((edcp->edc_pio_alloc_size == 0) ||
868             (enp->en_arch.ef10.ena_piobuf_count == 0)) {
869                 rc = ENOMEM;
870                 goto fail1;
871         }
872         blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size;
873
874         for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) {
875                 uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf];
876
877                 if (~(*map) == 0)
878                         continue;
879
880                 EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map)));
881                 for (blk = 0; blk < blk_per_buf; blk++) {
882                         if ((*map & (1u << blk)) == 0) {
883                                 *map |= (1u << blk);
884                                 goto done;
885                         }
886                 }
887         }
888         rc = ENOMEM;
889         goto fail2;
890
891 done:
892         *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf];
893         *bufnump = buf;
894         *blknump = blk;
895         *sizep = edcp->edc_pio_alloc_size;
896         *offsetp = blk * (*sizep);
897
898         return (0);
899
900 fail2:
901         EFSYS_PROBE(fail2);
902 fail1:
903         EFSYS_PROBE1(fail1, efx_rc_t, rc);
904
905         return (rc);
906 }
907
908 /* Free a piobuf sub-allocated block */
909         __checkReturn   efx_rc_t
910 ef10_nic_pio_free(
911         __inout         efx_nic_t *enp,
912         __in            uint32_t bufnum,
913         __in            uint32_t blknum)
914 {
915         uint32_t *map;
916         efx_rc_t rc;
917
918         if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) ||
919             (blknum >= (8 * sizeof (*map)))) {
920                 rc = EINVAL;
921                 goto fail1;
922         }
923
924         map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum];
925         if ((*map & (1u << blknum)) == 0) {
926                 rc = ENOENT;
927                 goto fail2;
928         }
929         *map &= ~(1u << blknum);
930
931         return (0);
932
933 fail2:
934         EFSYS_PROBE(fail2);
935 fail1:
936         EFSYS_PROBE1(fail1, efx_rc_t, rc);
937
938         return (rc);
939 }
940
941         __checkReturn   efx_rc_t
942 ef10_nic_pio_link(
943         __inout         efx_nic_t *enp,
944         __in            uint32_t vi_index,
945         __in            efx_piobuf_handle_t handle)
946 {
947         return (efx_mcdi_link_piobuf(enp, vi_index, handle));
948 }
949
950         __checkReturn   efx_rc_t
951 ef10_nic_pio_unlink(
952         __inout         efx_nic_t *enp,
953         __in            uint32_t vi_index)
954 {
955         return (efx_mcdi_unlink_piobuf(enp, vi_index));
956 }
957
958 static  __checkReturn   efx_rc_t
959 ef10_mcdi_get_pf_count(
960         __in            efx_nic_t *enp,
961         __out           uint32_t *pf_countp)
962 {
963         efx_mcdi_req_t req;
964         uint8_t payload[MAX(MC_CMD_GET_PF_COUNT_IN_LEN,
965                             MC_CMD_GET_PF_COUNT_OUT_LEN)];
966         efx_rc_t rc;
967
968         (void) memset(payload, 0, sizeof (payload));
969         req.emr_cmd = MC_CMD_GET_PF_COUNT;
970         req.emr_in_buf = payload;
971         req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN;
972         req.emr_out_buf = payload;
973         req.emr_out_length = MC_CMD_GET_PF_COUNT_OUT_LEN;
974
975         efx_mcdi_execute(enp, &req);
976
977         if (req.emr_rc != 0) {
978                 rc = req.emr_rc;
979                 goto fail1;
980         }
981
982         if (req.emr_out_length_used < MC_CMD_GET_PF_COUNT_OUT_LEN) {
983                 rc = EMSGSIZE;
984                 goto fail2;
985         }
986
987         *pf_countp = *MCDI_OUT(req, uint8_t,
988                                 MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST);
989
990         EFSYS_ASSERT(*pf_countp != 0);
991
992         return (0);
993
994 fail2:
995         EFSYS_PROBE(fail2);
996 fail1:
997         EFSYS_PROBE1(fail1, efx_rc_t, rc);
998
999         return (rc);
1000 }
1001
1002         __checkReturn   efx_rc_t
1003 ef10_get_datapath_caps(
1004         __in            efx_nic_t *enp)
1005 {
1006         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1007         uint32_t flags;
1008         uint32_t flags2;
1009         uint32_t tso2nc;
1010         efx_rc_t rc;
1011
1012         if ((rc = efx_mcdi_get_capabilities(enp, &flags, &flags2,
1013                                             &tso2nc)) != 0)
1014                 goto fail1;
1015
1016         if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
1017                 goto fail1;
1018
1019 #define CAP_FLAG(flags1, field)         \
1020         ((flags1) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
1021
1022 #define CAP_FLAG2(flags2, field)        \
1023         ((flags2) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
1024
1025         /*
1026          * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
1027          * We only support the 14 byte prefix here.
1028          */
1029         if (CAP_FLAG(flags, RX_PREFIX_LEN_14) == 0) {
1030                 rc = ENOTSUP;
1031                 goto fail2;
1032         }
1033         encp->enc_rx_prefix_size = 14;
1034
1035         /* Check if the firmware supports TSO */
1036         encp->enc_fw_assisted_tso_enabled =
1037             CAP_FLAG(flags, TX_TSO) ? B_TRUE : B_FALSE;
1038
1039         /* Check if the firmware supports FATSOv2 */
1040         encp->enc_fw_assisted_tso_v2_enabled =
1041             CAP_FLAG2(flags2, TX_TSO_V2) ? B_TRUE : B_FALSE;
1042
1043         /* Get the number of TSO contexts (FATSOv2) */
1044         encp->enc_fw_assisted_tso_v2_n_contexts =
1045                 CAP_FLAG2(flags2, TX_TSO_V2) ? tso2nc : 0;
1046
1047         /* Check if the firmware has vadapter/vport/vswitch support */
1048         encp->enc_datapath_cap_evb =
1049             CAP_FLAG(flags, EVB) ? B_TRUE : B_FALSE;
1050
1051         /* Check if the firmware supports VLAN insertion */
1052         encp->enc_hw_tx_insert_vlan_enabled =
1053             CAP_FLAG(flags, TX_VLAN_INSERTION) ? B_TRUE : B_FALSE;
1054
1055         /* Check if the firmware supports RX event batching */
1056         encp->enc_rx_batching_enabled =
1057             CAP_FLAG(flags, RX_BATCHING) ? B_TRUE : B_FALSE;
1058
1059         /*
1060          * Even if batching isn't reported as supported, we may still get
1061          * batched events (see bug61153).
1062          */
1063         encp->enc_rx_batch_max = 16;
1064
1065         /* Check if the firmware supports disabling scatter on RXQs */
1066         encp->enc_rx_disable_scatter_supported =
1067             CAP_FLAG(flags, RX_DISABLE_SCATTER) ? B_TRUE : B_FALSE;
1068
1069         /* Check if the firmware supports packed stream mode */
1070         encp->enc_rx_packed_stream_supported =
1071             CAP_FLAG(flags, RX_PACKED_STREAM) ? B_TRUE : B_FALSE;
1072
1073         /*
1074          * Check if the firmware supports configurable buffer sizes
1075          * for packed stream mode (otherwise buffer size is 1Mbyte)
1076          */
1077         encp->enc_rx_var_packed_stream_supported =
1078             CAP_FLAG(flags, RX_PACKED_STREAM_VAR_BUFFERS) ? B_TRUE : B_FALSE;
1079
1080         /* Check if the firmware supports set mac with running filters */
1081         encp->enc_allow_set_mac_with_installed_filters =
1082             CAP_FLAG(flags, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED) ?
1083             B_TRUE : B_FALSE;
1084
1085         /*
1086          * Check if firmware supports the extended MC_CMD_SET_MAC, which allows
1087          * specifying which parameters to configure.
1088          */
1089         encp->enc_enhanced_set_mac_supported =
1090                 CAP_FLAG(flags, SET_MAC_ENHANCED) ? B_TRUE : B_FALSE;
1091
1092         /*
1093          * Check if firmware supports version 2 of MC_CMD_INIT_EVQ, which allows
1094          * us to let the firmware choose the settings to use on an EVQ.
1095          */
1096         encp->enc_init_evq_v2_supported =
1097                 CAP_FLAG2(flags2, INIT_EVQ_V2) ? B_TRUE : B_FALSE;
1098
1099         /*
1100          * Check if firmware-verified NVRAM updates must be used.
1101          *
1102          * The firmware trusted installer requires all NVRAM updates to use
1103          * version 2 of MC_CMD_NVRAM_UPDATE_START (to enable verified update)
1104          * and version 2 of MC_CMD_NVRAM_UPDATE_FINISH (to verify the updated
1105          * partition and report the result).
1106          */
1107         encp->enc_fw_verified_nvram_update_required =
1108             CAP_FLAG2(flags2, NVRAM_UPDATE_REPORT_VERIFY_RESULT) ?
1109             B_TRUE : B_FALSE;
1110
1111         /*
1112          * Check if firmware provides packet memory and Rx datapath
1113          * counters.
1114          */
1115         encp->enc_pm_and_rxdp_counters =
1116             CAP_FLAG(flags, PM_AND_RXDP_COUNTERS) ? B_TRUE : B_FALSE;
1117
1118         /*
1119          * Check if the 40G MAC hardware is capable of reporting
1120          * statistics for Tx size bins.
1121          */
1122         encp->enc_mac_stats_40g_tx_size_bins =
1123             CAP_FLAG2(flags2, MAC_STATS_40G_TX_SIZE_BINS) ? B_TRUE : B_FALSE;
1124
1125 #undef CAP_FLAG
1126 #undef CAP_FLAG2
1127
1128         return (0);
1129
1130 fail2:
1131         EFSYS_PROBE(fail2);
1132 fail1:
1133         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1134
1135         return (rc);
1136 }
1137
1138
1139 #define EF10_LEGACY_PF_PRIVILEGE_MASK                                   \
1140         (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN                     |       \
1141         MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK                       |       \
1142         MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD                     |       \
1143         MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP                        |       \
1144         MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS           |       \
1145         MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING               |       \
1146         MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST                    |       \
1147         MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST                  |       \
1148         MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST                  |       \
1149         MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST              |       \
1150         MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS)
1151
1152 #define EF10_LEGACY_VF_PRIVILEGE_MASK   0
1153
1154
1155         __checkReturn           efx_rc_t
1156 ef10_get_privilege_mask(
1157         __in                    efx_nic_t *enp,
1158         __out                   uint32_t *maskp)
1159 {
1160         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1161         uint32_t mask;
1162         efx_rc_t rc;
1163
1164         if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf,
1165                                             &mask)) != 0) {
1166                 if (rc != ENOTSUP)
1167                         goto fail1;
1168
1169                 /* Fallback for old firmware without privilege mask support */
1170                 if (EFX_PCI_FUNCTION_IS_PF(encp)) {
1171                         /* Assume PF has admin privilege */
1172                         mask = EF10_LEGACY_PF_PRIVILEGE_MASK;
1173                 } else {
1174                         /* VF is always unprivileged by default */
1175                         mask = EF10_LEGACY_VF_PRIVILEGE_MASK;
1176                 }
1177         }
1178
1179         *maskp = mask;
1180
1181         return (0);
1182
1183 fail1:
1184         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1185
1186         return (rc);
1187 }
1188
1189
1190 /*
1191  * Table of mapping schemes from port number to the number of the external
1192  * connector on the board. The external numbering does not distinguish
1193  * off-board separated outputs such as from multi-headed cables.
1194  *
1195  * The count of adjacent port numbers that map to each external port
1196  * and the offset in the numbering, is determined by the chip family and
1197  * current port mode.
1198  *
1199  * For the Huntington family, the current port mode cannot be discovered,
1200  * so the mapping used is instead the last match in the table to the full
1201  * set of port modes to which the NIC can be configured. Therefore the
1202  * ordering of entries in the the mapping table is significant.
1203  */
1204 static struct {
1205         efx_family_t    family;
1206         uint32_t        modes_mask;
1207         int32_t         count;
1208         int32_t         offset;
1209 }       __ef10_external_port_mappings[] = {
1210         /* Supported modes with 1 output per external port */
1211         {
1212                 EFX_FAMILY_HUNTINGTON,
1213                 (1 << TLV_PORT_MODE_10G) |
1214                 (1 << TLV_PORT_MODE_10G_10G) |
1215                 (1 << TLV_PORT_MODE_10G_10G_10G_10G),
1216                 1,
1217                 1
1218         },
1219         {
1220                 EFX_FAMILY_MEDFORD,
1221                 (1 << TLV_PORT_MODE_10G) |
1222                 (1 << TLV_PORT_MODE_10G_10G),
1223                 1,
1224                 1
1225         },
1226         /* Supported modes with 2 outputs per external port */
1227         {
1228                 EFX_FAMILY_HUNTINGTON,
1229                 (1 << TLV_PORT_MODE_40G) |
1230                 (1 << TLV_PORT_MODE_40G_40G) |
1231                 (1 << TLV_PORT_MODE_40G_10G_10G) |
1232                 (1 << TLV_PORT_MODE_10G_10G_40G),
1233                 2,
1234                 1
1235         },
1236         {
1237                 EFX_FAMILY_MEDFORD,
1238                 (1 << TLV_PORT_MODE_40G) |
1239                 (1 << TLV_PORT_MODE_40G_40G) |
1240                 (1 << TLV_PORT_MODE_40G_10G_10G) |
1241                 (1 << TLV_PORT_MODE_10G_10G_40G) |
1242                 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2),
1243                 2,
1244                 1
1245         },
1246         /* Supported modes with 4 outputs per external port */
1247         {
1248                 EFX_FAMILY_MEDFORD,
1249                 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) |
1250                 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1),
1251                 4,
1252                 1,
1253         },
1254         {
1255                 EFX_FAMILY_MEDFORD,
1256                 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2),
1257                 4,
1258                 2
1259         },
1260 };
1261
1262         __checkReturn   efx_rc_t
1263 ef10_external_port_mapping(
1264         __in            efx_nic_t *enp,
1265         __in            uint32_t port,
1266         __out           uint8_t *external_portp)
1267 {
1268         efx_rc_t rc;
1269         int i;
1270         uint32_t port_modes;
1271         uint32_t matches;
1272         uint32_t current;
1273         int32_t count = 1; /* Default 1-1 mapping */
1274         int32_t offset = 1; /* Default starting external port number */
1275
1276         if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current)) != 0) {
1277                 /*
1278                  * No current port mode information
1279                  * - infer mapping from available modes
1280                  */
1281                 if ((rc = efx_mcdi_get_port_modes(enp,
1282                             &port_modes, NULL)) != 0) {
1283                         /*
1284                          * No port mode information available
1285                          * - use default mapping
1286                          */
1287                         goto out;
1288                 }
1289         } else {
1290                 /* Only need to scan the current mode */
1291                 port_modes = 1 << current;
1292         }
1293
1294         /*
1295          * Infer the internal port -> external port mapping from
1296          * the possible port modes for this NIC.
1297          */
1298         for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) {
1299                 if (__ef10_external_port_mappings[i].family !=
1300                     enp->en_family)
1301                         continue;
1302                 matches = (__ef10_external_port_mappings[i].modes_mask &
1303                     port_modes);
1304                 if (matches != 0) {
1305                         count = __ef10_external_port_mappings[i].count;
1306                         offset = __ef10_external_port_mappings[i].offset;
1307                         port_modes &= ~matches;
1308                 }
1309         }
1310
1311         if (port_modes != 0) {
1312                 /* Some advertised modes are not supported */
1313                 rc = ENOTSUP;
1314                 goto fail1;
1315         }
1316
1317 out:
1318         /*
1319          * Scale as required by last matched mode and then convert to
1320          * correctly offset numbering
1321          */
1322         *external_portp = (uint8_t)((port / count) + offset);
1323         return (0);
1324
1325 fail1:
1326         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1327
1328         return (rc);
1329 }
1330
1331
1332         __checkReturn   efx_rc_t
1333 ef10_nic_probe(
1334         __in            efx_nic_t *enp)
1335 {
1336         const efx_nic_ops_t *enop = enp->en_enop;
1337         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1338         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
1339         efx_rc_t rc;
1340
1341         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
1342                     enp->en_family == EFX_FAMILY_MEDFORD);
1343
1344         /* Read and clear any assertion state */
1345         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
1346                 goto fail1;
1347
1348         /* Exit the assertion handler */
1349         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
1350                 if (rc != EACCES)
1351                         goto fail2;
1352
1353         if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
1354                 goto fail3;
1355
1356         if ((rc = enop->eno_board_cfg(enp)) != 0)
1357                 if (rc != EACCES)
1358                         goto fail4;
1359
1360         /*
1361          * Set default driver config limits (based on board config).
1362          *
1363          * FIXME: For now allocate a fixed number of VIs which is likely to be
1364          * sufficient and small enough to allow multiple functions on the same
1365          * port.
1366          */
1367         edcp->edc_min_vi_count = edcp->edc_max_vi_count =
1368             MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
1369
1370         /* The client driver must configure and enable PIO buffer support */
1371         edcp->edc_max_piobuf_count = 0;
1372         edcp->edc_pio_alloc_size = 0;
1373
1374         encp->enc_features = enp->en_features;
1375
1376         return (0);
1377
1378 fail4:
1379         EFSYS_PROBE(fail4);
1380 fail3:
1381         EFSYS_PROBE(fail3);
1382 fail2:
1383         EFSYS_PROBE(fail2);
1384 fail1:
1385         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1386
1387         return (rc);
1388 }
1389
1390         __checkReturn   efx_rc_t
1391 ef10_nic_set_drv_limits(
1392         __inout         efx_nic_t *enp,
1393         __in            efx_drv_limits_t *edlp)
1394 {
1395         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1396         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
1397         uint32_t min_evq_count, max_evq_count;
1398         uint32_t min_rxq_count, max_rxq_count;
1399         uint32_t min_txq_count, max_txq_count;
1400         efx_rc_t rc;
1401
1402         if (edlp == NULL) {
1403                 rc = EINVAL;
1404                 goto fail1;
1405         }
1406
1407         /* Get minimum required and maximum usable VI limits */
1408         min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
1409         min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
1410         min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
1411
1412         edcp->edc_min_vi_count =
1413             MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
1414
1415         max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
1416         max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
1417         max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
1418
1419         edcp->edc_max_vi_count =
1420             MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
1421
1422         /*
1423          * Check limits for sub-allocated piobuf blocks.
1424          * PIO is optional, so don't fail if the limits are incorrect.
1425          */
1426         if ((encp->enc_piobuf_size == 0) ||
1427             (encp->enc_piobuf_limit == 0) ||
1428             (edlp->edl_min_pio_alloc_size == 0) ||
1429             (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) {
1430                 /* Disable PIO */
1431                 edcp->edc_max_piobuf_count = 0;
1432                 edcp->edc_pio_alloc_size = 0;
1433         } else {
1434                 uint32_t blk_size, blk_count, blks_per_piobuf;
1435
1436                 blk_size =
1437                     MAX(edlp->edl_min_pio_alloc_size,
1438                             encp->enc_piobuf_min_alloc_size);
1439
1440                 blks_per_piobuf = encp->enc_piobuf_size / blk_size;
1441                 EFSYS_ASSERT3U(blks_per_piobuf, <=, 32);
1442
1443                 blk_count = (encp->enc_piobuf_limit * blks_per_piobuf);
1444
1445                 /* A zero max pio alloc count means unlimited */
1446                 if ((edlp->edl_max_pio_alloc_count > 0) &&
1447                     (edlp->edl_max_pio_alloc_count < blk_count)) {
1448                         blk_count = edlp->edl_max_pio_alloc_count;
1449                 }
1450
1451                 edcp->edc_pio_alloc_size = blk_size;
1452                 edcp->edc_max_piobuf_count =
1453                     (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf;
1454         }
1455
1456         return (0);
1457
1458 fail1:
1459         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1460
1461         return (rc);
1462 }
1463
1464
1465         __checkReturn   efx_rc_t
1466 ef10_nic_reset(
1467         __in            efx_nic_t *enp)
1468 {
1469         efx_mcdi_req_t req;
1470         uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
1471                             MC_CMD_ENTITY_RESET_OUT_LEN)];
1472         efx_rc_t rc;
1473
1474         /* ef10_nic_reset() is called to recover from BADASSERT failures. */
1475         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
1476                 goto fail1;
1477         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
1478                 goto fail2;
1479
1480         (void) memset(payload, 0, sizeof (payload));
1481         req.emr_cmd = MC_CMD_ENTITY_RESET;
1482         req.emr_in_buf = payload;
1483         req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
1484         req.emr_out_buf = payload;
1485         req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
1486
1487         MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
1488             ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
1489
1490         efx_mcdi_execute(enp, &req);
1491
1492         if (req.emr_rc != 0) {
1493                 rc = req.emr_rc;
1494                 goto fail3;
1495         }
1496
1497         /* Clear RX/TX DMA queue errors */
1498         enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
1499
1500         return (0);
1501
1502 fail3:
1503         EFSYS_PROBE(fail3);
1504 fail2:
1505         EFSYS_PROBE(fail2);
1506 fail1:
1507         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1508
1509         return (rc);
1510 }
1511
1512         __checkReturn   efx_rc_t
1513 ef10_nic_init(
1514         __in            efx_nic_t *enp)
1515 {
1516         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
1517         uint32_t min_vi_count, max_vi_count;
1518         uint32_t vi_count, vi_base, vi_shift;
1519         uint32_t i;
1520         uint32_t retry;
1521         uint32_t delay_us;
1522         efx_rc_t rc;
1523
1524         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
1525                     enp->en_family == EFX_FAMILY_MEDFORD);
1526
1527         /* Enable reporting of some events (e.g. link change) */
1528         if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
1529                 goto fail1;
1530
1531         /* Allocate (optional) on-chip PIO buffers */
1532         ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count);
1533
1534         /*
1535          * For best performance, PIO writes should use a write-combined
1536          * (WC) memory mapping. Using a separate WC mapping for the PIO
1537          * aperture of each VI would be a burden to drivers (and not
1538          * possible if the host page size is >4Kbyte).
1539          *
1540          * To avoid this we use a single uncached (UC) mapping for VI
1541          * register access, and a single WC mapping for extra VIs used
1542          * for PIO writes.
1543          *
1544          * Each piobuf must be linked to a VI in the WC mapping, and to
1545          * each VI that is using a sub-allocated block from the piobuf.
1546          */
1547         min_vi_count = edcp->edc_min_vi_count;
1548         max_vi_count =
1549             edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count;
1550
1551         /* Ensure that the previously attached driver's VIs are freed */
1552         if ((rc = efx_mcdi_free_vis(enp)) != 0)
1553                 goto fail2;
1554
1555         /*
1556          * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
1557          * fails then retrying the request for fewer VI resources may succeed.
1558          */
1559         vi_count = 0;
1560         if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
1561                     &vi_base, &vi_count, &vi_shift)) != 0)
1562                 goto fail3;
1563
1564         EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
1565
1566         if (vi_count < min_vi_count) {
1567                 rc = ENOMEM;
1568                 goto fail4;
1569         }
1570
1571         enp->en_arch.ef10.ena_vi_base = vi_base;
1572         enp->en_arch.ef10.ena_vi_count = vi_count;
1573         enp->en_arch.ef10.ena_vi_shift = vi_shift;
1574
1575         if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) {
1576                 /* Not enough extra VIs to map piobufs */
1577                 ef10_nic_free_piobufs(enp);
1578         }
1579
1580         enp->en_arch.ef10.ena_pio_write_vi_base =
1581             vi_count - enp->en_arch.ef10.ena_piobuf_count;
1582
1583         /* Save UC memory mapping details */
1584         enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
1585         if (enp->en_arch.ef10.ena_piobuf_count > 0) {
1586                 enp->en_arch.ef10.ena_uc_mem_map_size =
1587                     (ER_DZ_TX_PIOBUF_STEP *
1588                     enp->en_arch.ef10.ena_pio_write_vi_base);
1589         } else {
1590                 enp->en_arch.ef10.ena_uc_mem_map_size =
1591                     (ER_DZ_TX_PIOBUF_STEP *
1592                     enp->en_arch.ef10.ena_vi_count);
1593         }
1594
1595         /* Save WC memory mapping details */
1596         enp->en_arch.ef10.ena_wc_mem_map_offset =
1597             enp->en_arch.ef10.ena_uc_mem_map_offset +
1598             enp->en_arch.ef10.ena_uc_mem_map_size;
1599
1600         enp->en_arch.ef10.ena_wc_mem_map_size =
1601             (ER_DZ_TX_PIOBUF_STEP *
1602             enp->en_arch.ef10.ena_piobuf_count);
1603
1604         /* Link piobufs to extra VIs in WC mapping */
1605         if (enp->en_arch.ef10.ena_piobuf_count > 0) {
1606                 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
1607                         rc = efx_mcdi_link_piobuf(enp,
1608                             enp->en_arch.ef10.ena_pio_write_vi_base + i,
1609                             enp->en_arch.ef10.ena_piobuf_handle[i]);
1610                         if (rc != 0)
1611                                 break;
1612                 }
1613         }
1614
1615         /*
1616          * Allocate a vAdaptor attached to our upstream vPort/pPort.
1617          *
1618          * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF
1619          * driver has yet to bring up the EVB port. See bug 56147. In this case,
1620          * retry the request several times after waiting a while. The wait time
1621          * between retries starts small (10ms) and exponentially increases.
1622          * Total wait time is a little over two seconds. Retry logic in the
1623          * client driver may mean this whole loop is repeated if it continues to
1624          * fail.
1625          */
1626         retry = 0;
1627         delay_us = 10000;
1628         while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) {
1629                 if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) ||
1630                     (rc != ENOENT)) {
1631                         /*
1632                          * Do not retry alloc for PF, or for other errors on
1633                          * a VF.
1634                          */
1635                         goto fail5;
1636                 }
1637
1638                 /* VF startup before PF is ready. Retry allocation. */
1639                 if (retry > 5) {
1640                         /* Too many attempts */
1641                         rc = EINVAL;
1642                         goto fail6;
1643                 }
1644                 EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry);
1645                 EFSYS_SLEEP(delay_us);
1646                 retry++;
1647                 if (delay_us < 500000)
1648                         delay_us <<= 2;
1649         }
1650
1651         enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
1652         enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
1653
1654         return (0);
1655
1656 fail6:
1657         EFSYS_PROBE(fail6);
1658 fail5:
1659         EFSYS_PROBE(fail5);
1660 fail4:
1661         EFSYS_PROBE(fail4);
1662 fail3:
1663         EFSYS_PROBE(fail3);
1664 fail2:
1665         EFSYS_PROBE(fail2);
1666
1667         ef10_nic_free_piobufs(enp);
1668
1669 fail1:
1670         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1671
1672         return (rc);
1673 }
1674
1675         __checkReturn   efx_rc_t
1676 ef10_nic_get_vi_pool(
1677         __in            efx_nic_t *enp,
1678         __out           uint32_t *vi_countp)
1679 {
1680         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
1681                     enp->en_family == EFX_FAMILY_MEDFORD);
1682
1683         /*
1684          * Report VIs that the client driver can use.
1685          * Do not include VIs used for PIO buffer writes.
1686          */
1687         *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base;
1688
1689         return (0);
1690 }
1691
1692         __checkReturn   efx_rc_t
1693 ef10_nic_get_bar_region(
1694         __in            efx_nic_t *enp,
1695         __in            efx_nic_region_t region,
1696         __out           uint32_t *offsetp,
1697         __out           size_t *sizep)
1698 {
1699         efx_rc_t rc;
1700
1701         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
1702                     enp->en_family == EFX_FAMILY_MEDFORD);
1703
1704         /*
1705          * TODO: Specify host memory mapping alignment and granularity
1706          * in efx_drv_limits_t so that they can be taken into account
1707          * when allocating extra VIs for PIO writes.
1708          */
1709         switch (region) {
1710         case EFX_REGION_VI:
1711                 /* UC mapped memory BAR region for VI registers */
1712                 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
1713                 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
1714                 break;
1715
1716         case EFX_REGION_PIO_WRITE_VI:
1717                 /* WC mapped memory BAR region for piobuf writes */
1718                 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
1719                 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
1720                 break;
1721
1722         default:
1723                 rc = EINVAL;
1724                 goto fail1;
1725         }
1726
1727         return (0);
1728
1729 fail1:
1730         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1731
1732         return (rc);
1733 }
1734
1735                         void
1736 ef10_nic_fini(
1737         __in            efx_nic_t *enp)
1738 {
1739         uint32_t i;
1740         efx_rc_t rc;
1741
1742         (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
1743         enp->en_vport_id = 0;
1744
1745         /* Unlink piobufs from extra VIs in WC mapping */
1746         if (enp->en_arch.ef10.ena_piobuf_count > 0) {
1747                 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
1748                         rc = efx_mcdi_unlink_piobuf(enp,
1749                             enp->en_arch.ef10.ena_pio_write_vi_base + i);
1750                         if (rc != 0)
1751                                 break;
1752                 }
1753         }
1754
1755         ef10_nic_free_piobufs(enp);
1756
1757         (void) efx_mcdi_free_vis(enp);
1758         enp->en_arch.ef10.ena_vi_count = 0;
1759 }
1760
1761                         void
1762 ef10_nic_unprobe(
1763         __in            efx_nic_t *enp)
1764 {
1765         (void) efx_mcdi_drv_attach(enp, B_FALSE);
1766 }
1767
1768
1769 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */