2 * Copyright (c) 2008-2016 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
31 #include <sys/types.h>
33 #include <sys/sunddi.h>
34 #include <sys/modctl.h>
36 #include <sys/ethernet.h>
38 #include <sys/stream.h>
39 #include <sys/strsun.h>
40 #include <sys/processor.h>
41 #include <sys/cpuvar.h>
45 #include "sfxge_version.h"
50 boolean_t sfxge_aask
= B_FALSE
;
53 /* Receive queue TRIM default polling interval (in microseconds) */
54 #define SFXGE_RX_QPOLL_USEC (5000000)
56 /* Broadcast address */
57 uint8_t sfxge_brdcst
[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
60 * By default modinfo will display lines truncated to 80 characters and so just
61 * show 32 characters of our sfxge_ident string.
63 const char sfxge_ident
[] = "Solarflare 10Gb/40Gb Ethernet";
64 const char sfxge_version
[] = SFXGE_VERSION_STRING
;
67 sfxge_cfg_build(sfxge_t
*sp
)
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]);
78 sfxge_create(dev_info_t
*dip
, sfxge_t
**spp
)
82 unsigned int rxq_size
;
86 /* Allocate the object */
87 sp
= kmem_zalloc(sizeof (*sp
), KM_SLEEP
);
89 ddi_set_driver_private(dip
, sp
);
91 mutex_init(&(sp
->s_state_lock
), NULL
, MUTEX_DRIVER
, NULL
);
92 sp
->s_state
= SFXGE_UNINITIALIZED
;
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
);
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
);
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
);
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
;
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);
121 sp
->s_tqp
= ddi_taskq_create(dip
, "tq", 1, TASKQ_DEFAULTPRI
, 0);
122 if (sp
->s_tqp
== NULL
) {
127 /* Check and initialize PCI configuration space */
128 if ((rc
= sfxge_pci_init(sp
)) != 0)
131 /* Map the device registers */
132 if ((rc
= sfxge_bar_init(sp
)) != 0)
135 /* Create the NIC object */
136 mutex_init(&(sp
->s_nic_lock
), NULL
, MUTEX_DRIVER
, NULL
);
138 if ((rc
= efx_nic_create(sp
->s_family
, (efsys_identifier_t
*)sp
,
139 &(sp
->s_bar
), &(sp
->s_nic_lock
), &enp
)) != 0)
144 /* Initialize MCDI to talk to the Microcontroller */
145 if ((rc
= sfxge_mcdi_init(sp
)) != 0)
148 /* Probe the NIC and build the configuration data area */
149 if ((rc
= efx_nic_probe(enp
)) != 0)
152 switch (sp
->s_family
) {
153 case EFX_FAMILY_HUNTINGTON
:
154 sfxge_pcie_check_link(sp
, 8, 3); /* PCI 8x Gen3 */
157 case EFX_FAMILY_SIENA
:
158 sfxge_pcie_check_link(sp
, 8, 2); /* PCI 8x Gen2 */
165 if ((rc
= efx_nvram_init(enp
)) != 0)
168 if ((rc
= efx_vpd_init(enp
)) != 0)
171 if ((rc
= efx_nic_reset(enp
)) != 0)
176 if ((rc
= sfxge_intr_init(sp
)) != 0)
179 if ((rc
= sfxge_ev_init(sp
)) != 0)
182 if ((rc
= sfxge_mac_init(sp
)) != 0)
185 if ((rc
= sfxge_rx_init(sp
)) != 0)
188 if ((rc
= sfxge_tx_init(sp
)) != 0)
191 if ((rc
= sfxge_mon_init(sp
)) != 0)
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
);
198 sp
->s_state
= SFXGE_INITIALIZED
;
204 DTRACE_PROBE(fail15
);
208 DTRACE_PROBE(fail14
);
212 DTRACE_PROBE(fail14
);
216 DTRACE_PROBE(fail13
);
220 DTRACE_PROBE(fail12
);
224 DTRACE_PROBE(fail11
);
226 (void) efx_nic_reset(sp
->s_enp
);
229 DTRACE_PROBE(fail10
);
238 efx_nic_unprobe(enp
);
247 efx_nic_destroy(enp
);
251 mutex_destroy(&(sp
->s_nic_lock
));
260 ddi_taskq_destroy(sp
->s_tqp
);
266 /* Clear property values */
269 mutex_destroy(&(sp
->s_state_lock
));
271 /* Free the soft state */
274 SFXGE_OBJ_CHECK(sp
, sfxge_t
);
275 kmem_free(sp
, sizeof (*sp
));
282 sfxge_start_locked(sfxge_t
*sp
, boolean_t restart
)
286 ASSERT(mutex_owned(&(sp
->s_state_lock
)));
288 if (sp
->s_state
== SFXGE_STARTED
)
291 if (sp
->s_state
!= SFXGE_REGISTERED
) {
295 sp
->s_state
= SFXGE_STARTING
;
297 /* Start a new epoch (allow fresh MCDI requests to succeed) */
298 efx_mcdi_new_epoch(sp
->s_enp
);
300 if ((rc
= efx_nic_reset(sp
->s_enp
)) != 0)
303 if ((rc
= efx_nic_init(sp
->s_enp
)) != 0)
306 if ((rc
= efx_filter_init(sp
->s_enp
)) != 0)
309 if ((rc
= sfxge_sram_start(sp
)) != 0)
312 if ((rc
= sfxge_intr_start(sp
)) != 0)
315 if ((rc
= sfxge_ev_start(sp
)) != 0)
318 if ((rc
= sfxge_mac_start(sp
, restart
)) != 0)
321 if ((rc
= sfxge_rx_start(sp
)) != 0)
324 if ((rc
= sfxge_tx_start(sp
)) != 0)
327 if ((rc
= sfxge_mon_start(sp
)) != 0)
330 ASSERT3U(sp
->s_state
, ==, SFXGE_STARTING
);
331 sp
->s_state
= SFXGE_STARTED
;
333 /* Notify any change of MTU */
334 sfxge_gld_mtu_update(sp
);
340 DTRACE_PROBE(fail11
);
344 DTRACE_PROBE(fail10
);
365 efx_filter_fini(sp
->s_enp
);
369 efx_nic_fini(sp
->s_enp
);
373 (void) efx_nic_reset(sp
->s_enp
);
378 ASSERT3U(sp
->s_state
, ==, SFXGE_STARTING
);
379 sp
->s_state
= SFXGE_REGISTERED
;
382 DTRACE_PROBE1(fail1
, int, rc
);
389 sfxge_start(sfxge_t
*sp
, boolean_t restart
)
393 mutex_enter(&(sp
->s_state_lock
));
394 rc
= sfxge_start_locked(sp
, restart
);
395 mutex_exit(&(sp
->s_state_lock
));
401 sfxge_stop_locked(sfxge_t
*sp
)
403 ASSERT(mutex_owned(&(sp
->s_state_lock
)));
405 if (sp
->s_state
!= SFXGE_STARTED
) {
408 sp
->s_state
= SFXGE_STOPPING
;
415 /* Stop event processing - must be after rx_stop see sfxge_rx_qpoll() */
417 sfxge_intr_stop(sp
); /* cope with late flush/soft events until here */
420 efx_filter_fini(sp
->s_enp
);
422 efx_nic_fini(sp
->s_enp
);
423 (void) efx_nic_reset(sp
->s_enp
);
425 ASSERT3U(sp
->s_state
, ==, SFXGE_STOPPING
);
426 sp
->s_state
= SFXGE_REGISTERED
;
430 sfxge_stop(sfxge_t
*sp
)
432 mutex_enter(&(sp
->s_state_lock
));
433 sfxge_stop_locked(sp
);
434 mutex_exit(&(sp
->s_state_lock
));
438 _sfxge_restart(void *arg
)
443 /* logging on entry is in sfxge_restart_dispatch */
444 mutex_enter(&(sp
->s_state_lock
));
446 DTRACE_PROBE(_sfxge_restart
);
447 if (sp
->s_state
!= SFXGE_STARTED
)
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
);
456 /* Stop processing */
457 sfxge_stop_locked(sp
);
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");
464 (void) atomic_swap_32(&(sp
->s_nested_restarts
), 0);
465 mutex_exit(&(sp
->s_state_lock
));
468 sp
->s_hw_err
= SFXGE_HW_OK
;
470 /* Start processing */
471 if ((rc
= sfxge_start_locked(sp
, B_TRUE
)) != 0)
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");
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
);
485 (void) atomic_swap_32(&(sp
->s_nested_restarts
), 0);
486 mutex_exit(&(sp
->s_state_lock
));
490 sfxge_restart_dispatch(sfxge_t
*sp
, uint_t cflags
, sfxge_hw_err_t hw_err
,
491 const char *reason
, uint32_t errval
)
493 if (hw_err
== SFXGE_HW_OK
)
494 sp
->s_num_restarts
++;
496 sp
->s_hw_err
= hw_err
;
497 sp
->s_num_restarts_hw_err
++;
500 if (atomic_inc_32_nv(&(sp
->s_nested_restarts
)) > 1) {
501 /* A restart is currently in progress */
505 DTRACE_PROBE2(sfxge_restart_dispatch
, sfxge_hw_err_t
, hw_err
, char *,
508 dev_err(sp
->s_dip
, CE_WARN
, SFXGE_CMN_ERR
"NIC restart due to %s:%d",
511 /* If cflags == DDI_SLEEP then guaranteed to succeed */
512 return (ddi_taskq_dispatch(sp
->s_tqp
, _sfxge_restart
, sp
, cflags
));
517 sfxge_can_destroy(sfxge_t
*sp
)
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.
527 index
= EFX_ARRAY_SIZE(sp
->s_stp
);
528 while (--index
>= 0) {
529 sfxge_txq_t
*stp
= sp
->s_stp
[index
];
532 sfxge_tx_qdpl_flush(stp
);
535 /* Need to wait for desballoc free_func callback */
536 return (sfxge_rx_loaned(sp
));
541 sfxge_destroy(sfxge_t
*sp
)
547 ASSERT3U(sp
->s_state
, ==, SFXGE_INITIALIZED
);
550 if (sfxge_can_destroy(sp
) != 0) {
555 sp
->s_state
= SFXGE_UNINITIALIZED
;
557 cv_destroy(&(sp
->s_tx_flush_kv
));
558 mutex_destroy(&(sp
->s_tx_flush_lock
));
567 (void) efx_nic_reset(enp
);
571 efx_nic_unprobe(enp
);
574 /* Destroy the NIC object */
576 efx_nic_destroy(enp
);
578 mutex_destroy(&(sp
->s_nic_lock
));
580 /* Unmap the device registers */
583 /* Tear down PCI configuration space */
586 /* Destroy the taskq */
589 ddi_taskq_destroy(tqp
);
591 mutex_destroy(&(sp
->s_state_lock
));
593 /* Clear property values */
596 /* Free the soft state */
599 SFXGE_OBJ_CHECK(sp
, sfxge_t
);
600 kmem_free(sp
, sizeof (*sp
));
605 DTRACE_PROBE1(fail1
, int, rc
);
611 sfxge_ioctl(sfxge_t
*sp
, queue_t
*wq
, mblk_t
*mp
)
614 int rc
, taskq_wait
= 0;
618 * single concurrent IOCTL
619 * serialized from sfxge_create, _destroy, _(re)start, _stop
621 mutex_enter(&(sp
->s_state_lock
));
624 iocp
= (struct iocblk
*)mp
->b_rptr
;
626 switch (iocp
->ioc_cmd
) {
627 case SFXGE_NVRAM_IOC
:
628 ioclen
= sizeof (sfxge_nvram_ioc_t
);
631 ioclen
= sizeof (sfxge_mcdi_ioc_t
);
633 case SFXGE_MCDI2_IOC
:
634 ioclen
= sizeof (sfxge_mcdi2_ioc_t
);
637 ioclen
= sizeof (sfxge_vpd_ioc_t
);
639 case SFXGE_NIC_RESET_IOC
:
646 if (iocp
->ioc_count
!= ioclen
) {
651 /* if in multiple fragments pull it up to one linear buffer */
652 if ((rc
= miocpullup(mp
, ioclen
)) != 0) {
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
;
661 if ((rc
= sfxge_nvram_ioctl(sp
, snip
)) != 0)
666 case SFXGE_MCDI_IOC
: {
667 sfxge_mcdi_ioc_t
*smip
= (sfxge_mcdi_ioc_t
*)mp
->b_cont
->b_rptr
;
669 if ((rc
= sfxge_mcdi_ioctl(sp
, smip
)) != 0)
675 case SFXGE_MCDI2_IOC
: {
676 sfxge_mcdi2_ioc_t
*smip
=
677 (sfxge_mcdi2_ioc_t
*)mp
->b_cont
->b_rptr
;
679 if ((rc
= sfxge_mcdi2_ioctl(sp
, smip
)) != 0)
685 case SFXGE_NIC_RESET_IOC
: {
686 DTRACE_PROBE(nic_reset_ioc
);
688 /* sp->s_state_lock held */
689 (void) sfxge_restart_dispatch(sp
, DDI_SLEEP
, SFXGE_HW_OK
,
695 case SFXGE_VPD_IOC
: {
696 sfxge_vpd_ioc_t
*svip
= (sfxge_vpd_ioc_t
*)mp
->b_cont
->b_rptr
;
698 if ((rc
= sfxge_vpd_ioctl(sp
, svip
)) != 0)
707 mutex_exit(&(sp
->s_state_lock
));
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()
715 ddi_taskq_wait(sp
->s_tqp
);
718 /* The entire structure is the acknowledgement */
719 miocack(wq
, mp
, iocp
->ioc_count
, 0);
730 DTRACE_PROBE1(fail1
, int, rc
);
732 mutex_exit(&(sp
->s_state_lock
));
734 /* no data returned */
735 miocnak(wq
, mp
, 0, rc
);
739 sfxge_register(sfxge_t
*sp
)
743 ASSERT3U(sp
->s_state
, ==, SFXGE_INITIALIZED
);
745 if ((rc
= sfxge_gld_register(sp
)) != 0)
748 sp
->s_state
= SFXGE_REGISTERED
;
753 DTRACE_PROBE1(fail1
, int, rc
);
759 sfxge_unregister(sfxge_t
*sp
)
763 ASSERT3U(sp
->s_state
, ==, SFXGE_REGISTERED
);
765 /* Wait for any tasks that may be accessing GLD functions */
766 ddi_taskq_wait(sp
->s_tqp
);
768 if ((rc
= sfxge_gld_unregister(sp
)) != 0)
771 sp
->s_state
= SFXGE_INITIALIZED
;
776 DTRACE_PROBE1(fail1
, int, rc
);
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
)
785 static const char unknown
[] = "?";
786 efx_nic_t
*enp
= sp
->s_enp
;
787 sfxge_vpd_kstat_t
*svkp
= &(sp
->s_vpd_kstat
);
789 efx_vpd_value_t
*evvp
;
791 evvp
= svkp
->svk_vv
+ type
;
793 evvp
->evv_keyword
= EFX_VPD_KEYWORD(keyword
[0], keyword
[1]);
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
);
800 knp
= &(svkp
->svk_stat
[type
]);
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
);
808 sfxge_vpd_kstat_init(sfxge_t
*sp
)
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
];
819 SFXGE_OBJ_CHECK(svkp
, sfxge_vpd_kstat_t
);
820 (void) snprintf(name
, MAXNAMELEN
- 1, "%s_vpd", ddi_driver_name(dip
));
822 /* Get a copy of the VPD space */
823 if ((rc
= efx_vpd_size(enp
, &size
)) != 0)
826 if ((vpd
= kmem_zalloc(size
, KM_NOSLEEP
)) == NULL
) {
831 if ((svkp
->svk_vv
= kmem_zalloc(sizeof (efx_vpd_value_t
) *
832 SFXGE_VPD_MAX
, KM_NOSLEEP
)) == NULL
) {
837 if ((rc
= efx_vpd_read(enp
, vpd
, size
)) != 0)
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
) {
847 ksp
->ks_data
= &(svkp
->svk_stat
);
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
);
858 kmem_free(vpd
, size
);
866 kmem_free(svkp
->svk_vv
, sizeof (efx_vpd_value_t
) * SFXGE_VPD_MAX
);
869 kmem_free(vpd
, size
);
873 DTRACE_PROBE1(fail1
, int, rc
);
874 SFXGE_OBJ_CHECK(svkp
, sfxge_vpd_kstat_t
);
880 sfxge_vpd_kstat_fini(sfxge_t
*sp
)
882 sfxge_vpd_kstat_t
*svkp
= &(sp
->s_vpd_kstat
);
884 /* NOTE: VPD support is optional, so kstats might not be registered */
885 if (svkp
->svk_ksp
!= NULL
) {
887 kstat_delete(svkp
->svk_ksp
);
889 kmem_free(svkp
->svk_vv
,
890 sizeof (efx_vpd_value_t
) * SFXGE_VPD_MAX
);
892 bzero(svkp
->svk_stat
,
893 sizeof (kstat_named_t
) * SFXGE_VPD_MAX
);
895 svkp
->svk_ksp
= NULL
;
898 SFXGE_OBJ_CHECK(svkp
, sfxge_vpd_kstat_t
);
902 sfxge_cfg_kstat_init(sfxge_t
*sp
)
904 dev_info_t
*dip
= sp
->s_dip
;
905 char name
[MAXNAMELEN
];
907 sfxge_cfg_kstat_t
*sckp
;
913 (void) snprintf(name
, MAXNAMELEN
- 1, "%s_cfg", ddi_driver_name(dip
));
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
) {
925 ksp
->ks_data
= sckp
= &(sp
->s_cfg_kstat
);
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
);
931 kstat_named_init(&(sckp
->kstat
.sck_version
), "version",
933 kstat_named_setstr(&(sckp
->kstat
.sck_version
), sfxge_version
);
934 ksp
->ks_data_size
+= sizeof (sfxge_version
);
940 DTRACE_PROBE1(fail1
, int, rc
);
946 sfxge_cfg_kstat_fini(sfxge_t
*sp
)
948 if (sp
->s_cfg_ksp
== NULL
)
951 kstat_delete(sp
->s_cfg_ksp
);
952 sp
->s_cfg_ksp
= NULL
;
954 bzero(&(sp
->s_cfg_kstat
), sizeof (sfxge_cfg_kstat_t
));
958 sfxge_resume(sfxge_t
*sp
)
962 /* Start processing */
963 if ((rc
= sfxge_start(sp
, B_FALSE
)) != 0)
966 return (DDI_SUCCESS
);
969 DTRACE_PROBE1(fail1
, int, rc
);
971 return (DDI_FAILURE
);
975 sfxge_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
985 if ((sp
= ddi_get_driver_private(dip
)) == NULL
)
986 return (DDI_FAILURE
);
987 return (sfxge_resume(sp
));
990 return (DDI_FAILURE
);
993 /* Create the soft state */
994 if ((rc
= sfxge_create(dip
, &sp
)) != 0)
997 /* Create the configuration kstats */
998 if ((rc
= sfxge_cfg_kstat_init(sp
)) != 0)
1001 /* Create the VPD kstats */
1002 if ((rc
= sfxge_vpd_kstat_init(sp
)) != 0) {
1007 /* Register the interface */
1008 if ((rc
= sfxge_register(sp
)) != 0)
1011 /* Announce ourselves in the system log */
1012 ddi_report_dev(dip
);
1014 return (DDI_SUCCESS
);
1017 DTRACE_PROBE(fail4
);
1019 /* Destroy the VPD kstats */
1020 sfxge_vpd_kstat_fini(sp
);
1023 DTRACE_PROBE(fail3
);
1025 /* Destroy the configuration kstats */
1026 sfxge_cfg_kstat_fini(sp
);
1029 DTRACE_PROBE(fail2
);
1031 /* Destroy the soft state */
1032 (void) sfxge_destroy(sp
);
1035 DTRACE_PROBE1(fail1
, int, rc
);
1037 return (DDI_FAILURE
);
1041 sfxge_suspend(sfxge_t
*sp
)
1043 /* Stop processing */
1046 return (DDI_SUCCESS
);
1050 sfxge_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
1052 sfxge_t
*sp
= ddi_get_driver_private(dip
);
1058 return (DDI_FAILURE
);
1063 return (DDI_FAILURE
);
1064 return (sfxge_suspend(sp
));
1067 return (DDI_FAILURE
);
1072 /* Wait for any pending restarts to complete */
1073 ddi_taskq_wait(sp
->s_tqp
);
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
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
);
1087 mutex_exit(&(sp
->s_state_lock
));
1089 ASSERT(sp
->s_state
== SFXGE_REGISTERED
||
1090 sp
->s_state
== SFXGE_INITIALIZED
);
1092 if (sp
->s_state
!= SFXGE_REGISTERED
)
1095 /* Unregister the interface */
1096 if ((rc
= sfxge_unregister(sp
)) != 0)
1100 /* Destroy the VPD kstats */
1101 sfxge_vpd_kstat_fini(sp
);
1103 /* Destroy the configuration kstats */
1104 sfxge_cfg_kstat_fini(sp
);
1107 * Destroy the soft state - this might fail until rx_loaned packets that
1108 * have been passed up the STREAMS stack are returned
1110 if ((rc
= sfxge_destroy(sp
)) != 0)
1113 return (DDI_SUCCESS
);
1116 DTRACE_PROBE(fail2
);
1118 DTRACE_PROBE1(fail1
, int, rc
);
1120 return (DDI_FAILURE
);
1127 DDI_DEFINE_STREAM_OPS(sfxge_dev_ops
, nulldev
, nulldev
, sfxge_attach
,
1128 sfxge_detach
, nulldev
, NULL
, D_MP
, NULL
, NULL
);
1130 static struct modldrv sfxge_modldrv
= {
1132 (char *)sfxge_ident
,
1136 static struct modlinkage sfxge_modlinkage
= {
1138 { &sfxge_modldrv
, NULL
}
1141 kmutex_t sfxge_global_lock
;
1142 unsigned int *sfxge_cpu
;
1149 mutex_init(&sfxge_global_lock
, NULL
, MUTEX_DRIVER
, NULL
);
1151 /* Create tables for CPU, core, cache and chip counts */
1152 sfxge_cpu
= kmem_zalloc(sizeof (unsigned int) * NCPU
, KM_SLEEP
);
1154 mac_init_ops(&sfxge_dev_ops
, SFXGE_DRIVER_NAME
);
1156 if ((rc
= mod_install(&sfxge_modlinkage
)) != 0)
1162 DTRACE_PROBE(fail2
);
1164 mac_fini_ops(&sfxge_dev_ops
);
1166 kmem_free(sfxge_cpu
, sizeof (unsigned int) * NCPU
);
1167 mutex_destroy(&sfxge_global_lock
);
1177 if ((rc
= mod_remove(&sfxge_modlinkage
)) != 0)
1180 mac_fini_ops(&sfxge_dev_ops
);
1182 /* Destroy tables */
1183 kmem_free(sfxge_cpu
, sizeof (unsigned int) * NCPU
);
1185 mutex_destroy(&sfxge_global_lock
);
1191 _info(struct modinfo
*mip
)
1193 return (mod_info(&sfxge_modlinkage
, mip
));