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