xref: /illumos-gate/usr/src/uts/common/io/sfxge/sfxge.c (revision 49ef7e06)
1 /*
2  * Copyright (c) 2008-2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30 
31 #include <sys/types.h>
32 #include <sys/ddi.h>
33 #include <sys/sunddi.h>
34 #include <sys/modctl.h>
35 #include <sys/conf.h>
36 #include <sys/ethernet.h>
37 #include <sys/pci.h>
38 #include <sys/stream.h>
39 #include <sys/strsun.h>
40 #include <sys/processor.h>
41 #include <sys/cpuvar.h>
42 #include <sys/pghw.h>
43 
44 #include "sfxge.h"
45 #include "sfxge_version.h"
46 #include "efsys.h"
47 #include "efx.h"
48 
49 #ifdef	DEBUG
50 boolean_t sfxge_aask = B_FALSE;
51 #endif
52 
53 /* Receive queue TRIM default polling interval (in microseconds) */
54 #define	SFXGE_RX_QPOLL_USEC	(5000000)
55 
56 /* Broadcast address */
57 uint8_t	sfxge_brdcst[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
58 
59 /*
60  * By default modinfo will display lines truncated to 80 characters and so just
61  * show 32 characters of our sfxge_ident string.
62  */
63 const char sfxge_ident[] = "Solarflare 10Gb/40Gb Ethernet";
64 const char sfxge_version[] = SFXGE_VERSION_STRING;
65 
66 static void
sfxge_cfg_build(sfxge_t * sp)67 sfxge_cfg_build(sfxge_t *sp)
68 {
69 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sp->s_enp);
70 	(void) snprintf(sp->s_cfg_kstat.buf.sck_mac, 64,
71 	    "%02X:%02X:%02X:%02X:%02X:%02X",
72 	    encp->enc_mac_addr[0], encp->enc_mac_addr[1],
73 	    encp->enc_mac_addr[2], encp->enc_mac_addr[3],
74 	    encp->enc_mac_addr[4], encp->enc_mac_addr[5]);
75 }
76 
77 static int
sfxge_create(dev_info_t * dip,sfxge_t ** spp)78 sfxge_create(dev_info_t *dip, sfxge_t **spp)
79 {
80 	sfxge_t *sp;
81 	efx_nic_t *enp;
82 	unsigned int rxq_size;
83 	int rxq_poll_usec;
84 	int rc;
85 
86 	/* Allocate the object */
87 	sp = kmem_zalloc(sizeof (*sp), KM_SLEEP);
88 	sp->s_dip = dip;
89 	ddi_set_driver_private(dip, sp);
90 
91 	mutex_init(&(sp->s_state_lock), NULL, MUTEX_DRIVER, NULL);
92 	sp->s_state = SFXGE_UNINITIALIZED;
93 
94 	/* Get property values */
95 	sp->s_mtu = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip,
96 	    DDI_PROP_DONTPASS, "mtu", ETHERMTU);
97 
98 	sp->s_action_on_hw_err = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip,
99 	    DDI_PROP_DONTPASS, "action_on_hw_err", SFXGE_RECOVER);
100 
101 	rxq_size = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip,
102 	    DDI_PROP_DONTPASS, "rxq_size", SFXGE_DEFAULT_RXQ_SIZE);
103 	if (!(ISP2(rxq_size)))
104 		rxq_size = SFXGE_DEFAULT_RXQ_SIZE;
105 	rxq_size = min(rxq_size, EFX_RXQ_MAXNDESCS);
106 	sp->s_rxq_size = (uint16_t)max(rxq_size, EFX_RXQ_MINNDESCS);
107 
108 	/* Configure polling interval for queue refill/trim */
109 	rxq_poll_usec = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip,
110 	    DDI_PROP_DONTPASS, "rxq_poll_usec", SFXGE_RX_QPOLL_USEC);
111 	if (rxq_poll_usec <= 0)
112 		rxq_poll_usec = SFXGE_RX_QPOLL_USEC;
113 	sp->s_rxq_poll_usec = rxq_poll_usec;
114 
115 #if EFSYS_OPT_MCDI_LOGGING
116 	sp->s_mcdi_logging = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip,
117 	    DDI_PROP_DONTPASS, "mcdi_logging", 0);
118 #endif
119 
120 	/* Create a taskq */
121 	sp->s_tqp = ddi_taskq_create(dip, "tq", 1, TASKQ_DEFAULTPRI, 0);
122 	if (sp->s_tqp == NULL) {
123 		rc = ENOMEM;
124 		goto fail2;
125 	}
126 
127 	/* Check and initialize PCI configuration space */
128 	if ((rc = sfxge_pci_init(sp)) != 0)
129 		goto fail3;
130 
131 	/* Map the device registers */
132 	if ((rc = sfxge_bar_init(sp)) != 0)
133 		goto fail4;
134 
135 	/* Create the NIC object */
136 	mutex_init(&(sp->s_nic_lock), NULL, MUTEX_DRIVER, NULL);
137 
138 	if ((rc = efx_nic_create(sp->s_family, (efsys_identifier_t *)sp,
139 	    &(sp->s_bar), &(sp->s_nic_lock), &enp)) != 0)
140 		goto fail5;
141 
142 	sp->s_enp = enp;
143 
144 	/* Initialize MCDI to talk to the Microcontroller */
145 	if ((rc = sfxge_mcdi_init(sp)) != 0)
146 		goto fail6;
147 
148 	/* Probe the NIC and build the configuration data area */
149 	if ((rc = efx_nic_probe(enp)) != 0)
150 		goto fail7;
151 
152 	switch (sp->s_family) {
153 	case EFX_FAMILY_HUNTINGTON:
154 		sfxge_pcie_check_link(sp, 8, 3); /* PCI 8x Gen3 */
155 		break;
156 
157 	case EFX_FAMILY_SIENA:
158 		sfxge_pcie_check_link(sp, 8, 2); /* PCI 8x Gen2 */
159 		break;
160 
161 	default:
162 		break;
163 	}
164 
165 	if ((rc = efx_nvram_init(enp)) != 0)
166 		goto fail8;
167 
168 	if ((rc = efx_vpd_init(enp)) != 0)
169 		goto fail9;
170 
171 	if ((rc = efx_nic_reset(enp)) != 0)
172 		goto fail10;
173 
174 	sfxge_sram_init(sp);
175 
176 	if ((rc = sfxge_intr_init(sp)) != 0)
177 		goto fail11;
178 
179 	if ((rc = sfxge_ev_init(sp)) != 0)
180 		goto fail12;
181 
182 	if ((rc = sfxge_mac_init(sp)) != 0)
183 		goto fail13;
184 
185 	if ((rc = sfxge_rx_init(sp)) != 0)
186 		goto fail14;
187 
188 	if ((rc = sfxge_tx_init(sp)) != 0)
189 		goto fail15;
190 
191 	if ((rc = sfxge_mon_init(sp)) != 0)
192 		goto fail16;
193 
194 	mutex_init(&(sp->s_tx_flush_lock), NULL, MUTEX_DRIVER,
195 	    DDI_INTR_PRI(sp->s_intr.si_intr_pri));
196 	cv_init(&(sp->s_tx_flush_kv), NULL, CV_DRIVER, NULL);
197 
198 	sp->s_state = SFXGE_INITIALIZED;
199 
200 	*spp = sp;
201 	return (0);
202 
203 fail16:
204 	DTRACE_PROBE(fail15);
205 	sfxge_tx_fini(sp);
206 
207 fail15:
208 	DTRACE_PROBE(fail14);
209 	sfxge_rx_fini(sp);
210 
211 fail14:
212 	DTRACE_PROBE(fail14);
213 	sfxge_mac_fini(sp);
214 
215 fail13:
216 	DTRACE_PROBE(fail13);
217 	sfxge_ev_fini(sp);
218 
219 fail12:
220 	DTRACE_PROBE(fail12);
221 	sfxge_intr_fini(sp);
222 
223 fail11:
224 	DTRACE_PROBE(fail11);
225 	sfxge_sram_fini(sp);
226 	(void) efx_nic_reset(sp->s_enp);
227 
228 fail10:
229 	DTRACE_PROBE(fail10);
230 	efx_vpd_fini(enp);
231 
232 fail9:
233 	DTRACE_PROBE(fail9);
234 	efx_nvram_fini(enp);
235 
236 fail8:
237 	DTRACE_PROBE(fail8);
238 	efx_nic_unprobe(enp);
239 
240 fail7:
241 	DTRACE_PROBE(fail7);
242 	sfxge_mcdi_fini(sp);
243 
244 fail6:
245 	DTRACE_PROBE(fail6);
246 	sp->s_enp = NULL;
247 	efx_nic_destroy(enp);
248 
249 fail5:
250 	DTRACE_PROBE(fail5);
251 	mutex_destroy(&(sp->s_nic_lock));
252 	sfxge_bar_fini(sp);
253 
254 fail4:
255 	DTRACE_PROBE(fail4);
256 	sfxge_pci_fini(sp);
257 
258 fail3:
259 	DTRACE_PROBE(fail3);
260 	ddi_taskq_destroy(sp->s_tqp);
261 	sp->s_tqp = NULL;
262 
263 fail2:
264 	DTRACE_PROBE(fail2);
265 
266 	/* Clear property values */
267 	sp->s_mtu = 0;
268 
269 	mutex_destroy(&(sp->s_state_lock));
270 
271 	/* Free the soft state */
272 	sp->s_dip = NULL;
273 
274 	SFXGE_OBJ_CHECK(sp, sfxge_t);
275 	kmem_free(sp, sizeof (*sp));
276 
277 	return (rc);
278 }
279 
280 
281 static int
sfxge_start_locked(sfxge_t * sp,boolean_t restart)282 sfxge_start_locked(sfxge_t *sp, boolean_t restart)
283 {
284 	int rc;
285 
286 	ASSERT(mutex_owned(&(sp->s_state_lock)));
287 
288 	if (sp->s_state == SFXGE_STARTED)
289 		goto done;
290 
291 	if (sp->s_state != SFXGE_REGISTERED) {
292 		rc = EINVAL;
293 		goto fail1;
294 	}
295 	sp->s_state = SFXGE_STARTING;
296 
297 	/* Start a new epoch (allow fresh MCDI requests to succeed) */
298 	efx_mcdi_new_epoch(sp->s_enp);
299 
300 	if ((rc = efx_nic_reset(sp->s_enp)) != 0)
301 		goto fail2;
302 
303 	if ((rc = efx_nic_init(sp->s_enp)) != 0)
304 		goto fail3;
305 
306 	if ((rc = efx_filter_init(sp->s_enp)) != 0)
307 		goto fail4;
308 
309 	if ((rc = sfxge_sram_start(sp)) != 0)
310 		goto fail5;
311 
312 	if ((rc = sfxge_intr_start(sp)) != 0)
313 		goto fail6;
314 
315 	if ((rc = sfxge_ev_start(sp)) != 0)
316 		goto fail7;
317 
318 	if ((rc = sfxge_mac_start(sp, restart)) != 0)
319 		goto fail8;
320 
321 	if ((rc = sfxge_rx_start(sp)) != 0)
322 		goto fail9;
323 
324 	if ((rc = sfxge_tx_start(sp)) != 0)
325 		goto fail10;
326 
327 	if ((rc = sfxge_mon_start(sp)) != 0)
328 		goto fail11;
329 
330 	ASSERT3U(sp->s_state, ==, SFXGE_STARTING);
331 	sp->s_state = SFXGE_STARTED;
332 
333 	/* Notify any change of MTU */
334 	sfxge_gld_mtu_update(sp);
335 
336 done:
337 	return (0);
338 
339 fail11:
340 	DTRACE_PROBE(fail11);
341 	sfxge_tx_stop(sp);
342 
343 fail10:
344 	DTRACE_PROBE(fail10);
345 	sfxge_rx_stop(sp);
346 
347 fail9:
348 	DTRACE_PROBE(fail9);
349 	sfxge_mac_stop(sp);
350 
351 fail8:
352 	DTRACE_PROBE(fail8);
353 	sfxge_ev_stop(sp);
354 
355 fail7:
356 	DTRACE_PROBE(fail7);
357 	sfxge_intr_stop(sp);
358 
359 fail6:
360 	DTRACE_PROBE(fail6);
361 	sfxge_sram_stop(sp);
362 
363 fail5:
364 	DTRACE_PROBE(fail5);
365 	efx_filter_fini(sp->s_enp);
366 
367 fail4:
368 	DTRACE_PROBE(fail4);
369 	efx_nic_fini(sp->s_enp);
370 
371 fail3:
372 	DTRACE_PROBE(fail3);
373 	(void) efx_nic_reset(sp->s_enp);
374 
375 fail2:
376 	DTRACE_PROBE(fail2);
377 
378 	ASSERT3U(sp->s_state, ==, SFXGE_STARTING);
379 	sp->s_state = SFXGE_REGISTERED;
380 
381 fail1:
382 	DTRACE_PROBE1(fail1, int, rc);
383 
384 	return (rc);
385 }
386 
387 
388 int
sfxge_start(sfxge_t * sp,boolean_t restart)389 sfxge_start(sfxge_t *sp, boolean_t restart)
390 {
391 	int rc;
392 
393 	mutex_enter(&(sp->s_state_lock));
394 	rc = sfxge_start_locked(sp, restart);
395 	mutex_exit(&(sp->s_state_lock));
396 	return (rc);
397 }
398 
399 
400 static void
sfxge_stop_locked(sfxge_t * sp)401 sfxge_stop_locked(sfxge_t *sp)
402 {
403 	ASSERT(mutex_owned(&(sp->s_state_lock)));
404 
405 	if (sp->s_state != SFXGE_STARTED) {
406 		return;
407 	}
408 	sp->s_state = SFXGE_STOPPING;
409 
410 	sfxge_mon_stop(sp);
411 	sfxge_tx_stop(sp);
412 	sfxge_rx_stop(sp);
413 	sfxge_mac_stop(sp);
414 
415 	/* Stop event processing - must be after rx_stop see sfxge_rx_qpoll() */
416 	sfxge_ev_stop(sp);
417 	sfxge_intr_stop(sp); /* cope with late flush/soft events until here */
418 	sfxge_sram_stop(sp);
419 
420 	efx_filter_fini(sp->s_enp);
421 
422 	efx_nic_fini(sp->s_enp);
423 	(void) efx_nic_reset(sp->s_enp);
424 
425 	ASSERT3U(sp->s_state, ==, SFXGE_STOPPING);
426 	sp->s_state = SFXGE_REGISTERED;
427 }
428 
429 void
sfxge_stop(sfxge_t * sp)430 sfxge_stop(sfxge_t *sp)
431 {
432 	mutex_enter(&(sp->s_state_lock));
433 	sfxge_stop_locked(sp);
434 	mutex_exit(&(sp->s_state_lock));
435 }
436 
437 static void
_sfxge_restart(void * arg)438 _sfxge_restart(void *arg)
439 {
440 	sfxge_t *sp = arg;
441 	int rc;
442 
443 	/* logging on entry is in sfxge_restart_dispatch */
444 	mutex_enter(&(sp->s_state_lock));
445 
446 	DTRACE_PROBE(_sfxge_restart);
447 	if (sp->s_state != SFXGE_STARTED)
448 		goto done;
449 
450 	/* inform the OS that the link is down - may trigger IPMP failover */
451 	if (sp->s_hw_err && sp->s_action_on_hw_err != SFXGE_INVISIBLE) {
452 		sp->s_mac.sm_link_mode = EFX_LINK_DOWN;
453 		sfxge_gld_link_update(sp);
454 	}
455 
456 	/* Stop processing */
457 	sfxge_stop_locked(sp);
458 
459 	if (sp->s_hw_err && sp->s_action_on_hw_err == SFXGE_LEAVE_DEAD) {
460 		dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
461 		    "NIC error - interface is"
462 		    " being left permanently DOWN per driver config");
463 
464 		(void) atomic_swap_32(&(sp->s_nested_restarts), 0);
465 		mutex_exit(&(sp->s_state_lock));
466 		return;
467 	} else
468 		sp->s_hw_err = SFXGE_HW_OK;
469 
470 	/* Start processing */
471 	if ((rc = sfxge_start_locked(sp, B_TRUE)) != 0)
472 		goto fail1;
473 
474 done:
475 	(void) atomic_swap_32(&(sp->s_nested_restarts), 0);
476 	mutex_exit(&(sp->s_state_lock));
477 	dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR "NIC restart complete");
478 	return;
479 
480 fail1:
481 	DTRACE_PROBE1(fail1, int, rc);
482 	dev_err(sp->s_dip, CE_WARN,
483 	    SFXGE_CMN_ERR "FATAL ERROR: NIC restart failed rc=%d", rc);
484 
485 	(void) atomic_swap_32(&(sp->s_nested_restarts), 0);
486 	mutex_exit(&(sp->s_state_lock));
487 }
488 
489 int
sfxge_restart_dispatch(sfxge_t * sp,uint_t cflags,sfxge_hw_err_t hw_err,const char * reason,uint32_t errval)490 sfxge_restart_dispatch(sfxge_t *sp, uint_t cflags, sfxge_hw_err_t hw_err,
491     const char *reason, uint32_t errval)
492 {
493 	if (hw_err == SFXGE_HW_OK)
494 		sp->s_num_restarts++;
495 	else {
496 		sp->s_hw_err = hw_err;
497 		sp->s_num_restarts_hw_err++;
498 	}
499 
500 	if (atomic_inc_32_nv(&(sp->s_nested_restarts)) > 1) {
501 		/* A restart is currently in progress */
502 		return (0);
503 	}
504 
505 	DTRACE_PROBE2(sfxge_restart_dispatch, sfxge_hw_err_t, hw_err, char *,
506 	    reason);
507 
508 	dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR "NIC restart due to %s:%d",
509 	    reason, errval);
510 
511 	/* If cflags == DDI_SLEEP then guaranteed to succeed */
512 	return (ddi_taskq_dispatch(sp->s_tqp, _sfxge_restart, sp, cflags));
513 }
514 
515 
516 static int
sfxge_can_destroy(sfxge_t * sp)517 sfxge_can_destroy(sfxge_t *sp)
518 {
519 	int index;
520 
521 	/*
522 	 * In SFC bug 19834 it was noted that a mblk passed up to STREAMS
523 	 * could be reused for transmit and sit in the sfxge_tx_packet_cache.
524 	 * This call to empty the TX deferred packet list may result in
525 	 * rx_loaned reducing.
526 	 */
527 	index = EFX_ARRAY_SIZE(sp->s_stp);
528 	while (--index >= 0) {
529 		sfxge_txq_t *stp = sp->s_stp[index];
530 
531 		if (stp != NULL)
532 			sfxge_tx_qdpl_flush(stp);
533 	}
534 
535 	/* Need to wait for desballoc free_func callback */
536 	return (sfxge_rx_loaned(sp));
537 }
538 
539 
540 static int
sfxge_destroy(sfxge_t * sp)541 sfxge_destroy(sfxge_t *sp)
542 {
543 	ddi_taskq_t *tqp;
544 	efx_nic_t *enp;
545 	int rc;
546 
547 	ASSERT3U(sp->s_state, ==, SFXGE_INITIALIZED);
548 	enp = sp->s_enp;
549 
550 	if (sfxge_can_destroy(sp) != 0) {
551 		rc = EBUSY;
552 		goto fail1;
553 	}
554 
555 	sp->s_state = SFXGE_UNINITIALIZED;
556 
557 	cv_destroy(&(sp->s_tx_flush_kv));
558 	mutex_destroy(&(sp->s_tx_flush_lock));
559 
560 	sfxge_mon_fini(sp);
561 	sfxge_tx_fini(sp);
562 	sfxge_rx_fini(sp);
563 	sfxge_mac_fini(sp);
564 	sfxge_ev_fini(sp);
565 	sfxge_intr_fini(sp);
566 	sfxge_sram_fini(sp);
567 	(void) efx_nic_reset(enp);
568 
569 	efx_vpd_fini(enp);
570 	efx_nvram_fini(enp);
571 	efx_nic_unprobe(enp);
572 	sfxge_mcdi_fini(sp);
573 
574 	/* Destroy the NIC object */
575 	sp->s_enp = NULL;
576 	efx_nic_destroy(enp);
577 
578 	mutex_destroy(&(sp->s_nic_lock));
579 
580 	/* Unmap the device registers */
581 	sfxge_bar_fini(sp);
582 
583 	/* Tear down PCI configuration space */
584 	sfxge_pci_fini(sp);
585 
586 	/* Destroy the taskq */
587 	tqp = sp->s_tqp;
588 	sp->s_tqp = NULL;
589 	ddi_taskq_destroy(tqp);
590 
591 	mutex_destroy(&(sp->s_state_lock));
592 
593 	/* Clear property values */
594 	sp->s_mtu = 0;
595 
596 	/* Free the soft state */
597 	sp->s_dip = NULL;
598 
599 	SFXGE_OBJ_CHECK(sp, sfxge_t);
600 	kmem_free(sp, sizeof (*sp));
601 
602 	return (0);
603 
604 fail1:
605 	DTRACE_PROBE1(fail1, int, rc);
606 
607 	return (rc);
608 }
609 
610 void
sfxge_ioctl(sfxge_t * sp,queue_t * wq,mblk_t * mp)611 sfxge_ioctl(sfxge_t *sp, queue_t *wq, mblk_t *mp)
612 {
613 	struct iocblk *iocp;
614 	int rc, taskq_wait = 0;
615 	size_t ioclen = 0;
616 
617 	/*
618 	 * single concurrent IOCTL
619 	 * serialized from sfxge_create, _destroy, _(re)start, _stop
620 	 */
621 	mutex_enter(&(sp->s_state_lock));
622 
623 	/*LINTED*/
624 	iocp = (struct iocblk *)mp->b_rptr;
625 
626 	switch (iocp->ioc_cmd) {
627 	case SFXGE_NVRAM_IOC:
628 		ioclen = sizeof (sfxge_nvram_ioc_t);
629 		break;
630 	case SFXGE_MCDI_IOC:
631 		ioclen = sizeof (sfxge_mcdi_ioc_t);
632 		break;
633 	case SFXGE_MCDI2_IOC:
634 		ioclen = sizeof (sfxge_mcdi2_ioc_t);
635 		break;
636 	case SFXGE_VPD_IOC:
637 		ioclen = sizeof (sfxge_vpd_ioc_t);
638 		break;
639 	case SFXGE_NIC_RESET_IOC:
640 		break;
641 	default:
642 		rc = ENOTSUP;
643 		goto fail1;
644 	}
645 
646 	if (iocp->ioc_count != ioclen) {
647 		rc = EINVAL;
648 		goto fail2;
649 	}
650 
651 	/* if in multiple fragments pull it up to one linear buffer */
652 	if ((rc = miocpullup(mp, ioclen)) != 0) {
653 		goto fail3;
654 	}
655 
656 	switch (iocp->ioc_cmd) {
657 	case SFXGE_NVRAM_IOC: {
658 		sfxge_nvram_ioc_t *snip =
659 		    (sfxge_nvram_ioc_t *)mp->b_cont->b_rptr;
660 
661 		if ((rc = sfxge_nvram_ioctl(sp, snip)) != 0)
662 			goto fail4;
663 
664 		break;
665 	}
666 	case SFXGE_MCDI_IOC: {
667 		sfxge_mcdi_ioc_t *smip = (sfxge_mcdi_ioc_t *)mp->b_cont->b_rptr;
668 
669 		if ((rc = sfxge_mcdi_ioctl(sp, smip)) != 0)
670 			goto fail4;
671 		taskq_wait = 1;
672 
673 		break;
674 	}
675 	case SFXGE_MCDI2_IOC: {
676 		sfxge_mcdi2_ioc_t *smip =
677 		    (sfxge_mcdi2_ioc_t *)mp->b_cont->b_rptr;
678 
679 		if ((rc = sfxge_mcdi2_ioctl(sp, smip)) != 0)
680 			goto fail4;
681 		taskq_wait = 1;
682 
683 		break;
684 	}
685 	case SFXGE_NIC_RESET_IOC: {
686 		DTRACE_PROBE(nic_reset_ioc);
687 
688 		/* sp->s_state_lock held */
689 		(void) sfxge_restart_dispatch(sp, DDI_SLEEP, SFXGE_HW_OK,
690 		    "NIC_RESET_IOC", 0);
691 		taskq_wait = 1;
692 
693 		break;
694 	}
695 	case SFXGE_VPD_IOC: {
696 		sfxge_vpd_ioc_t *svip = (sfxge_vpd_ioc_t *)mp->b_cont->b_rptr;
697 
698 		if ((rc = sfxge_vpd_ioctl(sp, svip)) != 0)
699 			goto fail4;
700 
701 		break;
702 	}
703 	default:
704 		ASSERT(0);
705 	}
706 
707 	mutex_exit(&(sp->s_state_lock));
708 
709 	if (taskq_wait) {
710 		/*
711 		 * Wait for any tasks that may be accessing GLD functions
712 		 * This may end up waiting for multiple nic_resets
713 		 * as it needs to be outside of s_state_lock for sfxge_restart()
714 		 */
715 		ddi_taskq_wait(sp->s_tqp);
716 	}
717 
718 	/* The entire structure is the acknowledgement */
719 	miocack(wq, mp, iocp->ioc_count, 0);
720 
721 	return;
722 
723 fail4:
724 	DTRACE_PROBE(fail4);
725 fail3:
726 	DTRACE_PROBE(fail3);
727 fail2:
728 	DTRACE_PROBE(fail2);
729 fail1:
730 	DTRACE_PROBE1(fail1, int, rc);
731 
732 	mutex_exit(&(sp->s_state_lock));
733 
734 	/* no data returned */
735 	miocnak(wq, mp, 0, rc);
736 }
737 
738 static int
sfxge_register(sfxge_t * sp)739 sfxge_register(sfxge_t *sp)
740 {
741 	int rc;
742 
743 	ASSERT3U(sp->s_state, ==, SFXGE_INITIALIZED);
744 
745 	if ((rc = sfxge_gld_register(sp)) != 0)
746 		goto fail1;
747 
748 	sp->s_state = SFXGE_REGISTERED;
749 
750 	return (0);
751 
752 fail1:
753 	DTRACE_PROBE1(fail1, int, rc);
754 
755 	return (rc);
756 }
757 
758 static int
sfxge_unregister(sfxge_t * sp)759 sfxge_unregister(sfxge_t *sp)
760 {
761 	int rc;
762 
763 	ASSERT3U(sp->s_state, ==, SFXGE_REGISTERED);
764 
765 	/* Wait for any tasks that may be accessing GLD functions */
766 	ddi_taskq_wait(sp->s_tqp);
767 
768 	if ((rc = sfxge_gld_unregister(sp)) != 0)
769 		goto fail1;
770 
771 	sp->s_state = SFXGE_INITIALIZED;
772 
773 	return (0);
774 
775 fail1:
776 	DTRACE_PROBE1(fail1, int, rc);
777 
778 	return (rc);
779 }
780 
781 static void
_sfxge_vpd_kstat_init(sfxge_t * sp,caddr_t vpd,size_t size,efx_vpd_tag_t tag,const char * keyword,sfxge_vpd_type_t type)782 _sfxge_vpd_kstat_init(sfxge_t *sp, caddr_t vpd, size_t size, efx_vpd_tag_t tag,
783     const char *keyword, sfxge_vpd_type_t type)
784 {
785 	static const char unknown[] = "?";
786 	efx_nic_t *enp = sp->s_enp;
787 	sfxge_vpd_kstat_t *svkp = &(sp->s_vpd_kstat);
788 	kstat_named_t *knp;
789 	efx_vpd_value_t *evvp;
790 
791 	evvp = svkp->svk_vv + type;
792 	evvp->evv_tag = tag;
793 	evvp->evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]);
794 
795 	if (efx_vpd_get(enp, vpd, size, evvp) != 0) {
796 		evvp->evv_length = strlen(unknown) + 1;
797 		bcopy(unknown, evvp->evv_value, evvp->evv_length);
798 	}
799 
800 	knp = &(svkp->svk_stat[type]);
801 
802 	kstat_named_init(knp, (char *)keyword, KSTAT_DATA_STRING);
803 	kstat_named_setstr(knp, (char *)evvp->evv_value);
804 	svkp->svk_ksp->ks_data_size += sizeof (*evvp);
805 }
806 
807 static int
sfxge_vpd_kstat_init(sfxge_t * sp)808 sfxge_vpd_kstat_init(sfxge_t *sp)
809 {
810 	efx_nic_t *enp = sp->s_enp;
811 	sfxge_vpd_kstat_t *svkp = &(sp->s_vpd_kstat);
812 	dev_info_t *dip = sp->s_dip;
813 	char name[MAXNAMELEN];
814 	kstat_t *ksp;
815 	caddr_t vpd;
816 	size_t size;
817 	int rc;
818 
819 	SFXGE_OBJ_CHECK(svkp, sfxge_vpd_kstat_t);
820 	(void) snprintf(name, MAXNAMELEN - 1, "%s_vpd", ddi_driver_name(dip));
821 
822 	/* Get a copy of the VPD space */
823 	if ((rc = efx_vpd_size(enp, &size)) != 0)
824 		goto fail1;
825 
826 	if ((vpd = kmem_zalloc(size, KM_NOSLEEP)) == NULL) {
827 		rc = ENOMEM;
828 		goto fail2;
829 	}
830 
831 	if ((svkp->svk_vv = kmem_zalloc(sizeof (efx_vpd_value_t) *
832 	    SFXGE_VPD_MAX, KM_NOSLEEP)) == NULL) {
833 		rc = ENOMEM;
834 		goto fail3;
835 	}
836 
837 	if ((rc = efx_vpd_read(enp, vpd, size)) != 0)
838 		goto fail4;
839 
840 	if ((ksp = kstat_create((char *)ddi_driver_name(dip),
841 	    ddi_get_instance(dip), name, "vpd", KSTAT_TYPE_NAMED, SFXGE_VPD_MAX,
842 	    KSTAT_FLAG_VIRTUAL)) == NULL) {
843 		rc = ENOMEM;
844 		goto fail5;
845 	}
846 	svkp->svk_ksp = ksp;
847 	ksp->ks_data = &(svkp->svk_stat);
848 
849 	_sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_ID, "ID", SFXGE_VPD_ID);
850 	_sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "PN", SFXGE_VPD_PN);
851 	_sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "SN", SFXGE_VPD_SN);
852 	_sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "EC", SFXGE_VPD_EC);
853 	_sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "MN", SFXGE_VPD_MN);
854 	_sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "VD", SFXGE_VPD_VD);
855 	_sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "VE", SFXGE_VPD_VE);
856 
857 	kstat_install(ksp);
858 	kmem_free(vpd, size);
859 
860 	return (0);
861 
862 fail5:
863 	DTRACE_PROBE(fail5);
864 fail4:
865 	DTRACE_PROBE(fail4);
866 	kmem_free(svkp->svk_vv, sizeof (efx_vpd_value_t) * SFXGE_VPD_MAX);
867 fail3:
868 	DTRACE_PROBE(fail3);
869 	kmem_free(vpd, size);
870 fail2:
871 	DTRACE_PROBE(fail2);
872 fail1:
873 	DTRACE_PROBE1(fail1, int, rc);
874 	SFXGE_OBJ_CHECK(svkp, sfxge_vpd_kstat_t);
875 
876 	return (rc);
877 }
878 
879 static void
sfxge_vpd_kstat_fini(sfxge_t * sp)880 sfxge_vpd_kstat_fini(sfxge_t *sp)
881 {
882 	sfxge_vpd_kstat_t *svkp = &(sp->s_vpd_kstat);
883 
884 	/* NOTE: VPD support is optional, so kstats might not be registered */
885 	if (svkp->svk_ksp != NULL) {
886 
887 		kstat_delete(svkp->svk_ksp);
888 
889 		kmem_free(svkp->svk_vv,
890 		    sizeof (efx_vpd_value_t) * SFXGE_VPD_MAX);
891 
892 		bzero(svkp->svk_stat,
893 		    sizeof (kstat_named_t) * SFXGE_VPD_MAX);
894 
895 		svkp->svk_ksp = NULL;
896 	}
897 
898 	SFXGE_OBJ_CHECK(svkp, sfxge_vpd_kstat_t);
899 }
900 
901 static int
sfxge_cfg_kstat_init(sfxge_t * sp)902 sfxge_cfg_kstat_init(sfxge_t *sp)
903 {
904 	dev_info_t *dip = sp->s_dip;
905 	char name[MAXNAMELEN];
906 	kstat_t *ksp;
907 	sfxge_cfg_kstat_t *sckp;
908 	int rc;
909 
910 	sfxge_cfg_build(sp);
911 
912 	/* Create the set */
913 	(void) snprintf(name, MAXNAMELEN - 1, "%s_cfg", ddi_driver_name(dip));
914 
915 	if ((ksp = kstat_create((char *)ddi_driver_name(dip),
916 	    ddi_get_instance(dip), name, "cfg", KSTAT_TYPE_NAMED,
917 	    sizeof (sckp->kstat) / sizeof (kstat_named_t),
918 	    KSTAT_FLAG_VIRTUAL)) == NULL) {
919 		rc = ENOMEM;
920 		goto fail1;
921 	}
922 
923 	sp->s_cfg_ksp = ksp;
924 
925 	ksp->ks_data = sckp = &(sp->s_cfg_kstat);
926 
927 	kstat_named_init(&(sckp->kstat.sck_mac), "mac", KSTAT_DATA_STRING);
928 	kstat_named_setstr(&(sckp->kstat.sck_mac), sckp->buf.sck_mac);
929 	ksp->ks_data_size += sizeof (sckp->buf.sck_mac);
930 
931 	kstat_named_init(&(sckp->kstat.sck_version), "version",
932 	    KSTAT_DATA_STRING);
933 	kstat_named_setstr(&(sckp->kstat.sck_version), sfxge_version);
934 	ksp->ks_data_size += sizeof (sfxge_version);
935 
936 	kstat_install(ksp);
937 	return (0);
938 
939 fail1:
940 	DTRACE_PROBE1(fail1, int, rc);
941 
942 	return (rc);
943 }
944 
945 static void
sfxge_cfg_kstat_fini(sfxge_t * sp)946 sfxge_cfg_kstat_fini(sfxge_t *sp)
947 {
948 	if (sp->s_cfg_ksp == NULL)
949 		return;
950 
951 	kstat_delete(sp->s_cfg_ksp);
952 	sp->s_cfg_ksp = NULL;
953 
954 	bzero(&(sp->s_cfg_kstat), sizeof (sfxge_cfg_kstat_t));
955 }
956 
957 static int
sfxge_resume(sfxge_t * sp)958 sfxge_resume(sfxge_t *sp)
959 {
960 	int rc;
961 
962 	/* Start processing */
963 	if ((rc = sfxge_start(sp, B_FALSE)) != 0)
964 		goto fail1;
965 
966 	return (DDI_SUCCESS);
967 
968 fail1:
969 	DTRACE_PROBE1(fail1, int, rc);
970 
971 	return (DDI_FAILURE);
972 }
973 
974 static int
sfxge_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)975 sfxge_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
976 {
977 	sfxge_t *sp;
978 	int rc;
979 
980 	switch (cmd) {
981 	case DDI_ATTACH:
982 		break;
983 
984 	case DDI_RESUME:
985 		if ((sp = ddi_get_driver_private(dip)) == NULL)
986 			return (DDI_FAILURE);
987 		return (sfxge_resume(sp));
988 
989 	default:
990 		return (DDI_FAILURE);
991 	}
992 
993 	/* Create the soft state */
994 	if ((rc = sfxge_create(dip, &sp)) != 0)
995 		goto fail1;
996 
997 	/* Create the configuration kstats */
998 	if ((rc = sfxge_cfg_kstat_init(sp)) != 0)
999 		goto fail2;
1000 
1001 	/* Create the VPD kstats */
1002 	if ((rc = sfxge_vpd_kstat_init(sp)) != 0) {
1003 		if (rc != ENOTSUP)
1004 			goto fail3;
1005 	}
1006 
1007 	/* Register the interface */
1008 	if ((rc = sfxge_register(sp)) != 0)
1009 		goto fail4;
1010 
1011 	/* Announce ourselves in the system log */
1012 	ddi_report_dev(dip);
1013 
1014 	return (DDI_SUCCESS);
1015 
1016 fail4:
1017 	DTRACE_PROBE(fail4);
1018 
1019 	/* Destroy the VPD kstats */
1020 	sfxge_vpd_kstat_fini(sp);
1021 
1022 fail3:
1023 	DTRACE_PROBE(fail3);
1024 
1025 	/* Destroy the configuration kstats */
1026 	sfxge_cfg_kstat_fini(sp);
1027 
1028 fail2:
1029 	DTRACE_PROBE(fail2);
1030 
1031 	/* Destroy the soft state */
1032 	(void) sfxge_destroy(sp);
1033 
1034 fail1:
1035 	DTRACE_PROBE1(fail1, int, rc);
1036 
1037 	return (DDI_FAILURE);
1038 }
1039 
1040 static int
sfxge_suspend(sfxge_t * sp)1041 sfxge_suspend(sfxge_t *sp)
1042 {
1043 	/* Stop processing */
1044 	sfxge_stop(sp);
1045 
1046 	return (DDI_SUCCESS);
1047 }
1048 
1049 static int
sfxge_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1050 sfxge_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1051 {
1052 	sfxge_t *sp = ddi_get_driver_private(dip);
1053 	int rc;
1054 
1055 	switch (cmd) {
1056 	case DDI_DETACH:
1057 		if (sp == NULL)
1058 			return (DDI_FAILURE);
1059 		break;
1060 
1061 	case DDI_SUSPEND:
1062 		if (sp == NULL)
1063 			return (DDI_FAILURE);
1064 		return (sfxge_suspend(sp));
1065 
1066 	default:
1067 		return (DDI_FAILURE);
1068 	}
1069 
1070 	ASSERT(sp != NULL);
1071 
1072 	/* Wait for any pending restarts to complete */
1073 	ddi_taskq_wait(sp->s_tqp);
1074 
1075 	/*
1076 	 * IOCTLs from utilites can cause GLD mc_start() (SFXGE_STARTED state)
1077 	 * And mc_stop() may not occur until detach time and race. SFC bug 19855
1078 	 * Holding the lock seems to be enough - the log message is not seen
1079 	 */
1080 	mutex_enter(&(sp->s_state_lock));
1081 	if (sp->s_state == SFXGE_STARTED) {
1082 		dev_err(dip, CE_WARN, SFXGE_CMN_ERR
1083 		    "STREAMS detach when STARTED");
1084 		sfxge_stop_locked(sp);
1085 		ASSERT3U(sp->s_state, ==, SFXGE_REGISTERED);
1086 	}
1087 	mutex_exit(&(sp->s_state_lock));
1088 
1089 	ASSERT(sp->s_state == SFXGE_REGISTERED ||
1090 	    sp->s_state == SFXGE_INITIALIZED);
1091 
1092 	if (sp->s_state != SFXGE_REGISTERED)
1093 		goto destroy;
1094 
1095 	/* Unregister the interface */
1096 	if ((rc = sfxge_unregister(sp)) != 0)
1097 		goto fail1;
1098 
1099 destroy:
1100 	/* Destroy the VPD kstats */
1101 	sfxge_vpd_kstat_fini(sp);
1102 
1103 	/* Destroy the configuration kstats */
1104 	sfxge_cfg_kstat_fini(sp);
1105 
1106 	/*
1107 	 * Destroy the soft state - this might fail until rx_loaned packets that
1108 	 * have been passed up the STREAMS stack are returned
1109 	 */
1110 	if ((rc = sfxge_destroy(sp)) != 0)
1111 		goto fail2;
1112 
1113 	return (DDI_SUCCESS);
1114 
1115 fail2:
1116 	DTRACE_PROBE(fail2);
1117 fail1:
1118 	DTRACE_PROBE1(fail1, int, rc);
1119 
1120 	return (DDI_FAILURE);
1121 }
1122 
1123 /*
1124  * modlinkage
1125  */
1126 
1127 DDI_DEFINE_STREAM_OPS(sfxge_dev_ops, nulldev, nulldev, sfxge_attach,
1128     sfxge_detach, nulldev, NULL, D_MP, NULL, NULL);
1129 
1130 static struct modldrv		sfxge_modldrv = {
1131 	&mod_driverops,
1132 	(char *)sfxge_ident,
1133 	&sfxge_dev_ops,
1134 };
1135 
1136 static struct modlinkage	sfxge_modlinkage = {
1137 	MODREV_1,
1138 	{ &sfxge_modldrv, NULL }
1139 };
1140 
1141 kmutex_t	sfxge_global_lock;
1142 unsigned int	*sfxge_cpu;
1143 
1144 int
_init(void)1145 _init(void)
1146 {
1147 	int rc;
1148 
1149 	mutex_init(&sfxge_global_lock, NULL, MUTEX_DRIVER, NULL);
1150 
1151 	/* Create tables for CPU, core, cache and chip counts */
1152 	sfxge_cpu = kmem_zalloc(sizeof (unsigned int) * NCPU, KM_SLEEP);
1153 
1154 	mac_init_ops(&sfxge_dev_ops, SFXGE_DRIVER_NAME);
1155 
1156 	if ((rc = mod_install(&sfxge_modlinkage)) != 0)
1157 		goto fail1;
1158 
1159 	return (0);
1160 
1161 fail1:
1162 	DTRACE_PROBE(fail2);
1163 
1164 	mac_fini_ops(&sfxge_dev_ops);
1165 
1166 	kmem_free(sfxge_cpu, sizeof (unsigned int) * NCPU);
1167 	mutex_destroy(&sfxge_global_lock);
1168 
1169 	return (rc);
1170 }
1171 
1172 int
_fini(void)1173 _fini(void)
1174 {
1175 	int rc;
1176 
1177 	if ((rc = mod_remove(&sfxge_modlinkage)) != 0)
1178 		return (rc);
1179 
1180 	mac_fini_ops(&sfxge_dev_ops);
1181 
1182 	/* Destroy tables */
1183 	kmem_free(sfxge_cpu, sizeof (unsigned int) * NCPU);
1184 
1185 	mutex_destroy(&sfxge_global_lock);
1186 
1187 	return (0);
1188 }
1189 
1190 int
_info(struct modinfo * mip)1191 _info(struct modinfo *mip)
1192 {
1193 	return (mod_info(&sfxge_modlinkage, mip));
1194 }
1195