4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Hermon (InfiniBand) HCA Driver attach/detach Routines
30 * Implements all the routines necessary for the attach, setup,
31 * initialization (and subsequent possible teardown and detach) of the
32 * Hermon InfiniBand HCA driver.
35 #include <sys/types.h>
40 #include <sys/sunddi.h>
41 #include <sys/modctl.h>
44 #include <sys/pci_cap.h>
45 #include <sys/bitmap.h>
46 #include <sys/policy.h>
48 #include <sys/ib/adapters/hermon/hermon.h>
50 /* /etc/system can tune this down, if that is desirable. */
51 int hermon_msix_max
= HERMON_MSIX_MAX
;
53 /* The following works around a problem in pre-2_7_000 firmware. */
54 #define HERMON_FW_WORKAROUND
56 int hermon_verbose
= 0;
58 /* Hermon HCA State Pointer */
63 /* Disable the internal error-check polling thread */
64 int hermon_no_inter_err_chk
= 0;
67 * The Hermon "userland resource database" is common to instances of the
68 * Hermon HCA driver. This structure "hermon_userland_rsrc_db" contains all
69 * the necessary information to maintain it.
71 hermon_umap_db_t hermon_userland_rsrc_db
;
73 static int hermon_attach(dev_info_t
*, ddi_attach_cmd_t
);
74 static int hermon_detach(dev_info_t
*, ddi_detach_cmd_t
);
75 static int hermon_open(dev_t
*, int, int, cred_t
*);
76 static int hermon_close(dev_t
, int, int, cred_t
*);
77 static int hermon_getinfo(dev_info_t
*, ddi_info_cmd_t
, void *, void **);
79 static int hermon_drv_init(hermon_state_t
*state
, dev_info_t
*dip
,
81 static void hermon_drv_fini(hermon_state_t
*state
);
82 static void hermon_drv_fini2(hermon_state_t
*state
);
83 static int hermon_isr_init(hermon_state_t
*state
);
84 static void hermon_isr_fini(hermon_state_t
*state
);
86 static int hermon_hw_init(hermon_state_t
*state
);
88 static void hermon_hw_fini(hermon_state_t
*state
,
89 hermon_drv_cleanup_level_t cleanup
);
90 static int hermon_soft_state_init(hermon_state_t
*state
);
91 static void hermon_soft_state_fini(hermon_state_t
*state
);
92 static int hermon_icm_config_setup(hermon_state_t
*state
,
93 hermon_hw_initqueryhca_t
*inithca
);
94 static void hermon_icm_tables_init(hermon_state_t
*state
);
95 static void hermon_icm_tables_fini(hermon_state_t
*state
);
96 static int hermon_icm_dma_init(hermon_state_t
*state
);
97 static void hermon_icm_dma_fini(hermon_state_t
*state
);
98 static void hermon_inithca_set(hermon_state_t
*state
,
99 hermon_hw_initqueryhca_t
*inithca
);
100 static int hermon_hca_port_init(hermon_state_t
*state
);
101 static int hermon_hca_ports_shutdown(hermon_state_t
*state
, uint_t num_init
);
102 static int hermon_internal_uarpg_init(hermon_state_t
*state
);
103 static void hermon_internal_uarpg_fini(hermon_state_t
*state
);
104 static int hermon_special_qp_contexts_reserve(hermon_state_t
*state
);
105 static void hermon_special_qp_contexts_unreserve(hermon_state_t
*state
);
106 static int hermon_sw_reset(hermon_state_t
*state
);
107 static int hermon_mcg_init(hermon_state_t
*state
);
108 static void hermon_mcg_fini(hermon_state_t
*state
);
109 static int hermon_fw_version_check(hermon_state_t
*state
);
110 static void hermon_device_info_report(hermon_state_t
*state
);
111 static int hermon_pci_capability_list(hermon_state_t
*state
,
112 ddi_acc_handle_t hdl
);
113 static void hermon_pci_capability_vpd(hermon_state_t
*state
,
114 ddi_acc_handle_t hdl
, uint_t offset
);
115 static int hermon_pci_read_vpd(ddi_acc_handle_t hdl
, uint_t offset
,
116 uint32_t addr
, uint32_t *data
);
117 static int hermon_intr_or_msi_init(hermon_state_t
*state
);
118 static int hermon_add_intrs(hermon_state_t
*state
, int intr_type
);
119 static int hermon_intr_or_msi_fini(hermon_state_t
*state
);
120 void hermon_pci_capability_msix(hermon_state_t
*state
, ddi_acc_handle_t hdl
,
123 static uint64_t hermon_size_icm(hermon_state_t
*state
);
125 /* X86 fastreboot support */
126 static ushort_t
get_msix_ctrl(dev_info_t
*);
127 static size_t get_msix_tbl_size(dev_info_t
*);
128 static size_t get_msix_pba_size(dev_info_t
*);
129 static void hermon_set_msix_info(hermon_state_t
*);
130 static int hermon_intr_disable(hermon_state_t
*);
131 static int hermon_quiesce(dev_info_t
*);
134 /* Character/Block Operations */
135 static struct cb_ops hermon_cb_ops
= {
136 hermon_open
, /* open */
137 hermon_close
, /* close */
138 nodev
, /* strategy (block) */
139 nodev
, /* print (block) */
140 nodev
, /* dump (block) */
143 hermon_ioctl
, /* ioctl */
144 hermon_devmap
, /* devmap */
147 nochpoll
, /* chpoll */
148 ddi_prop_op
, /* prop_op */
151 D_64BIT
| D_HOTPLUG
|
152 D_DEVMAP
, /* flags */
156 /* Driver Operations */
157 static struct dev_ops hermon_ops
= {
158 DEVO_REV
, /* struct rev */
160 hermon_getinfo
, /* getinfo */
161 nulldev
, /* identify */
163 hermon_attach
, /* attach */
164 hermon_detach
, /* detach */
166 &hermon_cb_ops
, /* cb_ops */
169 hermon_quiesce
, /* devo_quiesce */
172 /* Module Driver Info */
173 static struct modldrv hermon_modldrv
= {
175 "ConnectX IB Driver",
180 static struct modlinkage hermon_modlinkage
= {
187 * This extern refers to the ibc_operations_t function vector that is defined
188 * in the hermon_ci.c file.
190 extern ibc_operations_t hermon_ibc_ops
;
200 status
= ddi_soft_state_init(&hermon_statep
, sizeof (hermon_state_t
),
201 (size_t)HERMON_INITIAL_STATES
);
206 status
= ibc_init(&hermon_modlinkage
);
208 ddi_soft_state_fini(&hermon_statep
);
212 status
= mod_install(&hermon_modlinkage
);
214 ibc_fini(&hermon_modlinkage
);
215 ddi_soft_state_fini(&hermon_statep
);
219 /* Initialize the Hermon "userland resources database" */
220 hermon_umap_db_init();
230 _info(struct modinfo
*modinfop
)
234 status
= mod_info(&hermon_modlinkage
, modinfop
);
247 status
= mod_remove(&hermon_modlinkage
);
252 /* Destroy the Hermon "userland resources database" */
253 hermon_umap_db_fini();
255 ibc_fini(&hermon_modlinkage
);
256 ddi_soft_state_fini(&hermon_statep
);
267 hermon_getinfo(dev_info_t
*dip
, ddi_info_cmd_t cmd
, void *arg
, void **result
)
270 hermon_state_t
*state
;
274 case DDI_INFO_DEVT2DEVINFO
:
276 instance
= HERMON_DEV_INSTANCE(dev
);
277 state
= ddi_get_soft_state(hermon_statep
, instance
);
279 return (DDI_FAILURE
);
281 *result
= (void *)state
->hs_dip
;
282 return (DDI_SUCCESS
);
284 case DDI_INFO_DEVT2INSTANCE
:
286 instance
= HERMON_DEV_INSTANCE(dev
);
287 *result
= (void *)(uintptr_t)instance
;
288 return (DDI_SUCCESS
);
294 return (DDI_FAILURE
);
303 hermon_open(dev_t
*devp
, int flag
, int otyp
, cred_t
*credp
)
305 hermon_state_t
*state
;
306 hermon_rsrc_t
*rsrcp
;
307 hermon_umap_db_entry_t
*umapdb
, *umapdb2
;
314 instance
= HERMON_DEV_INSTANCE(*devp
);
315 state
= ddi_get_soft_state(hermon_statep
, instance
);
321 * Only allow driver to be opened for character access, and verify
322 * whether exclusive access is allowed.
324 if ((otyp
!= OTYP_CHR
) || ((flag
& FEXCL
) &&
325 secpolicy_excl_open(credp
) != 0)) {
330 * Search for the current process PID in the "userland resources
331 * database". If it is not found, then attempt to allocate a UAR
332 * page and add the ("key", "value") pair to the database.
333 * Note: As a last step we always return a devp appropriate for
334 * the open. Either we return a new minor number (based on the
335 * instance and the UAR page index) or we return the current minor
336 * number for the given client process.
338 * We also add an entry to the database to allow for lookup from
339 * "dev_t" to the current process PID. This is necessary because,
340 * under certain circumstance, the process PID that calls the Hermon
341 * close() entry point may not be the same as the one who called
342 * open(). Specifically, this can happen if a child process calls
343 * the Hermon's open() entry point, gets a UAR page, maps it out (using
344 * mmap()), and then exits without calling munmap(). Because mmap()
345 * adds a reference to the file descriptor, at the exit of the child
346 * process the file descriptor is "inherited" by the parent (and will
347 * be close()'d by the parent's PID only when it exits).
349 * Note: We use the hermon_umap_db_find_nolock() and
350 * hermon_umap_db_add_nolock() database access routines below (with
351 * an explicit mutex_enter of the database lock - "hdl_umapdb_lock")
352 * to ensure that the multiple accesses (in this case searching for,
353 * and then adding _two_ database entries) can be done atomically.
356 mutex_enter(&hermon_userland_rsrc_db
.hdl_umapdb_lock
);
357 status
= hermon_umap_db_find_nolock(instance
, key
,
358 MLNX_UMAP_UARPG_RSRC
, &value
, 0, NULL
);
359 if (status
!= DDI_SUCCESS
) {
361 * If we are in 'maintenance mode', we cannot alloc a UAR page.
362 * But we still need some rsrcp value, and a mostly unique
363 * hr_indx value. So we set rsrcp to NULL for maintenance
364 * mode, and use a rolling count for hr_indx. The field
365 * 'hs_open_hr_indx' is used only in this maintenance mode
368 * Otherwise, if we are in operational mode then we allocate
369 * the UAR page as normal, and use the rsrcp value and tr_indx
370 * value from that allocation.
372 if (!HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
374 hr_indx
= state
->hs_open_ar_indx
++;
376 /* Allocate a new UAR page for this process */
377 status
= hermon_rsrc_alloc(state
, HERMON_UARPG
, 1,
378 HERMON_NOSLEEP
, &rsrcp
);
379 if (status
!= DDI_SUCCESS
) {
381 &hermon_userland_rsrc_db
.hdl_umapdb_lock
);
385 hr_indx
= rsrcp
->hr_indx
;
389 * Allocate an entry to track the UAR page resource in the
390 * "userland resources database".
392 umapdb
= hermon_umap_db_alloc(instance
, key
,
393 MLNX_UMAP_UARPG_RSRC
, (uint64_t)(uintptr_t)rsrcp
);
394 if (umapdb
== NULL
) {
395 mutex_exit(&hermon_userland_rsrc_db
.hdl_umapdb_lock
);
396 /* If in "maintenance mode", don't free the rsrc */
397 if (HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
398 hermon_rsrc_free(state
, &rsrcp
);
404 * Create a new device number. Minor number is a function of
405 * the UAR page index (15 bits) and the device instance number
408 dev
= makedevice(getmajor(*devp
), (hr_indx
<<
409 HERMON_MINORNUM_SHIFT
) | instance
);
412 * Allocate another entry in the "userland resources database"
413 * to track the association of the device number (above) to
414 * the current process ID (in "key").
416 umapdb2
= hermon_umap_db_alloc(instance
, dev
,
417 MLNX_UMAP_PID_RSRC
, (uint64_t)key
);
418 if (umapdb2
== NULL
) {
419 mutex_exit(&hermon_userland_rsrc_db
.hdl_umapdb_lock
);
420 hermon_umap_db_free(umapdb
);
421 /* If in "maintenance mode", don't free the rsrc */
422 if (HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
423 hermon_rsrc_free(state
, &rsrcp
);
428 /* Add the entries to the database */
429 hermon_umap_db_add_nolock(umapdb
);
430 hermon_umap_db_add_nolock(umapdb2
);
434 * Return the same device number as on the original open()
435 * call. This was calculated as a function of the UAR page
436 * index (top 16 bits) and the device instance number
438 rsrcp
= (hermon_rsrc_t
*)(uintptr_t)value
;
439 dev
= makedevice(getmajor(*devp
), (rsrcp
->hr_indx
<<
440 HERMON_MINORNUM_SHIFT
) | instance
);
442 mutex_exit(&hermon_userland_rsrc_db
.hdl_umapdb_lock
);
455 hermon_close(dev_t dev
, int flag
, int otyp
, cred_t
*credp
)
457 hermon_state_t
*state
;
458 hermon_rsrc_t
*rsrcp
;
459 hermon_umap_db_entry_t
*umapdb
;
460 hermon_umap_db_priv_t
*priv
;
463 int status
, reset_status
= 0;
465 instance
= HERMON_DEV_INSTANCE(dev
);
466 state
= ddi_get_soft_state(hermon_statep
, instance
);
472 * Search for "dev_t" in the "userland resources database". As
473 * explained above in hermon_open(), we can't depend on using the
474 * current process ID here to do the lookup because the process
475 * that ultimately closes may not be the same one who opened
476 * (because of inheritance).
477 * So we lookup the "dev_t" (which points to the PID of the process
478 * that opened), and we remove the entry from the database (and free
479 * it up). Then we do another query based on the PID value. And when
480 * we find that database entry, we free it up too and then free the
481 * Hermon UAR page resource.
483 * Note: We use the hermon_umap_db_find_nolock() database access
484 * routine below (with an explicit mutex_enter of the database lock)
485 * to ensure that the multiple accesses (which attempt to remove the
486 * two database entries) can be done atomically.
488 * This works the same in both maintenance mode and HCA mode, except
489 * for the call to hermon_rsrc_free(). In the case of maintenance mode,
490 * this call is not needed, as it was not allocated in hermon_open()
494 mutex_enter(&hermon_userland_rsrc_db
.hdl_umapdb_lock
);
495 status
= hermon_umap_db_find_nolock(instance
, key
, MLNX_UMAP_PID_RSRC
,
496 &value
, HERMON_UMAP_DB_REMOVE
, &umapdb
);
497 if (status
== DDI_SUCCESS
) {
499 * If the "hdb_priv" field is non-NULL, it indicates that
500 * some "on close" handling is still necessary. Call
501 * hermon_umap_db_handle_onclose_cb() to do the handling (i.e.
502 * to invoke all the registered callbacks). Then free up
503 * the resources associated with "hdb_priv" and continue
506 priv
= (hermon_umap_db_priv_t
*)umapdb
->hdbe_common
.hdb_priv
;
508 reset_status
= hermon_umap_db_handle_onclose_cb(priv
);
509 kmem_free(priv
, sizeof (hermon_umap_db_priv_t
));
510 umapdb
->hdbe_common
.hdb_priv
= NULL
;
513 hermon_umap_db_free(umapdb
);
516 * Now do another lookup using PID as the key (copy it from
517 * "value"). When this lookup is complete, the "value" field
518 * will contain the hermon_rsrc_t pointer for the UAR page
522 status
= hermon_umap_db_find_nolock(instance
, key
,
523 MLNX_UMAP_UARPG_RSRC
, &value
, HERMON_UMAP_DB_REMOVE
,
525 if (status
== DDI_SUCCESS
) {
526 hermon_umap_db_free(umapdb
);
527 /* If in "maintenance mode", don't free the rsrc */
528 if (HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
529 rsrcp
= (hermon_rsrc_t
*)(uintptr_t)value
;
530 hermon_rsrc_free(state
, &rsrcp
);
534 mutex_exit(&hermon_userland_rsrc_db
.hdl_umapdb_lock
);
535 return (reset_status
);
541 * Context: Only called from attach() path context
544 hermon_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
546 hermon_state_t
*state
;
547 ibc_clnt_hdl_t tmp_ibtfpriv
;
548 ibc_status_t ibc_status
;
553 (void) hermon_quiesce(dip
);
558 instance
= ddi_get_instance(dip
);
559 status
= ddi_soft_state_zalloc(hermon_statep
, instance
);
560 if (status
!= DDI_SUCCESS
) {
561 cmn_err(CE_NOTE
, "hermon%d: driver failed to attach: "
562 "attach_ssz_fail", instance
);
563 goto fail_attach_nomsg
;
566 state
= ddi_get_soft_state(hermon_statep
, instance
);
568 ddi_soft_state_free(hermon_statep
, instance
);
569 cmn_err(CE_NOTE
, "hermon%d: driver failed to attach: "
570 "attach_gss_fail", instance
);
571 goto fail_attach_nomsg
;
574 /* clear the attach error buffer */
575 HERMON_ATTACH_MSG_INIT(state
->hs_attach_buf
);
577 /* Save away devinfo and instance before hermon_fm_init() */
579 state
->hs_instance
= instance
;
581 hermon_fm_init(state
);
584 * Initialize Hermon driver and hardware.
586 * Note: If this initialization fails we may still wish to
587 * create a device node and remain operational so that Hermon
588 * firmware can be updated/flashed (i.e. "maintenance mode").
589 * If this is the case, then "hs_operational_mode" will be
590 * equal to HERMON_MAINTENANCE_MODE. We will not attempt to
591 * attach to the IBTF or register with the IBMF (i.e. no
592 * InfiniBand interfaces will be enabled).
594 status
= hermon_drv_init(state
, dip
, instance
);
595 if ((status
!= DDI_SUCCESS
) &&
596 (HERMON_IS_OPERATIONAL(state
->hs_operational_mode
))) {
601 * Change the Hermon FM mode
603 if ((hermon_get_state(state
) & HCA_PIO_FM
) &&
604 HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
606 * Now we wait for 50ms to give an opportunity
607 * to Solaris FMA so that HW errors can be notified.
608 * Then check if there are HW errors or not. If
609 * a HW error is detected, the Hermon attachment
612 delay(drv_usectohz(50000));
613 if (hermon_init_failure(state
)) {
614 hermon_drv_fini(state
);
615 HERMON_WARNING(state
, "unable to "
616 "attach Hermon due to a HW error");
617 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
618 "hermon_attach_failure");
623 * There seems no HW errors during the attachment,
624 * so let's change the Hermon FM state to the
627 if (hermon_fm_ereport_init(state
) != DDI_SUCCESS
) {
628 /* unwind the resources */
629 hermon_drv_fini(state
);
630 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
631 "hermon_attach_failure");
636 /* Create the minor node for device */
637 status
= ddi_create_minor_node(dip
, "devctl", S_IFCHR
, instance
,
639 if (status
!= DDI_SUCCESS
) {
640 hermon_drv_fini(state
);
641 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
642 "attach_create_mn_fail");
647 * If we are in "maintenance mode", then we don't want to
648 * register with the IBTF. All InfiniBand interfaces are
649 * uninitialized, and the device is only capable of handling
650 * requests to update/flash firmware (or test/debug requests).
652 if (HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
653 cmn_err(CE_NOTE
, "!Hermon is operational\n");
655 /* Attach to InfiniBand Transport Framework (IBTF) */
656 ibc_status
= ibc_attach(&tmp_ibtfpriv
,
657 &state
->hs_ibtfinfo
);
658 if (ibc_status
!= IBC_SUCCESS
) {
659 cmn_err(CE_CONT
, "hermon_attach: ibc_attach "
661 ddi_remove_minor_node(dip
, "devctl");
662 hermon_drv_fini(state
);
663 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
664 "attach_ibcattach_fail");
669 * Now that we've successfully attached to the IBTF,
670 * we enable all appropriate asynch and CQ events to
671 * be forwarded to the IBTF.
673 HERMON_ENABLE_IBTF_CALLB(state
, tmp_ibtfpriv
);
675 ibc_post_attach(state
->hs_ibtfpriv
);
677 /* Register agents with IB Mgmt Framework (IBMF) */
678 status
= hermon_agent_handlers_init(state
);
679 if (status
!= DDI_SUCCESS
) {
680 (void) ibc_pre_detach(tmp_ibtfpriv
, DDI_DETACH
);
681 HERMON_QUIESCE_IBTF_CALLB(state
);
682 if (state
->hs_in_evcallb
!= 0) {
683 HERMON_WARNING(state
, "unable to "
684 "quiesce Hermon IBTF callbacks");
686 ibc_detach(tmp_ibtfpriv
);
687 ddi_remove_minor_node(dip
, "devctl");
688 hermon_drv_fini(state
);
689 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
690 "attach_agentinit_fail");
695 /* Report attach in maintenance mode, if appropriate */
696 if (!(HERMON_IS_OPERATIONAL(state
->hs_operational_mode
))) {
697 cmn_err(CE_NOTE
, "hermon%d: driver attached "
698 "(for maintenance mode only)", state
->hs_instance
);
699 hermon_fm_ereport(state
, HCA_IBA_ERR
, HCA_ERR_DEGRADED
);
702 /* Report that driver was loaded */
705 /* Send device information to log file */
706 hermon_device_info_report(state
);
709 cmn_err(CE_CONT
, "!Hermon attach complete\n");
710 return (DDI_SUCCESS
);
713 /* Add code here for DDI_RESUME XXX */
714 return (DDI_FAILURE
);
717 cmn_err(CE_WARN
, "hermon_attach: unknown cmd (0x%x)\n", cmd
);
722 cmn_err(CE_NOTE
, "hermon%d: driver failed to attach: %s", instance
,
723 state
->hs_attach_buf
);
724 if (hermon_get_state(state
) & HCA_EREPORT_FM
) {
725 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_SRV_LOST
);
727 hermon_drv_fini2(state
);
728 hermon_fm_fini(state
);
729 ddi_soft_state_free(hermon_statep
, instance
);
732 return (DDI_FAILURE
);
738 * Context: Only called from detach() path context
741 hermon_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
743 hermon_state_t
*state
;
744 ibc_clnt_hdl_t tmp_ibtfpriv
;
745 ibc_status_t ibc_status
;
746 int instance
, status
;
748 instance
= ddi_get_instance(dip
);
749 state
= ddi_get_soft_state(hermon_statep
, instance
);
751 return (DDI_FAILURE
);
757 * If we are in "maintenance mode", then we do not want to
758 * do teardown for any of the InfiniBand interfaces.
759 * Specifically, this means not detaching from IBTF (we never
760 * attached to begin with) and not deregistering from IBMF.
762 if (HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
763 /* Unregister agents from IB Mgmt Framework (IBMF) */
764 status
= hermon_agent_handlers_fini(state
);
765 if (status
!= DDI_SUCCESS
) {
766 return (DDI_FAILURE
);
770 * Attempt the "pre-detach" from InfiniBand Transport
771 * Framework (IBTF). At this point the IBTF is still
772 * capable of handling incoming asynch and completion
773 * events. This "pre-detach" is primarily a mechanism
774 * to notify the appropriate IBTF clients that the
775 * HCA is being removed/offlined.
777 ibc_status
= ibc_pre_detach(state
->hs_ibtfpriv
, cmd
);
778 if (ibc_status
!= IBC_SUCCESS
) {
779 status
= hermon_agent_handlers_init(state
);
780 if (status
!= DDI_SUCCESS
) {
781 HERMON_WARNING(state
, "failed to "
782 "restart Hermon agents");
784 return (DDI_FAILURE
);
788 * Before we can fully detach from the IBTF we need to
789 * ensure that we have handled all outstanding event
790 * callbacks. This is accomplished by quiescing the
791 * event callback mechanism. Note: if we are unable
792 * to successfully quiesce the callbacks, then this is
793 * an indication that something has probably gone
794 * seriously wrong. We print out a warning, but
797 tmp_ibtfpriv
= state
->hs_ibtfpriv
;
798 HERMON_QUIESCE_IBTF_CALLB(state
);
799 if (state
->hs_in_evcallb
!= 0) {
800 HERMON_WARNING(state
, "unable to quiesce "
801 "Hermon IBTF callbacks");
804 /* Complete the detach from the IBTF */
805 ibc_detach(tmp_ibtfpriv
);
808 /* Remove the minor node for device */
809 ddi_remove_minor_node(dip
, "devctl");
812 * Only call hermon_drv_fini() if we are in Hermon HCA mode.
813 * (Because if we are in "maintenance mode", then we never
814 * successfully finished init.) Only report successful
815 * detach for normal HCA mode.
817 if (HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
818 /* Cleanup driver resources and shutdown hardware */
819 hermon_drv_fini(state
);
820 cmn_err(CE_CONT
, "!Hermon driver successfully "
824 hermon_drv_fini2(state
);
825 hermon_fm_fini(state
);
826 ddi_soft_state_free(hermon_statep
, instance
);
828 return (DDI_SUCCESS
);
831 /* Add code here for DDI_SUSPEND XXX */
832 return (DDI_FAILURE
);
835 cmn_err(CE_WARN
, "hermon_detach: unknown cmd (0x%x)\n", cmd
);
839 return (DDI_FAILURE
);
843 * hermon_dma_attr_init()
844 * Context: Can be called from interrupt or base context.
849 hermon_dma_attr_init(hermon_state_t
*state
, ddi_dma_attr_t
*dma_attr
)
851 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*dma_attr
))
853 dma_attr
->dma_attr_version
= DMA_ATTR_V0
;
854 dma_attr
->dma_attr_addr_lo
= 0;
855 dma_attr
->dma_attr_addr_hi
= 0xFFFFFFFFFFFFFFFFull
;
856 dma_attr
->dma_attr_count_max
= 0xFFFFFFFFFFFFFFFFull
;
857 dma_attr
->dma_attr_align
= HERMON_PAGESIZE
; /* default 4K */
858 dma_attr
->dma_attr_burstsizes
= 0x3FF;
859 dma_attr
->dma_attr_minxfer
= 1;
860 dma_attr
->dma_attr_maxxfer
= 0xFFFFFFFFFFFFFFFFull
;
861 dma_attr
->dma_attr_seg
= 0xFFFFFFFFFFFFFFFFull
;
862 dma_attr
->dma_attr_sgllen
= 0x7FFFFFFF;
863 dma_attr
->dma_attr_granular
= 1;
864 dma_attr
->dma_attr_flags
= 0;
869 * Context: Can be called from base context.
872 hermon_dma_alloc(hermon_state_t
*state
, hermon_dma_info_t
*dma_info
,
875 ddi_dma_handle_t dma_hdl
;
876 ddi_dma_attr_t dma_attr
;
877 ddi_acc_handle_t acc_hdl
;
878 ddi_dma_cookie_t cookie
;
884 hermon_dma_attr_init(state
, &dma_attr
);
886 /* Allocate a DMA handle */
887 status
= ddi_dma_alloc_handle(state
->hs_dip
, &dma_attr
, DDI_DMA_SLEEP
,
889 if (status
!= DDI_SUCCESS
) {
890 IBTF_DPRINTF_L2("DMA", "alloc handle failed: %d", status
);
891 cmn_err(CE_CONT
, "DMA alloc handle failed(status %d)", status
);
892 return (DDI_FAILURE
);
895 /* Allocate DMA memory */
896 status
= ddi_dma_mem_alloc(dma_hdl
, dma_info
->length
,
897 &state
->hs_reg_accattr
, DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
, NULL
,
898 (caddr_t
*)&kaddr
, (size_t *)&real_len
, &acc_hdl
);
899 if (status
!= DDI_SUCCESS
) {
900 ddi_dma_free_handle(&dma_hdl
);
901 IBTF_DPRINTF_L2("DMA", "memory alloc failed: %d", status
);
902 cmn_err(CE_CONT
, "DMA memory alloc failed(status %d)", status
);
903 return (DDI_FAILURE
);
905 bzero((caddr_t
)(uintptr_t)kaddr
, real_len
);
907 /* Bind the memory to the handle */
908 status
= ddi_dma_addr_bind_handle(dma_hdl
, NULL
,
909 (caddr_t
)(uintptr_t)kaddr
, (size_t)real_len
, DDI_DMA_RDWR
|
910 DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
, NULL
, &cookie
, &ccount
);
911 if (status
!= DDI_SUCCESS
) {
912 ddi_dma_mem_free(&acc_hdl
);
913 ddi_dma_free_handle(&dma_hdl
);
914 IBTF_DPRINTF_L2("DMA", "bind handle failed: %d", status
);
915 cmn_err(CE_CONT
, "DMA bind handle failed(status %d)", status
);
916 return (DDI_FAILURE
);
919 /* Package the hermon_dma_info contents and return */
920 dma_info
->vaddr
= kaddr
;
921 dma_info
->dma_hdl
= dma_hdl
;
922 dma_info
->acc_hdl
= acc_hdl
;
924 /* Pass the mapping information to the firmware */
925 status
= hermon_map_cmd_post(state
, dma_info
, opcode
, cookie
, ccount
);
926 if (status
!= DDI_SUCCESS
) {
928 hermon_dma_free(dma_info
);
942 cmn_err(CE_NOTE
, "Map cmd '%s' failed, status %08x\n",
944 return (DDI_FAILURE
);
947 return (DDI_SUCCESS
);
952 * Context: Can be called from base context.
955 hermon_dma_free(hermon_dma_info_t
*info
)
957 /* Unbind the handles and free the memory */
958 (void) ddi_dma_unbind_handle(info
->dma_hdl
);
959 ddi_dma_mem_free(&info
->acc_hdl
);
960 ddi_dma_free_handle(&info
->dma_hdl
);
963 /* These macros are valid for use only in hermon_icm_alloc/hermon_icm_free. */
964 #define HERMON_ICM_ALLOC(rsrc) \
965 hermon_icm_alloc(state, rsrc, index1, index2)
966 #define HERMON_ICM_FREE(rsrc) \
967 hermon_icm_free(state, rsrc, index1, index2)
971 * Context: Can be called from base context.
973 * Only one thread can be here for a given hermon_rsrc_type_t "type".
975 * "num_to_hdl" is set if there is a need for lookups from resource
976 * number/index to resource handle. This is needed for QPs/CQs/SRQs
977 * for the various affiliated events/errors.
980 hermon_icm_alloc(hermon_state_t
*state
, hermon_rsrc_type_t type
,
981 uint32_t index1
, uint32_t index2
)
983 hermon_icm_table_t
*icm
;
984 hermon_dma_info_t
*dma_info
;
989 if (hermon_verbose
) {
990 IBTF_DPRINTF_L2("hermon", "hermon_icm_alloc: rsrc_type (0x%x) "
991 "index1/2 (0x%x/0x%x)", type
, index1
, index2
);
994 icm
= &state
->hs_icm
[type
];
998 status
= HERMON_ICM_ALLOC(HERMON_CMPT_QPC
);
999 if (status
!= DDI_SUCCESS
) {
1002 status
= HERMON_ICM_ALLOC(HERMON_RDB
);
1003 if (status
!= DDI_SUCCESS
) { /* undo icm_alloc's */
1004 HERMON_ICM_FREE(HERMON_CMPT_QPC
);
1007 status
= HERMON_ICM_ALLOC(HERMON_ALTC
);
1008 if (status
!= DDI_SUCCESS
) { /* undo icm_alloc's */
1009 HERMON_ICM_FREE(HERMON_RDB
);
1010 HERMON_ICM_FREE(HERMON_CMPT_QPC
);
1013 status
= HERMON_ICM_ALLOC(HERMON_AUXC
);
1014 if (status
!= DDI_SUCCESS
) { /* undo icm_alloc's */
1015 HERMON_ICM_FREE(HERMON_ALTC
);
1016 HERMON_ICM_FREE(HERMON_RDB
);
1017 HERMON_ICM_FREE(HERMON_CMPT_QPC
);
1023 status
= HERMON_ICM_ALLOC(HERMON_CMPT_SRQC
);
1024 if (status
!= DDI_SUCCESS
) {
1030 status
= HERMON_ICM_ALLOC(HERMON_CMPT_CQC
);
1031 if (status
!= DDI_SUCCESS
) {
1037 status
= HERMON_ICM_ALLOC(HERMON_CMPT_EQC
);
1038 if (status
!= DDI_SUCCESS
) { /* undo icm_alloc's */
1044 /* ensure existence of bitmap and dmainfo, sets "dma_info" */
1045 hermon_bitmap(bitmap
, dma_info
, icm
, index1
, num_to_hdl
);
1047 /* Set up the DMA handle for allocation and mapping */
1049 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*dma_info
))
1050 dma_info
->length
= icm
->span
<< icm
->log_object_size
;
1051 dma_info
->icmaddr
= icm
->icm_baseaddr
+
1052 (((index1
<< icm
->split_shift
) +
1053 (index2
<< icm
->span_shift
)) << icm
->log_object_size
);
1055 /* Allocate memory for the num_to_qp/cq/srq pointers */
1057 icm
->num_to_hdl
[index1
][index2
] =
1058 kmem_zalloc(HERMON_ICM_SPAN
* sizeof (void *), KM_SLEEP
);
1060 if (hermon_verbose
) {
1061 IBTF_DPRINTF_L2("hermon", "alloc DMA: "
1062 "rsrc (0x%x) index (%x, %x) "
1063 "icm_addr/len (%llx/%x) bitmap %p", type
, index1
, index2
,
1064 (longlong_t
)dma_info
->icmaddr
, dma_info
->length
, bitmap
);
1067 /* Allocate and map memory for this span */
1068 status
= hermon_dma_alloc(state
, dma_info
, MAP_ICM
);
1069 if (status
!= DDI_SUCCESS
) {
1070 IBTF_DPRINTF_L2("hermon", "hermon_icm_alloc: DMA "
1071 "allocation failed, status 0x%x", status
);
1074 HERMON_ICM_FREE(HERMON_AUXC
);
1075 HERMON_ICM_FREE(HERMON_ALTC
);
1076 HERMON_ICM_FREE(HERMON_RDB
);
1077 HERMON_ICM_FREE(HERMON_CMPT_QPC
);
1080 HERMON_ICM_FREE(HERMON_CMPT_SRQC
);
1083 HERMON_ICM_FREE(HERMON_CMPT_CQC
);
1086 HERMON_ICM_FREE(HERMON_CMPT_EQC
);
1090 return (DDI_FAILURE
);
1092 if (hermon_verbose
) {
1093 IBTF_DPRINTF_L2("hermon", "hermon_icm_alloc: mapping ICM: "
1094 "rsrc_type (0x%x) index (0x%x, 0x%x) alloc length (0x%x) "
1095 "icm_addr (0x%lx)", type
, index1
, index2
, dma_info
->length
,
1099 /* Set the bit for this slot in the table bitmap */
1100 HERMON_BMAP_BIT_SET(icm
->icm_bitmap
[index1
], index2
);
1102 return (DDI_SUCCESS
);
1107 * Context: Can be called from base context.
1109 * ICM resources have been successfully returned from hermon_icm_alloc().
1110 * Associated dma_info is no longer in use. Free the ICM backing memory.
1113 hermon_icm_free(hermon_state_t
*state
, hermon_rsrc_type_t type
,
1114 uint32_t index1
, uint32_t index2
)
1116 hermon_icm_table_t
*icm
;
1117 hermon_dma_info_t
*dma_info
;
1120 icm
= &state
->hs_icm
[type
];
1121 ASSERT(icm
->icm_dma
[index1
][index2
].icm_refcnt
== 0);
1123 if (hermon_verbose
) {
1124 IBTF_DPRINTF_L2("hermon", "hermon_icm_free: rsrc_type (0x%x) "
1125 "index (0x%x, 0x%x)", type
, index1
, index2
);
1128 dma_info
= icm
->icm_dma
[index1
] + index2
;
1130 /* The following only happens if attach() is failing. */
1131 if (dma_info
== NULL
)
1134 /* Unmap the ICM allocation, then free the backing DMA memory */
1135 status
= hermon_unmap_icm_cmd_post(state
, dma_info
);
1136 if (status
!= DDI_SUCCESS
) {
1137 HERMON_WARNING(state
, "UNMAP_ICM failure");
1139 hermon_dma_free(dma_info
);
1141 /* Clear the bit in the ICM table bitmap */
1142 HERMON_BMAP_BIT_CLR(icm
->icm_bitmap
[index1
], index2
);
1146 HERMON_ICM_FREE(HERMON_AUXC
);
1147 HERMON_ICM_FREE(HERMON_ALTC
);
1148 HERMON_ICM_FREE(HERMON_RDB
);
1149 HERMON_ICM_FREE(HERMON_CMPT_QPC
);
1152 HERMON_ICM_FREE(HERMON_CMPT_SRQC
);
1155 HERMON_ICM_FREE(HERMON_CMPT_CQC
);
1158 HERMON_ICM_FREE(HERMON_CMPT_EQC
);
1166 * hermon_icm_num_to_hdl()
1167 * Context: Can be called from base or interrupt context.
1169 * Given an index of a resource, index through the sparsely allocated
1170 * arrays to find the pointer to its software handle. Return NULL if
1171 * any of the arrays of pointers has been freed (should never happen).
1174 hermon_icm_num_to_hdl(hermon_state_t
*state
, hermon_rsrc_type_t type
,
1177 hermon_icm_table_t
*icm
;
1178 uint32_t span_offset
;
1179 uint32_t index1
, index2
;
1182 icm
= &state
->hs_icm
[type
];
1183 hermon_index(index1
, index2
, idx
, icm
, span_offset
);
1184 p1
= icm
->num_to_hdl
[index1
];
1186 IBTF_DPRINTF_L2("hermon", "icm_num_to_hdl failed at level 1"
1187 ": rsrc_type %d, index 0x%x", type
, idx
);
1192 IBTF_DPRINTF_L2("hermon", "icm_num_to_hdl failed at level 2"
1193 ": rsrc_type %d, index 0x%x", type
, idx
);
1196 return (p2
[span_offset
]);
1200 * hermon_icm_set_num_to_hdl()
1201 * Context: Can be called from base or interrupt context.
1203 * Given an index of a resource, we index through the sparsely allocated
1204 * arrays to store the software handle, used by hermon_icm_num_to_hdl().
1205 * This function is used to both set and reset (set to NULL) the handle.
1206 * This table is allocated during ICM allocation for the given resource,
1207 * so its existence is a given, and the store location does not conflict
1208 * with any other stores to the table (no locking needed).
1211 hermon_icm_set_num_to_hdl(hermon_state_t
*state
, hermon_rsrc_type_t type
,
1212 uint32_t idx
, void *hdl
)
1214 hermon_icm_table_t
*icm
;
1215 uint32_t span_offset
;
1216 uint32_t index1
, index2
;
1218 icm
= &state
->hs_icm
[type
];
1219 hermon_index(index1
, index2
, idx
, icm
, span_offset
);
1220 ASSERT((hdl
== NULL
) ^
1221 (icm
->num_to_hdl
[index1
][index2
][span_offset
] == NULL
));
1222 icm
->num_to_hdl
[index1
][index2
][span_offset
] = hdl
;
1226 * hermon_device_mode()
1227 * Context: Can be called from base or interrupt context.
1229 * Return HERMON_HCA_MODE for operational mode
1230 * Return HERMON_MAINTENANCE_MODE for maintenance mode
1231 * Return 0 otherwise
1233 * A non-zero return for either operational or maintenance mode simplifies
1234 * one of the 2 uses of this function.
1237 hermon_device_mode(hermon_state_t
*state
)
1239 if (state
->hs_vendor_id
!= PCI_VENID_MLX
)
1242 switch (state
->hs_device_id
) {
1243 case PCI_DEVID_HERMON_SDR
:
1244 case PCI_DEVID_HERMON_DDR
:
1245 case PCI_DEVID_HERMON_DDRG2
:
1246 case PCI_DEVID_HERMON_QDRG2
:
1247 case PCI_DEVID_HERMON_QDRG2V
:
1248 return (HERMON_HCA_MODE
);
1249 case PCI_DEVID_HERMON_MAINT
:
1250 return (HERMON_MAINTENANCE_MODE
);
1258 * Context: Only called from attach() path context
1262 hermon_drv_init(hermon_state_t
*state
, dev_info_t
*dip
, int instance
)
1266 /* Retrieve PCI device, vendor and rev IDs */
1267 state
->hs_vendor_id
= HERMON_GET_VENDOR_ID(state
->hs_dip
);
1268 state
->hs_device_id
= HERMON_GET_DEVICE_ID(state
->hs_dip
);
1269 state
->hs_revision_id
= HERMON_GET_REVISION_ID(state
->hs_dip
);
1272 * Check and set the operational mode of the device. If the driver is
1273 * bound to the Hermon device in "maintenance mode", then this generally
1274 * means that either the device has been specifically jumpered to
1275 * start in this mode or the firmware boot process has failed to
1276 * successfully load either the primary or the secondary firmware
1279 state
->hs_operational_mode
= hermon_device_mode(state
);
1280 switch (state
->hs_operational_mode
) {
1281 case HERMON_HCA_MODE
:
1282 state
->hs_cfg_profile_setting
= HERMON_CFG_MEMFREE
;
1284 case HERMON_MAINTENANCE_MODE
:
1285 HERMON_FMANOTE(state
, HERMON_FMA_MAINT
);
1286 state
->hs_fm_degraded_reason
= HCA_FW_MISC
; /* not fw reason */
1287 return (DDI_FAILURE
);
1289 HERMON_FMANOTE(state
, HERMON_FMA_PCIID
);
1290 HERMON_WARNING(state
, "unexpected device type detected");
1291 return (DDI_FAILURE
);
1295 * Initialize the Hermon hardware.
1297 * Note: If this routine returns an error, it is often a reasonably
1298 * good indication that something Hermon firmware-related has caused
1299 * the failure or some HW related errors have caused the failure.
1300 * (also there are few possibilities that SW (e.g. SW resource
1301 * shortage) can cause the failure, but the majority case is due to
1302 * either a firmware related error or a HW related one) In order to
1303 * give the user an opportunity (if desired) to update or reflash
1304 * the Hermon firmware image, we set "hs_operational_mode" flag
1305 * (described above) to indicate that we wish to enter maintenance
1306 * mode in case of the firmware-related issue.
1308 status
= hermon_hw_init(state
);
1309 if (status
!= DDI_SUCCESS
) {
1310 cmn_err(CE_NOTE
, "hermon%d: error during attach: %s", instance
,
1311 state
->hs_attach_buf
);
1312 return (DDI_FAILURE
);
1316 * Now that the ISR has been setup, arm all the EQs for event
1320 status
= hermon_eq_arm_all(state
);
1321 if (status
!= DDI_SUCCESS
) {
1322 cmn_err(CE_NOTE
, "EQ Arm All failed\n");
1323 hermon_hw_fini(state
, HERMON_DRV_CLEANUP_ALL
);
1324 return (DDI_FAILURE
);
1327 /* test interrupts and event queues */
1328 status
= hermon_nop_post(state
, 0x0, 0x0);
1329 if (status
!= DDI_SUCCESS
) {
1330 cmn_err(CE_NOTE
, "Interrupts/EQs failed\n");
1331 hermon_hw_fini(state
, HERMON_DRV_CLEANUP_ALL
);
1332 return (DDI_FAILURE
);
1335 /* Initialize Hermon softstate */
1336 status
= hermon_soft_state_init(state
);
1337 if (status
!= DDI_SUCCESS
) {
1338 cmn_err(CE_NOTE
, "Failed to init soft state\n");
1339 hermon_hw_fini(state
, HERMON_DRV_CLEANUP_ALL
);
1340 return (DDI_FAILURE
);
1343 return (DDI_SUCCESS
);
1349 * Context: Only called from attach() and/or detach() path contexts
1352 hermon_drv_fini(hermon_state_t
*state
)
1354 /* Cleanup Hermon softstate */
1355 hermon_soft_state_fini(state
);
1357 /* Cleanup Hermon resources and shutdown hardware */
1358 hermon_hw_fini(state
, HERMON_DRV_CLEANUP_ALL
);
1363 * hermon_drv_fini2()
1364 * Context: Only called from attach() and/or detach() path contexts
1367 hermon_drv_fini2(hermon_state_t
*state
)
1369 if (state
->hs_fm_poll_thread
) {
1370 ddi_periodic_delete(state
->hs_fm_poll_thread
);
1371 state
->hs_fm_poll_thread
= NULL
;
1374 /* HERMON_DRV_CLEANUP_LEVEL1 */
1375 if (state
->hs_fm_cmdhdl
) {
1376 hermon_regs_map_free(state
, &state
->hs_fm_cmdhdl
);
1377 state
->hs_fm_cmdhdl
= NULL
;
1380 if (state
->hs_reg_cmdhdl
) {
1381 ddi_regs_map_free(&state
->hs_reg_cmdhdl
);
1382 state
->hs_reg_cmdhdl
= NULL
;
1385 /* HERMON_DRV_CLEANUP_LEVEL0 */
1386 if (state
->hs_msix_tbl_entries
) {
1387 kmem_free(state
->hs_msix_tbl_entries
,
1388 state
->hs_msix_tbl_size
);
1389 state
->hs_msix_tbl_entries
= NULL
;
1392 if (state
->hs_msix_pba_entries
) {
1393 kmem_free(state
->hs_msix_pba_entries
,
1394 state
->hs_msix_pba_size
);
1395 state
->hs_msix_pba_entries
= NULL
;
1398 if (state
->hs_fm_msix_tblhdl
) {
1399 hermon_regs_map_free(state
, &state
->hs_fm_msix_tblhdl
);
1400 state
->hs_fm_msix_tblhdl
= NULL
;
1403 if (state
->hs_reg_msix_tblhdl
) {
1404 ddi_regs_map_free(&state
->hs_reg_msix_tblhdl
);
1405 state
->hs_reg_msix_tblhdl
= NULL
;
1408 if (state
->hs_fm_msix_pbahdl
) {
1409 hermon_regs_map_free(state
, &state
->hs_fm_msix_pbahdl
);
1410 state
->hs_fm_msix_pbahdl
= NULL
;
1413 if (state
->hs_reg_msix_pbahdl
) {
1414 ddi_regs_map_free(&state
->hs_reg_msix_pbahdl
);
1415 state
->hs_reg_msix_pbahdl
= NULL
;
1418 if (state
->hs_fm_pcihdl
) {
1419 hermon_pci_config_teardown(state
, &state
->hs_fm_pcihdl
);
1420 state
->hs_fm_pcihdl
= NULL
;
1423 if (state
->hs_reg_pcihdl
) {
1424 pci_config_teardown(&state
->hs_reg_pcihdl
);
1425 state
->hs_reg_pcihdl
= NULL
;
1432 * Context: Only called from attach() path context
1435 hermon_isr_init(hermon_state_t
*state
)
1440 for (intr
= 0; intr
< state
->hs_intrmsi_allocd
; intr
++) {
1443 * Add a handler for the interrupt or MSI
1445 status
= ddi_intr_add_handler(state
->hs_intrmsi_hdl
[intr
],
1446 hermon_isr
, (caddr_t
)state
, (void *)(uintptr_t)intr
);
1447 if (status
!= DDI_SUCCESS
) {
1448 return (DDI_FAILURE
);
1452 * Enable the software interrupt. Note: depending on the value
1453 * returned in the capability flag, we have to call either
1454 * ddi_intr_block_enable() or ddi_intr_enable().
1456 if (state
->hs_intrmsi_cap
& DDI_INTR_FLAG_BLOCK
) {
1457 status
= ddi_intr_block_enable(
1458 &state
->hs_intrmsi_hdl
[intr
], 1);
1459 if (status
!= DDI_SUCCESS
) {
1460 return (DDI_FAILURE
);
1463 status
= ddi_intr_enable(state
->hs_intrmsi_hdl
[intr
]);
1464 if (status
!= DDI_SUCCESS
) {
1465 return (DDI_FAILURE
);
1471 * Now that the ISR has been enabled, defer arm_all EQs for event
1472 * generation until later, in case MSIX is enabled
1474 return (DDI_SUCCESS
);
1480 * Context: Only called from attach() and/or detach() path contexts
1483 hermon_isr_fini(hermon_state_t
*state
)
1487 for (intr
= 0; intr
< state
->hs_intrmsi_allocd
; intr
++) {
1488 /* Disable the software interrupt */
1489 if (state
->hs_intrmsi_cap
& DDI_INTR_FLAG_BLOCK
) {
1490 (void) ddi_intr_block_disable(
1491 &state
->hs_intrmsi_hdl
[intr
], 1);
1493 (void) ddi_intr_disable(state
->hs_intrmsi_hdl
[intr
]);
1497 * Remove the software handler for the interrupt or MSI
1499 (void) ddi_intr_remove_handler(state
->hs_intrmsi_hdl
[intr
]);
1505 * Sum of ICM configured values:
1506 * cMPT, dMPT, MTT, QPC, SRQC, RDB, CQC, ALTC, AUXC, EQC, MCG
1510 hermon_size_icm(hermon_state_t
*state
)
1512 hermon_hw_querydevlim_t
*devlim
;
1513 hermon_cfg_profile_t
*cfg
;
1514 uint64_t num_cmpts
, num_dmpts
, num_mtts
;
1515 uint64_t num_qpcs
, num_srqc
, num_rdbs
;
1516 #ifndef HERMON_FW_WORKAROUND
1519 uint64_t num_cqcs
, num_altc
;
1520 uint64_t num_eqcs
, num_mcgs
;
1523 devlim
= &state
->hs_devlim
;
1524 cfg
= state
->hs_cfg_profile
;
1525 /* number of respective entries */
1526 num_cmpts
= (uint64_t)0x1 << cfg
->cp_log_num_cmpt
;
1527 num_mtts
= (uint64_t)0x1 << cfg
->cp_log_num_mtt
;
1528 num_dmpts
= (uint64_t)0x1 << cfg
->cp_log_num_dmpt
;
1529 num_qpcs
= (uint64_t)0x1 << cfg
->cp_log_num_qp
;
1530 num_srqc
= (uint64_t)0x1 << cfg
->cp_log_num_srq
;
1531 num_rdbs
= (uint64_t)0x1 << cfg
->cp_log_num_rdb
;
1532 num_cqcs
= (uint64_t)0x1 << cfg
->cp_log_num_cq
;
1533 num_altc
= (uint64_t)0x1 << cfg
->cp_log_num_qp
;
1534 #ifndef HERMON_FW_WORKAROUND
1535 num_auxc
= (uint64_t)0x1 << cfg
->cp_log_num_qp
;
1537 num_eqcs
= (uint64_t)0x1 << cfg
->cp_log_num_eq
;
1538 num_mcgs
= (uint64_t)0x1 << cfg
->cp_log_num_mcg
;
1541 num_cmpts
* devlim
->cmpt_entry_sz
+
1542 num_dmpts
* devlim
->dmpt_entry_sz
+
1543 num_mtts
* devlim
->mtt_entry_sz
+
1544 num_qpcs
* devlim
->qpc_entry_sz
+
1545 num_srqc
* devlim
->srq_entry_sz
+
1546 num_rdbs
* devlim
->rdmardc_entry_sz
+
1547 num_cqcs
* devlim
->cqc_entry_sz
+
1548 num_altc
* devlim
->altc_entry_sz
+
1549 #ifdef HERMON_FW_WORKAROUND
1552 num_auxc
* devlim
->aux_entry_sz
+
1554 num_eqcs
* devlim
->eqc_entry_sz
+
1555 num_mcgs
* HERMON_MCGMEM_SZ(state
);
1562 * Context: Only called from attach() path context
1565 hermon_hw_init(hermon_state_t
*state
)
1567 hermon_drv_cleanup_level_t cleanup
;
1568 sm_nodeinfo_t nodeinfo
;
1569 uint64_t clr_intr_offset
;
1571 uint32_t fw_size
; /* in page */
1574 /* This is where driver initialization begins */
1575 cleanup
= HERMON_DRV_CLEANUP_LEVEL0
;
1577 /* Setup device access attributes */
1578 state
->hs_reg_accattr
.devacc_attr_version
= DDI_DEVICE_ATTR_V1
;
1579 state
->hs_reg_accattr
.devacc_attr_endian_flags
= DDI_STRUCTURE_BE_ACC
;
1580 state
->hs_reg_accattr
.devacc_attr_dataorder
= DDI_STRICTORDER_ACC
;
1581 state
->hs_reg_accattr
.devacc_attr_access
= DDI_DEFAULT_ACC
;
1583 /* Setup fma-protected access attributes */
1584 state
->hs_fm_accattr
.devacc_attr_version
=
1585 hermon_devacc_attr_version(state
);
1586 state
->hs_fm_accattr
.devacc_attr_endian_flags
= DDI_STRUCTURE_BE_ACC
;
1587 state
->hs_fm_accattr
.devacc_attr_dataorder
= DDI_STRICTORDER_ACC
;
1588 /* set acc err protection type */
1589 state
->hs_fm_accattr
.devacc_attr_access
=
1590 hermon_devacc_attr_access(state
);
1592 /* Setup for PCI config read/write of HCA device */
1593 status
= hermon_pci_config_setup(state
, &state
->hs_fm_pcihdl
);
1594 if (status
!= DDI_SUCCESS
) {
1595 hermon_hw_fini(state
, cleanup
);
1596 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1597 "hw_init_PCI_config_space_regmap_fail");
1598 /* This case is not the degraded one */
1599 return (DDI_FAILURE
);
1602 /* Map PCI config space and MSI-X tables/pba */
1603 hermon_set_msix_info(state
);
1605 /* Map in Hermon registers (CMD, UAR, MSIX) and setup offsets */
1606 status
= hermon_regs_map_setup(state
, HERMON_CMD_BAR
,
1607 &state
->hs_reg_cmd_baseaddr
, 0, 0, &state
->hs_fm_accattr
,
1608 &state
->hs_fm_cmdhdl
);
1609 if (status
!= DDI_SUCCESS
) {
1610 hermon_hw_fini(state
, cleanup
);
1611 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1612 "hw_init_CMD_BAR_regmap_fail");
1613 /* This case is not the degraded one */
1614 return (DDI_FAILURE
);
1617 cleanup
= HERMON_DRV_CLEANUP_LEVEL1
;
1619 * We defer UAR-BAR mapping until later. Need to know if
1620 * blueflame mapping is to be done, and don't know that until after
1621 * we get the dev_caps, so do it right after that
1625 * There is a third BAR defined for Hermon - it is for MSIX
1627 * Will need to explore it's possible need/use w/ Mellanox
1628 * [es] Temporary mapping maybe
1631 #ifdef HERMON_SUPPORTS_MSIX_BAR
1632 status
= ddi_regs_map_setup(state
->hs_dip
, HERMON_MSIX_BAR
,
1633 &state
->hs_reg_msi_baseaddr
, 0, 0, &state
->hs_reg_accattr
,
1634 &state
->hs_reg_msihdl
);
1635 if (status
!= DDI_SUCCESS
) {
1636 hermon_hw_fini(state
, cleanup
);
1637 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1638 "hw_init_MSIX_BAR_regmap_fail");
1639 /* This case is not the degraded one */
1640 return (DDI_FAILURE
);
1644 cleanup
= HERMON_DRV_CLEANUP_LEVEL2
;
1647 * Save interesting registers away. The offsets of the first two
1648 * here (HCR and sw_reset) are detailed in the PRM, the others are
1649 * derived from values in the QUERY_FW output, so we'll save them
1652 /* Host Command Register (HCR) */
1653 state
->hs_cmd_regs
.hcr
= (hermon_hw_hcr_t
*)
1654 ((uintptr_t)state
->hs_reg_cmd_baseaddr
+ HERMON_CMD_HCR_OFFSET
);
1655 state
->hs_cmd_toggle
= 0; /* initialize it for use */
1657 /* Software Reset register (sw_reset) and semaphore */
1658 state
->hs_cmd_regs
.sw_reset
= (uint32_t *)
1659 ((uintptr_t)state
->hs_reg_cmd_baseaddr
+
1660 HERMON_CMD_SW_RESET_OFFSET
);
1661 state
->hs_cmd_regs
.sw_semaphore
= (uint32_t *)
1662 ((uintptr_t)state
->hs_reg_cmd_baseaddr
+
1663 HERMON_CMD_SW_SEMAPHORE_OFFSET
);
1665 /* make sure init'd before we start filling things in */
1666 bzero(&state
->hs_hcaparams
, sizeof (struct hermon_hw_initqueryhca_s
));
1668 /* Initialize the Phase1 configuration profile */
1669 status
= hermon_cfg_profile_init_phase1(state
);
1670 if (status
!= DDI_SUCCESS
) {
1671 hermon_hw_fini(state
, cleanup
);
1672 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1673 "hw_init_cfginit1_fail");
1674 /* This case is not the degraded one */
1675 return (DDI_FAILURE
);
1677 cleanup
= HERMON_DRV_CLEANUP_LEVEL3
;
1679 /* Do a software reset of the adapter to ensure proper state */
1680 status
= hermon_sw_reset(state
);
1681 if (status
!= HERMON_CMD_SUCCESS
) {
1682 hermon_hw_fini(state
, cleanup
);
1683 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1684 "hw_init_sw_reset_fail");
1685 /* This case is not the degraded one */
1686 return (DDI_FAILURE
);
1689 /* Initialize mailboxes */
1690 status
= hermon_rsrc_init_phase1(state
);
1691 if (status
!= DDI_SUCCESS
) {
1692 hermon_hw_fini(state
, cleanup
);
1693 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1694 "hw_init_rsrcinit1_fail");
1695 /* This case is not the degraded one */
1696 return (DDI_FAILURE
);
1698 cleanup
= HERMON_DRV_CLEANUP_LEVEL4
;
1701 status
= hermon_cmn_query_cmd_post(state
, QUERY_FW
, 0, 0, &state
->hs_fw
,
1702 sizeof (hermon_hw_queryfw_t
), HERMON_CMD_NOSLEEP_SPIN
);
1703 if (status
!= HERMON_CMD_SUCCESS
) {
1704 cmn_err(CE_NOTE
, "QUERY_FW command failed: %08x\n", status
);
1705 hermon_hw_fini(state
, cleanup
);
1706 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1707 "hw_init_query_fw_cmd_fail");
1708 /* This case is not the degraded one */
1709 return (DDI_FAILURE
);
1712 /* Validate what/that HERMON FW version is appropriate */
1714 status
= hermon_fw_version_check(state
);
1715 if (status
!= DDI_SUCCESS
) {
1716 HERMON_FMANOTE(state
, HERMON_FMA_FWVER
);
1717 if (state
->hs_operational_mode
== HERMON_HCA_MODE
) {
1718 cmn_err(CE_CONT
, "Unsupported Hermon FW version: "
1719 "expected: %04d.%04d.%04d, "
1720 "actual: %04d.%04d.%04d\n",
1721 HERMON_FW_VER_MAJOR
,
1722 HERMON_FW_VER_MINOR
,
1723 HERMON_FW_VER_SUBMINOR
,
1724 state
->hs_fw
.fw_rev_major
,
1725 state
->hs_fw
.fw_rev_minor
,
1726 state
->hs_fw
.fw_rev_subminor
);
1728 cmn_err(CE_CONT
, "Unsupported FW version: "
1730 state
->hs_fw
.fw_rev_major
,
1731 state
->hs_fw
.fw_rev_minor
,
1732 state
->hs_fw
.fw_rev_subminor
);
1734 state
->hs_operational_mode
= HERMON_MAINTENANCE_MODE
;
1735 state
->hs_fm_degraded_reason
= HCA_FW_MISMATCH
;
1736 hermon_hw_fini(state
, cleanup
);
1737 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1738 "hw_init_checkfwver_fail");
1739 /* This case is the degraded one */
1740 return (HERMON_CMD_BAD_NVMEM
);
1744 * Save off the rest of the interesting registers that we'll be using.
1745 * Setup the offsets for the other registers.
1749 * Hermon does the intr_offset from the BAR - technically should get the
1750 * BAR info from the response, but PRM says it's from BAR0-1, which is
1751 * for us the CMD BAR
1754 clr_intr_offset
= state
->hs_fw
.clr_intr_offs
& HERMON_CMD_OFFSET_MASK
;
1756 /* Save Clear Interrupt address */
1757 state
->hs_cmd_regs
.clr_intr
= (uint64_t *)
1758 (uintptr_t)(state
->hs_reg_cmd_baseaddr
+ clr_intr_offset
);
1761 * Set the error buffer also into the structure - used in hermon_event.c
1762 * to check for internal error on the HCA, not reported in eqe or
1763 * (necessarily) by interrupt
1765 state
->hs_cmd_regs
.fw_err_buf
= (uint32_t *)(uintptr_t)
1766 (state
->hs_reg_cmd_baseaddr
+ state
->hs_fw
.error_buf_addr
);
1769 * Invoke a polling thread to check the error buffer periodically.
1771 if (!hermon_no_inter_err_chk
) {
1772 state
->hs_fm_poll_thread
= ddi_periodic_add(
1773 hermon_inter_err_chk
, (void *)state
, FM_POLL_INTERVAL
,
1777 cleanup
= HERMON_DRV_CLEANUP_LEVEL5
;
1780 * Allocate, map, and run the HCA Firmware.
1783 /* Allocate memory for the firmware to load into and map it */
1785 /* get next higher power of 2 */
1786 fw_size
= 1 << highbit(state
->hs_fw
.fw_pages
);
1787 state
->hs_fw_dma
.length
= fw_size
<< HERMON_PAGESHIFT
;
1788 status
= hermon_dma_alloc(state
, &state
->hs_fw_dma
, MAP_FA
);
1789 if (status
!= DDI_SUCCESS
) {
1790 cmn_err(CE_NOTE
, "FW alloc failed\n");
1791 hermon_hw_fini(state
, cleanup
);
1792 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1793 "hw_init_dma_alloc_fw_fail");
1794 /* This case is not the degraded one */
1795 return (DDI_FAILURE
);
1798 cleanup
= HERMON_DRV_CLEANUP_LEVEL6
;
1800 /* Invoke the RUN_FW cmd to run the firmware */
1801 status
= hermon_run_fw_cmd_post(state
);
1802 if (status
!= DDI_SUCCESS
) {
1803 cmn_err(CE_NOTE
, "RUN_FW command failed: 0x%08x\n", status
);
1804 if (status
== HERMON_CMD_BAD_NVMEM
) {
1805 state
->hs_operational_mode
= HERMON_MAINTENANCE_MODE
;
1806 state
->hs_fm_degraded_reason
= HCA_FW_CORRUPT
;
1808 hermon_hw_fini(state
, cleanup
);
1809 HERMON_ATTACH_MSG(state
->hs_attach_buf
, "hw_init_run_fw_fail");
1811 * If the status is HERMON_CMD_BAD_NVMEM, it's likely the
1812 * firmware is corrupted, so the mode falls into the
1815 return (status
== HERMON_CMD_BAD_NVMEM
? HERMON_CMD_BAD_NVMEM
:
1821 * QUERY DEVICE LIMITS/CAPABILITIES
1822 * NOTE - in Hermon, the command is changed to QUERY_DEV_CAP,
1823 * but for familiarity we have kept the structure name the
1824 * same as Tavor/Arbel
1827 status
= hermon_cmn_query_cmd_post(state
, QUERY_DEV_CAP
, 0, 0,
1828 &state
->hs_devlim
, sizeof (hermon_hw_querydevlim_t
),
1829 HERMON_CMD_NOSLEEP_SPIN
);
1830 if (status
!= HERMON_CMD_SUCCESS
) {
1831 cmn_err(CE_NOTE
, "QUERY_DEV_CAP command failed: 0x%08x\n",
1833 hermon_hw_fini(state
, cleanup
);
1834 HERMON_ATTACH_MSG(state
->hs_attach_buf
, "hw_init_devcap_fail");
1835 /* This case is not the degraded one */
1836 return (DDI_FAILURE
);
1839 state
->hs_rsvd_eqs
= max(state
->hs_devlim
.num_rsvd_eq
,
1840 (4 * state
->hs_devlim
.num_rsvd_uar
));
1842 /* now we have enough info to map in the UAR BAR */
1844 * First, we figure out how to map the BAR for UAR - use only half if
1845 * BlueFlame is enabled - in that case the mapped length is 1/2 the
1846 * log_max_uar_sz (max__uar - 1) * 1MB ( +20).
1849 if (state
->hs_devlim
.blu_flm
) { /* Blue Flame Enabled */
1850 offset
= (uint64_t)1 << (state
->hs_devlim
.log_max_uar_sz
+ 20);
1852 offset
= 0; /* a zero length means map the whole thing */
1854 status
= hermon_regs_map_setup(state
, HERMON_UAR_BAR
,
1855 &state
->hs_reg_uar_baseaddr
, 0, offset
, &state
->hs_fm_accattr
,
1856 &state
->hs_fm_uarhdl
);
1857 if (status
!= DDI_SUCCESS
) {
1858 HERMON_ATTACH_MSG(state
->hs_attach_buf
, "UAR BAR mapping");
1859 /* This case is not the degraded one */
1860 return (DDI_FAILURE
);
1863 /* and if BlueFlame is enabled, map the other half there */
1864 if (state
->hs_devlim
.blu_flm
) { /* Blue Flame Enabled */
1865 offset
= (uint64_t)1 << (state
->hs_devlim
.log_max_uar_sz
+ 20);
1866 status
= ddi_regs_map_setup(state
->hs_dip
, HERMON_UAR_BAR
,
1867 &state
->hs_reg_bf_baseaddr
, offset
, offset
,
1868 &state
->hs_reg_accattr
, &state
->hs_reg_bfhdl
);
1869 if (status
!= DDI_SUCCESS
) {
1870 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1871 "BlueFlame BAR mapping");
1872 /* This case is not the degraded one */
1873 return (DDI_FAILURE
);
1875 /* This will be used in hw_fini if we fail to init. */
1876 state
->hs_bf_offset
= offset
;
1878 cleanup
= HERMON_DRV_CLEANUP_LEVEL7
;
1880 /* Hermon has a couple of things needed for phase 2 in query port */
1882 status
= hermon_cmn_query_cmd_post(state
, QUERY_PORT
, 0, 0x01,
1883 &state
->hs_queryport
, sizeof (hermon_hw_query_port_t
),
1884 HERMON_CMD_NOSLEEP_SPIN
);
1885 if (status
!= HERMON_CMD_SUCCESS
) {
1886 cmn_err(CE_NOTE
, "QUERY_PORT command failed: 0x%08x\n",
1888 hermon_hw_fini(state
, cleanup
);
1889 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1890 "hw_init_queryport_fail");
1891 /* This case is not the degraded one */
1892 return (DDI_FAILURE
);
1895 /* Initialize the Phase2 Hermon configuration profile */
1896 status
= hermon_cfg_profile_init_phase2(state
);
1897 if (status
!= DDI_SUCCESS
) {
1898 cmn_err(CE_NOTE
, "CFG phase 2 failed: 0x%08x\n", status
);
1899 hermon_hw_fini(state
, cleanup
);
1900 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1901 "hw_init_cfginit2_fail");
1902 /* This case is not the degraded one */
1903 return (DDI_FAILURE
);
1906 /* Determine and set the ICM size */
1907 state
->hs_icm_sz
= hermon_size_icm(state
);
1908 status
= hermon_set_icm_size_cmd_post(state
);
1909 if (status
!= DDI_SUCCESS
) {
1910 cmn_err(CE_NOTE
, "Hermon: SET_ICM_SIZE cmd failed: 0x%08x\n",
1912 hermon_hw_fini(state
, cleanup
);
1913 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1914 "hw_init_seticmsz_fail");
1915 /* This case is not the degraded one */
1916 return (DDI_FAILURE
);
1918 /* alloc icm aux physical memory and map it */
1920 state
->hs_icma_dma
.length
= 1 << highbit(state
->hs_icma_sz
);
1922 status
= hermon_dma_alloc(state
, &state
->hs_icma_dma
, MAP_ICM_AUX
);
1923 if (status
!= DDI_SUCCESS
) {
1924 cmn_err(CE_NOTE
, "failed to alloc (0x%llx) bytes for ICMA\n",
1925 (longlong_t
)state
->hs_icma_dma
.length
);
1926 hermon_hw_fini(state
, cleanup
);
1927 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1928 "hw_init_dma_alloc_icm_aux_fail");
1929 /* This case is not the degraded one */
1930 return (DDI_FAILURE
);
1932 cleanup
= HERMON_DRV_CLEANUP_LEVEL8
;
1934 cleanup
= HERMON_DRV_CLEANUP_LEVEL9
;
1936 /* Allocate an array of structures to house the ICM tables */
1937 state
->hs_icm
= kmem_zalloc(HERMON_NUM_ICM_RESOURCES
*
1938 sizeof (hermon_icm_table_t
), KM_SLEEP
);
1940 /* Set up the ICM address space and the INIT_HCA command input */
1941 status
= hermon_icm_config_setup(state
, &state
->hs_hcaparams
);
1942 if (status
!= HERMON_CMD_SUCCESS
) {
1943 cmn_err(CE_NOTE
, "ICM configuration failed\n");
1944 hermon_hw_fini(state
, cleanup
);
1945 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1946 "hw_init_icm_config_setup_fail");
1947 /* This case is not the degraded one */
1948 return (DDI_FAILURE
);
1950 cleanup
= HERMON_DRV_CLEANUP_LEVEL10
;
1952 /* Initialize the adapter with the INIT_HCA cmd */
1953 status
= hermon_init_hca_cmd_post(state
, &state
->hs_hcaparams
,
1954 HERMON_CMD_NOSLEEP_SPIN
);
1955 if (status
!= HERMON_CMD_SUCCESS
) {
1956 cmn_err(CE_NOTE
, "INIT_HCA command failed: %08x\n", status
);
1957 hermon_hw_fini(state
, cleanup
);
1958 HERMON_ATTACH_MSG(state
->hs_attach_buf
, "hw_init_hca_fail");
1959 /* This case is not the degraded one */
1960 return (DDI_FAILURE
);
1962 cleanup
= HERMON_DRV_CLEANUP_LEVEL11
;
1964 /* Enter the second phase of init for Hermon configuration/resources */
1965 status
= hermon_rsrc_init_phase2(state
);
1966 if (status
!= DDI_SUCCESS
) {
1967 hermon_hw_fini(state
, cleanup
);
1968 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1969 "hw_init_rsrcinit2_fail");
1970 /* This case is not the degraded one */
1971 return (DDI_FAILURE
);
1973 cleanup
= HERMON_DRV_CLEANUP_LEVEL12
;
1975 /* Query the adapter via QUERY_ADAPTER */
1976 status
= hermon_cmn_query_cmd_post(state
, QUERY_ADAPTER
, 0, 0,
1977 &state
->hs_adapter
, sizeof (hermon_hw_queryadapter_t
),
1978 HERMON_CMD_NOSLEEP_SPIN
);
1979 if (status
!= HERMON_CMD_SUCCESS
) {
1980 cmn_err(CE_NOTE
, "Hermon: QUERY_ADAPTER command failed: %08x\n",
1982 hermon_hw_fini(state
, cleanup
);
1983 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1984 "hw_init_query_adapter_fail");
1985 /* This case is not the degraded one */
1986 return (DDI_FAILURE
);
1989 /* Allocate protection domain (PD) for Hermon internal use */
1990 status
= hermon_pd_alloc(state
, &state
->hs_pdhdl_internal
,
1992 if (status
!= DDI_SUCCESS
) {
1993 cmn_err(CE_NOTE
, "failed to alloc internal PD\n");
1994 hermon_hw_fini(state
, cleanup
);
1995 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
1996 "hw_init_internal_pd_alloc_fail");
1997 /* This case is not the degraded one */
1998 return (DDI_FAILURE
);
2000 cleanup
= HERMON_DRV_CLEANUP_LEVEL13
;
2002 /* Setup UAR page for kernel use */
2003 status
= hermon_internal_uarpg_init(state
);
2004 if (status
!= DDI_SUCCESS
) {
2005 cmn_err(CE_NOTE
, "failed to setup internal UAR\n");
2006 hermon_hw_fini(state
, cleanup
);
2007 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2008 "hw_init_internal_uarpg_alloc_fail");
2009 /* This case is not the degraded one */
2010 return (DDI_FAILURE
);
2012 cleanup
= HERMON_DRV_CLEANUP_LEVEL14
;
2014 /* Query and initialize the Hermon interrupt/MSI information */
2015 status
= hermon_intr_or_msi_init(state
);
2016 if (status
!= DDI_SUCCESS
) {
2017 cmn_err(CE_NOTE
, "failed to setup INTR/MSI\n");
2018 hermon_hw_fini(state
, cleanup
);
2019 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2020 "hw_init_intr_or_msi_init_fail");
2021 /* This case is not the degraded one */
2022 return (DDI_FAILURE
);
2024 cleanup
= HERMON_DRV_CLEANUP_LEVEL15
;
2026 status
= hermon_isr_init(state
); /* set up the isr */
2027 if (status
!= DDI_SUCCESS
) {
2028 cmn_err(CE_NOTE
, "failed to init isr\n");
2029 hermon_hw_fini(state
, cleanup
);
2030 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2031 "hw_init_isrinit_fail");
2032 /* This case is not the degraded one */
2033 return (DDI_FAILURE
);
2035 cleanup
= HERMON_DRV_CLEANUP_LEVEL16
;
2037 /* Setup the event queues */
2038 status
= hermon_eq_init_all(state
);
2039 if (status
!= DDI_SUCCESS
) {
2040 cmn_err(CE_NOTE
, "failed to init EQs\n");
2041 hermon_hw_fini(state
, cleanup
);
2042 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2043 "hw_init_eqinitall_fail");
2044 /* This case is not the degraded one */
2045 return (DDI_FAILURE
);
2047 cleanup
= HERMON_DRV_CLEANUP_LEVEL17
;
2051 /* Reserve contexts for QP0 and QP1 */
2052 status
= hermon_special_qp_contexts_reserve(state
);
2053 if (status
!= DDI_SUCCESS
) {
2054 cmn_err(CE_NOTE
, "failed to init special QPs\n");
2055 hermon_hw_fini(state
, cleanup
);
2056 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2057 "hw_init_rsrv_sqp_fail");
2058 /* This case is not the degraded one */
2059 return (DDI_FAILURE
);
2061 cleanup
= HERMON_DRV_CLEANUP_LEVEL18
;
2063 /* Initialize for multicast group handling */
2064 status
= hermon_mcg_init(state
);
2065 if (status
!= DDI_SUCCESS
) {
2066 cmn_err(CE_NOTE
, "failed to init multicast\n");
2067 hermon_hw_fini(state
, cleanup
);
2068 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2069 "hw_init_mcg_init_fail");
2070 /* This case is not the degraded one */
2071 return (DDI_FAILURE
);
2073 cleanup
= HERMON_DRV_CLEANUP_LEVEL19
;
2075 /* Initialize the Hermon IB port(s) */
2076 status
= hermon_hca_port_init(state
);
2077 if (status
!= DDI_SUCCESS
) {
2078 cmn_err(CE_NOTE
, "failed to init HCA Port\n");
2079 hermon_hw_fini(state
, cleanup
);
2080 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2081 "hw_init_hca_port_init_fail");
2082 /* This case is not the degraded one */
2083 return (DDI_FAILURE
);
2086 cleanup
= HERMON_DRV_CLEANUP_ALL
;
2088 /* Determine NodeGUID and SystemImageGUID */
2089 status
= hermon_getnodeinfo_cmd_post(state
, HERMON_CMD_NOSLEEP_SPIN
,
2091 if (status
!= HERMON_CMD_SUCCESS
) {
2092 cmn_err(CE_NOTE
, "GetNodeInfo command failed: %08x\n", status
);
2093 hermon_hw_fini(state
, cleanup
);
2094 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2095 "hw_init_getnodeinfo_cmd_fail");
2096 /* This case is not the degraded one */
2097 return (DDI_FAILURE
);
2101 * If the NodeGUID value was set in OBP properties, then we use that
2102 * value. But we still print a message if the value we queried from
2103 * firmware does not match this value.
2105 * Otherwise if OBP value is not set then we use the value from
2106 * firmware unconditionally.
2108 if (state
->hs_cfg_profile
->cp_nodeguid
) {
2109 state
->hs_nodeguid
= state
->hs_cfg_profile
->cp_nodeguid
;
2111 state
->hs_nodeguid
= nodeinfo
.NodeGUID
;
2114 if (state
->hs_nodeguid
!= nodeinfo
.NodeGUID
) {
2115 cmn_err(CE_NOTE
, "!NodeGUID value queried from firmware "
2116 "does not match value set by device property");
2120 * If the SystemImageGUID value was set in OBP properties, then we use
2121 * that value. But we still print a message if the value we queried
2122 * from firmware does not match this value.
2124 * Otherwise if OBP value is not set then we use the value from
2125 * firmware unconditionally.
2127 if (state
->hs_cfg_profile
->cp_sysimgguid
) {
2128 state
->hs_sysimgguid
= state
->hs_cfg_profile
->cp_sysimgguid
;
2130 state
->hs_sysimgguid
= nodeinfo
.SystemImageGUID
;
2133 if (state
->hs_sysimgguid
!= nodeinfo
.SystemImageGUID
) {
2134 cmn_err(CE_NOTE
, "!SystemImageGUID value queried from firmware "
2135 "does not match value set by device property");
2138 /* Get NodeDescription */
2139 status
= hermon_getnodedesc_cmd_post(state
, HERMON_CMD_NOSLEEP_SPIN
,
2140 (sm_nodedesc_t
*)&state
->hs_nodedesc
);
2141 if (status
!= HERMON_CMD_SUCCESS
) {
2142 cmn_err(CE_CONT
, "GetNodeDesc command failed: %08x\n", status
);
2143 hermon_hw_fini(state
, cleanup
);
2144 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2145 "hw_init_getnodedesc_cmd_fail");
2146 /* This case is not the degraded one */
2147 return (DDI_FAILURE
);
2150 return (DDI_SUCCESS
);
2156 * Context: Only called from attach() and/or detach() path contexts
2159 hermon_hw_fini(hermon_state_t
*state
, hermon_drv_cleanup_level_t cleanup
)
2166 * JBDB - We might not want to run these returns in all cases of
2167 * Bad News. We should still attempt to free all of the DMA memory
2168 * resources... This needs to be worked last, after all allocations
2169 * are implemented. For now, and possibly for later, this works.
2174 * If we add more driver initialization steps that should be cleaned
2175 * up here, we need to ensure that HERMON_DRV_CLEANUP_ALL is still the
2176 * first entry (i.e. corresponds to the last init step).
2178 case HERMON_DRV_CLEANUP_ALL
:
2179 /* Shutdown the Hermon IB port(s) */
2180 num_ports
= state
->hs_cfg_profile
->cp_num_ports
;
2181 (void) hermon_hca_ports_shutdown(state
, num_ports
);
2184 case HERMON_DRV_CLEANUP_LEVEL19
:
2185 /* Teardown resources used for multicast group handling */
2186 hermon_mcg_fini(state
);
2189 case HERMON_DRV_CLEANUP_LEVEL18
:
2190 /* Unreserve the special QP contexts */
2191 hermon_special_qp_contexts_unreserve(state
);
2194 case HERMON_DRV_CLEANUP_LEVEL17
:
2196 * Attempt to teardown all event queues (EQ). If we fail
2197 * here then print a warning message and return. Something
2198 * (either in HW or SW) has gone seriously wrong.
2200 status
= hermon_eq_fini_all(state
);
2201 if (status
!= DDI_SUCCESS
) {
2202 HERMON_WARNING(state
, "failed to teardown EQs");
2206 case HERMON_DRV_CLEANUP_LEVEL16
:
2207 /* Teardown Hermon interrupts */
2208 hermon_isr_fini(state
);
2211 case HERMON_DRV_CLEANUP_LEVEL15
:
2212 status
= hermon_intr_or_msi_fini(state
);
2213 if (status
!= DDI_SUCCESS
) {
2214 HERMON_WARNING(state
, "failed to free intr/MSI");
2219 case HERMON_DRV_CLEANUP_LEVEL14
:
2220 /* Free the resources for the Hermon internal UAR pages */
2221 hermon_internal_uarpg_fini(state
);
2224 case HERMON_DRV_CLEANUP_LEVEL13
:
2226 * Free the PD that was used internally by Hermon software. If
2227 * we fail here then print a warning and return. Something
2228 * (probably software-related, but perhaps HW) has gone wrong.
2230 status
= hermon_pd_free(state
, &state
->hs_pdhdl_internal
);
2231 if (status
!= DDI_SUCCESS
) {
2232 HERMON_WARNING(state
, "failed to free internal PD");
2237 case HERMON_DRV_CLEANUP_LEVEL12
:
2238 /* Cleanup all the phase2 resources first */
2239 hermon_rsrc_fini(state
, HERMON_RSRC_CLEANUP_ALL
);
2242 case HERMON_DRV_CLEANUP_LEVEL11
:
2243 /* LEVEL11 is after INIT_HCA */
2247 case HERMON_DRV_CLEANUP_LEVEL10
:
2249 * Unmap the ICM memory area with UNMAP_ICM command.
2251 status
= hermon_unmap_icm_cmd_post(state
, NULL
);
2252 if (status
!= DDI_SUCCESS
) {
2254 "hermon_hw_fini: failed to unmap ICM\n");
2257 /* Free the initial ICM DMA handles */
2258 hermon_icm_dma_fini(state
);
2260 /* Free the ICM table structures */
2261 hermon_icm_tables_fini(state
);
2263 /* Free the ICM table handles */
2264 kmem_free(state
->hs_icm
, HERMON_NUM_ICM_RESOURCES
*
2265 sizeof (hermon_icm_table_t
));
2269 case HERMON_DRV_CLEANUP_LEVEL9
:
2271 * Unmap the ICM Aux memory area with UNMAP_ICM_AUX command.
2273 status
= hermon_unmap_icm_aux_cmd_post(state
);
2274 if (status
!= HERMON_CMD_SUCCESS
) {
2276 "hermon_hw_fini: failed to unmap ICMA\n");
2280 case HERMON_DRV_CLEANUP_LEVEL8
:
2282 * Deallocate ICM Aux DMA memory.
2284 hermon_dma_free(&state
->hs_icma_dma
);
2287 case HERMON_DRV_CLEANUP_LEVEL7
:
2288 if (state
->hs_fm_uarhdl
) {
2289 hermon_regs_map_free(state
, &state
->hs_fm_uarhdl
);
2290 state
->hs_fm_uarhdl
= NULL
;
2293 if (state
->hs_reg_uarhdl
) {
2294 ddi_regs_map_free(&state
->hs_reg_uarhdl
);
2295 state
->hs_reg_uarhdl
= NULL
;
2298 if (state
->hs_bf_offset
!= 0 && state
->hs_reg_bfhdl
) {
2299 ddi_regs_map_free(&state
->hs_reg_bfhdl
);
2300 state
->hs_reg_bfhdl
= NULL
;
2303 for (i
= 0; i
< HERMON_MAX_PORTS
; i
++) {
2304 if (state
->hs_pkey
[i
]) {
2305 kmem_free(state
->hs_pkey
[i
], (1 <<
2306 state
->hs_cfg_profile
->cp_log_max_pkeytbl
) *
2307 sizeof (ib_pkey_t
));
2308 state
->hs_pkey
[i
] = NULL
;
2310 if (state
->hs_guid
[i
]) {
2311 kmem_free(state
->hs_guid
[i
], (1 <<
2312 state
->hs_cfg_profile
->cp_log_max_gidtbl
) *
2313 sizeof (ib_guid_t
));
2314 state
->hs_guid
[i
] = NULL
;
2319 case HERMON_DRV_CLEANUP_LEVEL6
:
2321 * Unmap the firmware memory area with UNMAP_FA command.
2323 status
= hermon_unmap_fa_cmd_post(state
);
2325 if (status
!= HERMON_CMD_SUCCESS
) {
2327 "hermon_hw_fini: failed to unmap FW\n");
2331 * Deallocate firmware DMA memory.
2333 hermon_dma_free(&state
->hs_fw_dma
);
2336 case HERMON_DRV_CLEANUP_LEVEL5
:
2337 /* stop the poll thread */
2338 if (state
->hs_fm_poll_thread
) {
2339 ddi_periodic_delete(state
->hs_fm_poll_thread
);
2340 state
->hs_fm_poll_thread
= NULL
;
2344 case HERMON_DRV_CLEANUP_LEVEL4
:
2345 /* Then cleanup the phase1 resources */
2346 hermon_rsrc_fini(state
, HERMON_RSRC_CLEANUP_PHASE1_COMPLETE
);
2349 case HERMON_DRV_CLEANUP_LEVEL3
:
2350 /* Teardown any resources allocated for the config profile */
2351 hermon_cfg_profile_fini(state
);
2354 case HERMON_DRV_CLEANUP_LEVEL2
:
2355 #ifdef HERMON_SUPPORTS_MSIX_BAR
2357 * unmap 3rd BAR, MSIX BAR
2359 if (state
->hs_reg_msihdl
) {
2360 ddi_regs_map_free(&state
->hs_reg_msihdl
);
2361 state
->hs_reg_msihdl
= NULL
;
2365 case HERMON_DRV_CLEANUP_LEVEL1
:
2366 case HERMON_DRV_CLEANUP_LEVEL0
:
2368 * LEVEL1 and LEVEL0 resources are freed in
2369 * hermon_drv_fini2().
2374 HERMON_WARNING(state
, "unexpected driver cleanup level");
2381 * hermon_soft_state_init()
2382 * Context: Only called from attach() path context
2385 hermon_soft_state_init(hermon_state_t
*state
)
2387 ibt_hca_attr_t
*hca_attr
;
2388 uint64_t maxval
, val
;
2389 ibt_hca_flags_t caps
= IBT_HCA_NO_FLAGS
;
2390 ibt_hca_flags2_t caps2
= IBT_HCA2_NO_FLAGS
;
2392 int max_send_wqe_bytes
;
2393 int max_recv_wqe_bytes
;
2396 * The ibc_hca_info_t struct is passed to the IBTF. This is the
2397 * routine where we initialize it. Many of the init values come from
2398 * either configuration variables or successful queries of the Hermon
2399 * hardware abilities
2401 state
->hs_ibtfinfo
.hca_ci_vers
= IBCI_V4
;
2402 state
->hs_ibtfinfo
.hca_handle
= (ibc_hca_hdl_t
)state
;
2403 state
->hs_ibtfinfo
.hca_ops
= &hermon_ibc_ops
;
2405 hca_attr
= kmem_zalloc(sizeof (ibt_hca_attr_t
), KM_SLEEP
);
2406 state
->hs_ibtfinfo
.hca_attr
= hca_attr
;
2408 hca_attr
->hca_dip
= state
->hs_dip
;
2409 hca_attr
->hca_fw_major_version
= state
->hs_fw
.fw_rev_major
;
2410 hca_attr
->hca_fw_minor_version
= state
->hs_fw
.fw_rev_minor
;
2411 hca_attr
->hca_fw_micro_version
= state
->hs_fw
.fw_rev_subminor
;
2413 /* CQ interrupt moderation maximums - each limited to 16 bits */
2414 hca_attr
->hca_max_cq_mod_count
= 0xFFFF;
2415 hca_attr
->hca_max_cq_mod_usec
= 0xFFFF;
2416 hca_attr
->hca_max_cq_handlers
= state
->hs_intrmsi_allocd
;
2420 * Determine HCA capabilities:
2421 * No default support for IBT_HCA_RD, IBT_HCA_RAW_MULTICAST,
2422 * IBT_HCA_ATOMICS_GLOBAL, IBT_HCA_RESIZE_CHAN, IBT_HCA_INIT_TYPE,
2423 * or IBT_HCA_SHUTDOWN_PORT
2424 * But IBT_HCA_AH_PORT_CHECK, IBT_HCA_SQD_RTS_PORT, IBT_HCA_SI_GUID,
2425 * IBT_HCA_RNR_NAK, IBT_HCA_CURRENT_QP_STATE, IBT_HCA_PORT_UP,
2426 * IBT_HCA_SRQ, IBT_HCA_RESIZE_SRQ and IBT_HCA_FMR are always
2428 * All other features are conditionally supported, depending on the
2429 * status return by the Hermon HCA in QUERY_DEV_LIM.
2431 if (state
->hs_devlim
.ud_multi
) {
2432 caps
|= IBT_HCA_UD_MULTICAST
;
2434 if (state
->hs_devlim
.atomic
) {
2435 caps
|= IBT_HCA_ATOMICS_HCA
;
2437 if (state
->hs_devlim
.apm
) {
2438 caps
|= IBT_HCA_AUTO_PATH_MIG
;
2440 if (state
->hs_devlim
.pkey_v
) {
2441 caps
|= IBT_HCA_PKEY_CNTR
;
2443 if (state
->hs_devlim
.qkey_v
) {
2444 caps
|= IBT_HCA_QKEY_CNTR
;
2446 if (state
->hs_devlim
.ipoib_cksm
) {
2447 caps
|= IBT_HCA_CKSUM_FULL
;
2448 caps2
|= IBT_HCA2_IP_CLASS
;
2450 if (state
->hs_devlim
.mod_wr_srq
) {
2451 caps
|= IBT_HCA_RESIZE_SRQ
;
2453 if (state
->hs_devlim
.lif
) {
2454 caps
|= IBT_HCA_LOCAL_INVAL_FENCE
;
2456 if (state
->hs_devlim
.reserved_lkey
) {
2457 caps2
|= IBT_HCA2_RES_LKEY
;
2458 hca_attr
->hca_reserved_lkey
= state
->hs_devlim
.rsv_lkey
;
2460 if (state
->hs_devlim
.local_inv
&& state
->hs_devlim
.remote_inv
&&
2461 state
->hs_devlim
.fast_reg_wr
) { /* fw needs to be >= 2.7.000 */
2462 if ((state
->hs_fw
.fw_rev_major
> 2) ||
2463 ((state
->hs_fw
.fw_rev_major
== 2) &&
2464 (state
->hs_fw
.fw_rev_minor
>= 7)))
2465 caps2
|= IBT_HCA2_MEM_MGT_EXT
;
2467 if (state
->hs_devlim
.log_max_rss_tbl_sz
) {
2468 hca_attr
->hca_rss_max_log2_table
=
2469 state
->hs_devlim
.log_max_rss_tbl_sz
;
2470 if (state
->hs_devlim
.rss_xor
)
2471 caps2
|= IBT_HCA2_RSS_XOR_ALG
;
2472 if (state
->hs_devlim
.rss_toep
)
2473 caps2
|= IBT_HCA2_RSS_TPL_ALG
;
2475 if (state
->hs_devlim
.mps
) {
2476 caps
|= IBT_HCA_ZERO_BASED_VA
;
2478 if (state
->hs_devlim
.zb
) {
2479 caps
|= IBT_HCA_MULT_PAGE_SZ_MR
;
2481 caps
|= (IBT_HCA_AH_PORT_CHECK
| IBT_HCA_SQD_SQD_PORT
|
2482 IBT_HCA_SI_GUID
| IBT_HCA_RNR_NAK
| IBT_HCA_CURRENT_QP_STATE
|
2483 IBT_HCA_PORT_UP
| IBT_HCA_RC_SRQ
| IBT_HCA_UD_SRQ
| IBT_HCA_FMR
);
2484 caps2
|= IBT_HCA2_DMA_MR
;
2486 if (state
->hs_devlim
.log_max_gso_sz
) {
2487 hca_attr
->hca_max_lso_size
=
2488 (1 << state
->hs_devlim
.log_max_gso_sz
);
2489 /* 64 = ctrl & datagram seg, 4 = LSO seg, 16 = 1 SGL */
2490 hca_attr
->hca_max_lso_hdr_size
=
2491 state
->hs_devlim
.max_desc_sz_sq
- (64 + 4 + 16);
2494 caps
|= IBT_HCA_WQE_SIZE_INFO
;
2495 max_send_wqe_bytes
= state
->hs_devlim
.max_desc_sz_sq
;
2496 max_recv_wqe_bytes
= state
->hs_devlim
.max_desc_sz_rq
;
2497 hca_attr
->hca_ud_send_sgl_sz
= (max_send_wqe_bytes
/ 16) - 4;
2498 hca_attr
->hca_conn_send_sgl_sz
= (max_send_wqe_bytes
/ 16) - 1;
2499 hca_attr
->hca_conn_rdma_sgl_overhead
= 1;
2500 hca_attr
->hca_conn_rdma_write_sgl_sz
= (max_send_wqe_bytes
/ 16) - 2;
2501 hca_attr
->hca_conn_rdma_read_sgl_sz
= (512 / 16) - 2; /* see PRM */
2502 hca_attr
->hca_recv_sgl_sz
= max_recv_wqe_bytes
/ 16;
2504 /* We choose not to support "inline" unless it improves performance */
2505 hca_attr
->hca_max_inline_size
= 0;
2506 hca_attr
->hca_ud_send_inline_sz
= 0;
2507 hca_attr
->hca_conn_send_inline_sz
= 0;
2508 hca_attr
->hca_conn_rdmaw_inline_overhead
= 4;
2511 /* 32-bit kernels are too small for Fibre Channel over IB */
2512 if (state
->hs_devlim
.fcoib
&& (caps2
& IBT_HCA2_MEM_MGT_EXT
)) {
2513 caps2
|= IBT_HCA2_FC
;
2514 hca_attr
->hca_rfci_max_log2_qp
= 7; /* 128 per port */
2515 hca_attr
->hca_fexch_max_log2_qp
= 16; /* 64K per port */
2516 hca_attr
->hca_fexch_max_log2_mem
= 20; /* 1MB per MPT */
2520 hca_attr
->hca_flags
= caps
;
2521 hca_attr
->hca_flags2
= caps2
;
2524 * Set hca_attr's IDs
2526 hca_attr
->hca_vendor_id
= state
->hs_vendor_id
;
2527 hca_attr
->hca_device_id
= state
->hs_device_id
;
2528 hca_attr
->hca_version_id
= state
->hs_revision_id
;
2531 * Determine number of available QPs and max QP size. Number of
2532 * available QPs is determined by subtracting the number of
2533 * "reserved QPs" (i.e. reserved for firmware use) from the
2534 * total number configured.
2536 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_qp
);
2537 hca_attr
->hca_max_qp
= val
- ((uint64_t)1 <<
2538 state
->hs_devlim
.log_rsvd_qp
);
2539 maxval
= ((uint64_t)1 << state
->hs_devlim
.log_max_qp_sz
);
2540 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_max_qp_sz
);
2542 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2543 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2544 "soft_state_init_maxqpsz_toobig_fail");
2545 return (DDI_FAILURE
);
2547 /* we need to reduce this by the max space needed for headroom */
2548 hca_attr
->hca_max_qp_sz
= (uint_t
)val
- (HERMON_QP_OH_SIZE
>>
2549 HERMON_QP_WQE_LOG_MINIMUM
) - 1;
2552 * Determine max scatter-gather size in WQEs. The HCA has split
2553 * the max sgl into rec'v Q and send Q values. Use the least.
2555 * This is mainly useful for legacy clients. Smart clients
2556 * such as IPoIB will use the IBT_HCA_WQE_SIZE_INFO sgl info.
2558 if (state
->hs_devlim
.max_sg_rq
<= state
->hs_devlim
.max_sg_sq
) {
2559 maxval
= state
->hs_devlim
.max_sg_rq
;
2561 maxval
= state
->hs_devlim
.max_sg_sq
;
2563 val
= state
->hs_cfg_profile
->cp_wqe_max_sgl
;
2565 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2566 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2567 "soft_state_init_toomanysgl_fail");
2568 return (DDI_FAILURE
);
2570 /* If the rounded value for max SGL is too large, cap it */
2571 if (state
->hs_cfg_profile
->cp_wqe_real_max_sgl
> maxval
) {
2572 state
->hs_cfg_profile
->cp_wqe_real_max_sgl
= (uint32_t)maxval
;
2575 val
= state
->hs_cfg_profile
->cp_wqe_real_max_sgl
;
2578 hca_attr
->hca_max_sgl
= (uint_t
)val
;
2579 hca_attr
->hca_max_rd_sgl
= 0; /* zero because RD is unsupported */
2582 * Determine number of available CQs and max CQ size. Number of
2583 * available CQs is determined by subtracting the number of
2584 * "reserved CQs" (i.e. reserved for firmware use) from the
2585 * total number configured.
2587 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_cq
);
2588 hca_attr
->hca_max_cq
= val
- ((uint64_t)1 <<
2589 state
->hs_devlim
.log_rsvd_cq
);
2590 maxval
= ((uint64_t)1 << state
->hs_devlim
.log_max_cq_sz
);
2591 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_max_cq_sz
) - 1;
2593 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2594 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2595 "soft_state_init_maxcqsz_toobig_fail");
2596 return (DDI_FAILURE
);
2598 hca_attr
->hca_max_cq_sz
= (uint_t
)val
;
2601 * Determine number of available SRQs and max SRQ size. Number of
2602 * available SRQs is determined by subtracting the number of
2603 * "reserved SRQs" (i.e. reserved for firmware use) from the
2604 * total number configured.
2606 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_srq
);
2607 hca_attr
->hca_max_srqs
= val
- ((uint64_t)1 <<
2608 state
->hs_devlim
.log_rsvd_srq
);
2609 maxval
= ((uint64_t)1 << state
->hs_devlim
.log_max_srq_sz
);
2610 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_max_srq_sz
);
2613 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2614 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2615 "soft_state_init_maxsrqsz_toobig_fail");
2616 return (DDI_FAILURE
);
2618 hca_attr
->hca_max_srqs_sz
= (uint_t
)val
;
2620 val
= hca_attr
->hca_recv_sgl_sz
- 1; /* SRQ has a list link */
2621 maxval
= state
->hs_devlim
.max_sg_rq
- 1;
2623 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2624 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2625 "soft_state_init_toomanysrqsgl_fail");
2626 return (DDI_FAILURE
);
2628 hca_attr
->hca_max_srq_sgl
= (uint_t
)val
;
2631 * Determine supported HCA page sizes
2633 * For now we simply return the system pagesize as the only supported
2636 hca_attr
->hca_page_sz
= ((PAGESIZE
== (1 << 13)) ? IBT_PAGE_8K
:
2640 * Determine number of available MemReg, MemWin, and their max size.
2641 * Number of available MRs and MWs is determined by subtracting
2642 * the number of "reserved MPTs" (i.e. reserved for firmware use)
2643 * from the total number configured for each.
2645 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_dmpt
);
2646 hca_attr
->hca_max_memr
= val
- ((uint64_t)1 <<
2647 state
->hs_devlim
.log_rsvd_dmpt
);
2648 hca_attr
->hca_max_mem_win
= state
->hs_devlim
.mem_win
? (val
-
2649 ((uint64_t)1 << state
->hs_devlim
.log_rsvd_dmpt
)) : 0;
2650 maxval
= state
->hs_devlim
.log_max_mrw_sz
;
2651 val
= state
->hs_cfg_profile
->cp_log_max_mrw_sz
;
2653 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2654 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2655 "soft_state_init_maxmrwsz_toobig_fail");
2656 return (DDI_FAILURE
);
2658 hca_attr
->hca_max_memr_len
= ((uint64_t)1 << val
);
2660 /* Determine RDMA/Atomic properties */
2661 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_rdb
);
2662 hca_attr
->hca_max_rsc
= (uint_t
)val
;
2663 val
= state
->hs_cfg_profile
->cp_hca_max_rdma_in_qp
;
2664 hca_attr
->hca_max_rdma_in_qp
= (uint8_t)val
;
2665 val
= state
->hs_cfg_profile
->cp_hca_max_rdma_out_qp
;
2666 hca_attr
->hca_max_rdma_out_qp
= (uint8_t)val
;
2667 hca_attr
->hca_max_rdma_in_ee
= 0;
2668 hca_attr
->hca_max_rdma_out_ee
= 0;
2671 * Determine maximum number of raw IPv6 and Ether QPs. Set to 0
2672 * because neither type of raw QP is supported
2674 hca_attr
->hca_max_ipv6_qp
= 0;
2675 hca_attr
->hca_max_ether_qp
= 0;
2677 /* Determine max number of MCGs and max QP-per-MCG */
2678 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_qp
);
2679 hca_attr
->hca_max_mcg_qps
= (uint_t
)val
;
2680 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_mcg
);
2681 hca_attr
->hca_max_mcg
= (uint_t
)val
;
2682 val
= state
->hs_cfg_profile
->cp_num_qp_per_mcg
;
2683 hca_attr
->hca_max_qp_per_mcg
= (uint_t
)val
;
2685 /* Determine max number partitions (i.e. PKeys) */
2686 maxval
= ((uint64_t)state
->hs_cfg_profile
->cp_num_ports
<<
2687 state
->hs_queryport
.log_max_pkey
);
2688 val
= ((uint64_t)state
->hs_cfg_profile
->cp_num_ports
<<
2689 state
->hs_cfg_profile
->cp_log_max_pkeytbl
);
2692 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2693 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2694 "soft_state_init_toomanypkey_fail");
2695 return (DDI_FAILURE
);
2697 hca_attr
->hca_max_partitions
= (uint16_t)val
;
2699 /* Determine number of ports */
2700 maxval
= state
->hs_devlim
.num_ports
;
2701 val
= state
->hs_cfg_profile
->cp_num_ports
;
2702 if ((val
> maxval
) || (val
== 0)) {
2703 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2704 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2705 "soft_state_init_toomanyports_fail");
2706 return (DDI_FAILURE
);
2708 hca_attr
->hca_nports
= (uint8_t)val
;
2710 /* Copy NodeGUID and SystemImageGUID from softstate */
2711 hca_attr
->hca_node_guid
= state
->hs_nodeguid
;
2712 hca_attr
->hca_si_guid
= state
->hs_sysimgguid
;
2715 * Determine local ACK delay. Use the value suggested by the Hermon
2716 * hardware (from the QUERY_DEV_CAP command)
2718 hca_attr
->hca_local_ack_delay
= state
->hs_devlim
.ca_ack_delay
;
2720 /* Determine max SGID table and PKey table sizes */
2721 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_max_gidtbl
);
2722 hca_attr
->hca_max_port_sgid_tbl_sz
= (uint_t
)val
;
2723 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_max_pkeytbl
);
2724 hca_attr
->hca_max_port_pkey_tbl_sz
= (uint16_t)val
;
2726 /* Determine max number of PDs */
2727 maxval
= ((uint64_t)1 << state
->hs_devlim
.log_max_pd
);
2728 val
= ((uint64_t)1 << state
->hs_cfg_profile
->cp_log_num_pd
);
2730 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2731 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2732 "soft_state_init_toomanypd_fail");
2733 return (DDI_FAILURE
);
2735 hca_attr
->hca_max_pd
= (uint_t
)val
;
2737 /* Determine max number of Address Handles (NOT IN ARBEL or HERMON) */
2738 hca_attr
->hca_max_ah
= 0;
2740 /* No RDDs or EECs (since Reliable Datagram is not supported) */
2741 hca_attr
->hca_max_rdd
= 0;
2742 hca_attr
->hca_max_eec
= 0;
2744 /* Initialize lock for reserved UAR page access */
2745 mutex_init(&state
->hs_uar_lock
, NULL
, MUTEX_DRIVER
,
2746 DDI_INTR_PRI(state
->hs_intrmsi_pri
));
2748 /* Initialize the flash fields */
2749 state
->hs_fw_flashstarted
= 0;
2750 mutex_init(&state
->hs_fw_flashlock
, NULL
, MUTEX_DRIVER
,
2751 DDI_INTR_PRI(state
->hs_intrmsi_pri
));
2753 /* Initialize the lock for the info ioctl */
2754 mutex_init(&state
->hs_info_lock
, NULL
, MUTEX_DRIVER
,
2755 DDI_INTR_PRI(state
->hs_intrmsi_pri
));
2757 /* Initialize the AVL tree for QP number support */
2758 hermon_qpn_avl_init(state
);
2760 /* Initialize the cq_sched info structure */
2761 status
= hermon_cq_sched_init(state
);
2762 if (status
!= DDI_SUCCESS
) {
2763 hermon_qpn_avl_fini(state
);
2764 mutex_destroy(&state
->hs_info_lock
);
2765 mutex_destroy(&state
->hs_fw_flashlock
);
2766 mutex_destroy(&state
->hs_uar_lock
);
2767 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2768 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2769 "soft_state_init_cqsched_init_fail");
2770 return (DDI_FAILURE
);
2773 /* Initialize the fcoib info structure */
2774 status
= hermon_fcoib_init(state
);
2775 if (status
!= DDI_SUCCESS
) {
2776 hermon_cq_sched_fini(state
);
2777 hermon_qpn_avl_fini(state
);
2778 mutex_destroy(&state
->hs_info_lock
);
2779 mutex_destroy(&state
->hs_fw_flashlock
);
2780 mutex_destroy(&state
->hs_uar_lock
);
2781 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2782 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2783 "soft_state_init_fcoibinit_fail");
2784 return (DDI_FAILURE
);
2787 /* Initialize the kstat info structure */
2788 status
= hermon_kstat_init(state
);
2789 if (status
!= DDI_SUCCESS
) {
2790 hermon_fcoib_fini(state
);
2791 hermon_cq_sched_fini(state
);
2792 hermon_qpn_avl_fini(state
);
2793 mutex_destroy(&state
->hs_info_lock
);
2794 mutex_destroy(&state
->hs_fw_flashlock
);
2795 mutex_destroy(&state
->hs_uar_lock
);
2796 kmem_free(hca_attr
, sizeof (ibt_hca_attr_t
));
2797 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2798 "soft_state_init_kstatinit_fail");
2799 return (DDI_FAILURE
);
2802 return (DDI_SUCCESS
);
2807 * hermon_soft_state_fini()
2808 * Context: Called only from detach() path context
2811 hermon_soft_state_fini(hermon_state_t
*state
)
2814 /* Teardown the kstat info */
2815 hermon_kstat_fini(state
);
2817 /* Teardown the fcoib info */
2818 hermon_fcoib_fini(state
);
2820 /* Teardown the cq_sched info */
2821 hermon_cq_sched_fini(state
);
2823 /* Teardown the AVL tree for QP number support */
2824 hermon_qpn_avl_fini(state
);
2826 /* Free up info ioctl mutex */
2827 mutex_destroy(&state
->hs_info_lock
);
2829 /* Free up flash mutex */
2830 mutex_destroy(&state
->hs_fw_flashlock
);
2832 /* Free up the UAR page access mutex */
2833 mutex_destroy(&state
->hs_uar_lock
);
2835 /* Free up the hca_attr struct */
2836 kmem_free(state
->hs_ibtfinfo
.hca_attr
, sizeof (ibt_hca_attr_t
));
2841 * hermon_icm_config_setup()
2842 * Context: Only called from attach() path context
2845 hermon_icm_config_setup(hermon_state_t
*state
,
2846 hermon_hw_initqueryhca_t
*inithca
)
2848 hermon_hw_querydevlim_t
*devlim
;
2849 hermon_cfg_profile_t
*cfg
;
2850 hermon_icm_table_t
*icm_p
[HERMON_NUM_ICM_RESOURCES
];
2851 hermon_icm_table_t
*icm
;
2852 hermon_icm_table_t
*tmp
;
2858 /* Bring in local devlims, cfg_profile and hs_icm table list */
2859 devlim
= &state
->hs_devlim
;
2860 cfg
= state
->hs_cfg_profile
;
2861 icm
= state
->hs_icm
;
2864 * Assign each ICM table's entry size from data in the devlims,
2865 * except for RDB and MCG sizes, which are not returned in devlims
2866 * but do have a fixed size, and the UAR context entry size, which
2867 * we determine. For this, we use the "cp_num_pgs_per_uce" value
2868 * from our hs_cfg_profile.
2870 icm
[HERMON_CMPT
].object_size
= devlim
->cmpt_entry_sz
;
2871 icm
[HERMON_CMPT_QPC
].object_size
= devlim
->cmpt_entry_sz
;
2872 icm
[HERMON_CMPT_SRQC
].object_size
= devlim
->cmpt_entry_sz
;
2873 icm
[HERMON_CMPT_CQC
].object_size
= devlim
->cmpt_entry_sz
;
2874 icm
[HERMON_CMPT_EQC
].object_size
= devlim
->cmpt_entry_sz
;
2875 icm
[HERMON_MTT
].object_size
= devlim
->mtt_entry_sz
;
2876 icm
[HERMON_DMPT
].object_size
= devlim
->dmpt_entry_sz
;
2877 icm
[HERMON_QPC
].object_size
= devlim
->qpc_entry_sz
;
2878 icm
[HERMON_CQC
].object_size
= devlim
->cqc_entry_sz
;
2879 icm
[HERMON_SRQC
].object_size
= devlim
->srq_entry_sz
;
2880 icm
[HERMON_EQC
].object_size
= devlim
->eqc_entry_sz
;
2881 icm
[HERMON_RDB
].object_size
= devlim
->rdmardc_entry_sz
*
2882 cfg
->cp_hca_max_rdma_in_qp
;
2883 icm
[HERMON_MCG
].object_size
= HERMON_MCGMEM_SZ(state
);
2884 icm
[HERMON_ALTC
].object_size
= devlim
->altc_entry_sz
;
2885 icm
[HERMON_AUXC
].object_size
= devlim
->aux_entry_sz
;
2887 /* Assign each ICM table's log2 number of entries */
2888 icm
[HERMON_CMPT
].log_num_entries
= cfg
->cp_log_num_cmpt
;
2889 icm
[HERMON_CMPT_QPC
].log_num_entries
= cfg
->cp_log_num_qp
;
2890 icm
[HERMON_CMPT_SRQC
].log_num_entries
= cfg
->cp_log_num_srq
;
2891 icm
[HERMON_CMPT_CQC
].log_num_entries
= cfg
->cp_log_num_cq
;
2892 icm
[HERMON_CMPT_EQC
].log_num_entries
= HERMON_NUM_EQ_SHIFT
;
2893 icm
[HERMON_MTT
].log_num_entries
= cfg
->cp_log_num_mtt
;
2894 icm
[HERMON_DMPT
].log_num_entries
= cfg
->cp_log_num_dmpt
;
2895 icm
[HERMON_QPC
].log_num_entries
= cfg
->cp_log_num_qp
;
2896 icm
[HERMON_SRQC
].log_num_entries
= cfg
->cp_log_num_srq
;
2897 icm
[HERMON_CQC
].log_num_entries
= cfg
->cp_log_num_cq
;
2898 icm
[HERMON_EQC
].log_num_entries
= HERMON_NUM_EQ_SHIFT
;
2899 icm
[HERMON_RDB
].log_num_entries
= cfg
->cp_log_num_qp
;
2900 icm
[HERMON_MCG
].log_num_entries
= cfg
->cp_log_num_mcg
;
2901 icm
[HERMON_ALTC
].log_num_entries
= cfg
->cp_log_num_qp
;
2902 icm
[HERMON_AUXC
].log_num_entries
= cfg
->cp_log_num_qp
;
2904 /* Initialize the ICM tables */
2905 hermon_icm_tables_init(state
);
2908 * ICM tables must be aligned on their size in the ICM address
2909 * space. So, here we order the tables from largest total table
2910 * size to the smallest. All tables are a power of 2 in size, so
2911 * this will ensure that all tables are aligned on their own size
2912 * without wasting space in the ICM.
2914 * In order to easily set the ICM addresses without needing to
2915 * worry about the ordering of our table indices as relates to
2916 * the hermon_rsrc_type_t enum, we will use a list of pointers
2917 * representing the tables for the sort, then assign ICM addresses
2920 for (i
= 0; i
< HERMON_NUM_ICM_RESOURCES
; i
++) {
2923 for (i
= HERMON_NUM_ICM_RESOURCES
; i
> 0; i
--) {
2925 case HERMON_CMPT_QPC
:
2926 case HERMON_CMPT_SRQC
:
2927 case HERMON_CMPT_CQC
:
2928 case HERMON_CMPT_EQC
:
2931 for (j
= 1; j
< i
; j
++) {
2932 if (icm_p
[j
]->table_size
> icm_p
[j
- 1]->table_size
) {
2934 icm_p
[j
] = icm_p
[j
- 1];
2940 /* Initialize the ICM address and ICM size */
2941 icm_addr
= icm_size
= 0;
2944 * Set the ICM base address of each table, using our sorted
2945 * list of pointers from above.
2947 for (i
= 0; i
< HERMON_NUM_ICM_RESOURCES
; i
++) {
2948 j
= icm_p
[i
]->icm_type
;
2950 case HERMON_CMPT_QPC
:
2951 case HERMON_CMPT_SRQC
:
2952 case HERMON_CMPT_CQC
:
2953 case HERMON_CMPT_EQC
:
2956 if (icm
[j
].table_size
) {
2958 * Set the ICM base address in the table, save the
2959 * ICM offset in the rsrc pool and increment the
2960 * total ICM allocation.
2962 icm
[j
].icm_baseaddr
= icm_addr
;
2963 if (hermon_verbose
) {
2964 IBTF_DPRINTF_L2("ICMADDR", "rsrc %x @ %p"
2965 " size %llx", j
, icm
[j
].icm_baseaddr
,
2968 icm_size
+= icm
[j
].table_size
;
2971 /* Verify that we don't exceed maximum ICM size */
2972 if (icm_size
> devlim
->max_icm_size
) {
2973 /* free the ICM table memory resources */
2974 hermon_icm_tables_fini(state
);
2975 cmn_err(CE_WARN
, "ICM configuration exceeds maximum "
2976 "configuration: max (0x%lx) requested (0x%lx)\n",
2977 (ulong_t
)devlim
->max_icm_size
, (ulong_t
)icm_size
);
2978 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
2979 "icm_config_toobig_fail");
2980 return (DDI_FAILURE
);
2983 /* assign address to the 4 pieces of the CMPT */
2984 if (j
== HERMON_CMPT
) {
2985 uint64_t cmpt_size
= icm
[j
].table_size
>> 2;
2986 #define init_cmpt_icm_baseaddr(rsrc, indx) \
2987 icm[rsrc].icm_baseaddr = icm_addr + (indx * cmpt_size);
2988 init_cmpt_icm_baseaddr(HERMON_CMPT_QPC
, 0);
2989 init_cmpt_icm_baseaddr(HERMON_CMPT_SRQC
, 1);
2990 init_cmpt_icm_baseaddr(HERMON_CMPT_CQC
, 2);
2991 init_cmpt_icm_baseaddr(HERMON_CMPT_EQC
, 3);
2994 /* Increment the ICM address for the next table */
2995 icm_addr
+= icm
[j
].table_size
;
2998 /* Populate the structure for the INIT_HCA command */
2999 hermon_inithca_set(state
, inithca
);
3002 * Prior to invoking INIT_HCA, we must have ICM memory in place
3003 * for the reserved objects in each table. We will allocate and map
3004 * this initial ICM memory here. Note that given the assignment
3005 * of span_size above, tables that are smaller or equal in total
3006 * size to the default span_size will be mapped in full.
3008 status
= hermon_icm_dma_init(state
);
3009 if (status
!= DDI_SUCCESS
) {
3010 /* free the ICM table memory resources */
3011 hermon_icm_tables_fini(state
);
3012 HERMON_WARNING(state
, "Failed to allocate initial ICM");
3013 HERMON_ATTACH_MSG(state
->hs_attach_buf
,
3014 "icm_config_dma_init_fail");
3015 return (DDI_FAILURE
);
3018 return (DDI_SUCCESS
);
3022 * hermon_inithca_set()
3023 * Context: Only called from attach() path context
3026 hermon_inithca_set(hermon_state_t
*state
, hermon_hw_initqueryhca_t
*inithca
)
3028 hermon_cfg_profile_t
*cfg
;
3029 hermon_icm_table_t
*icm
;
3033 /* Populate the INIT_HCA structure */
3034 icm
= state
->hs_icm
;
3035 cfg
= state
->hs_cfg_profile
;
3038 inithca
->version
= 0x02; /* PRM 0.36 */
3039 /* set cacheline - log2 in 16-byte chunks */
3040 inithca
->log2_cacheline
= 0x2; /* optimized for 64 byte cache */
3042 /* we need to update the inithca info with thie UAR info too */
3043 inithca
->uar
.log_max_uars
= highbit(cfg
->cp_log_num_uar
);
3044 inithca
->uar
.uar_pg_sz
= PAGESHIFT
- HERMON_PAGESHIFT
;
3047 #ifdef _LITTLE_ENDIAN
3048 inithca
->big_endian
= 0;
3050 inithca
->big_endian
= 1;
3053 /* Port Checking is on by default */
3054 inithca
->udav_port_chk
= HERMON_UDAV_PORTCHK_ENABLED
;
3056 /* Enable IPoIB checksum */
3057 if (state
->hs_devlim
.ipoib_cksm
)
3058 inithca
->chsum_en
= 1;
3060 /* Set each ICM table's attributes */
3061 for (i
= 0; i
< HERMON_NUM_ICM_RESOURCES
; i
++) {
3062 switch (icm
[i
].icm_type
) {
3064 inithca
->tpt
.cmpt_baseaddr
= icm
[i
].icm_baseaddr
;
3068 inithca
->tpt
.mtt_baseaddr
= icm
[i
].icm_baseaddr
;
3072 inithca
->tpt
.dmpt_baseaddr
= icm
[i
].icm_baseaddr
;
3073 inithca
->tpt
.log_dmpt_sz
= icm
[i
].log_num_entries
;
3074 inithca
->tpt
.pgfault_rnr_to
= 0; /* just in case */
3078 inithca
->context
.log_num_qp
= icm
[i
].log_num_entries
;
3079 inithca
->context
.qpc_baseaddr_h
=
3080 icm
[i
].icm_baseaddr
>> 32;
3081 inithca
->context
.qpc_baseaddr_l
=
3082 (icm
[i
].icm_baseaddr
& 0xFFFFFFFF) >> 5;
3086 inithca
->context
.log_num_cq
= icm
[i
].log_num_entries
;
3087 inithca
->context
.cqc_baseaddr_h
=
3088 icm
[i
].icm_baseaddr
>> 32;
3089 inithca
->context
.cqc_baseaddr_l
=
3090 (icm
[i
].icm_baseaddr
& 0xFFFFFFFF) >> 5;
3094 inithca
->context
.log_num_srq
= icm
[i
].log_num_entries
;
3095 inithca
->context
.srqc_baseaddr_h
=
3096 icm
[i
].icm_baseaddr
>> 32;
3097 inithca
->context
.srqc_baseaddr_l
=
3098 (icm
[i
].icm_baseaddr
& 0xFFFFFFFF) >> 5;
3102 inithca
->context
.log_num_eq
= icm
[i
].log_num_entries
;
3103 inithca
->context
.eqc_baseaddr_h
=
3104 icm
[i
].icm_baseaddr
>> 32;
3105 inithca
->context
.eqc_baseaddr_l
=
3106 (icm
[i
].icm_baseaddr
& 0xFFFFFFFF) >> 5;
3110 inithca
->context
.rdmardc_baseaddr_h
=
3111 icm
[i
].icm_baseaddr
>> 32;
3112 inithca
->context
.rdmardc_baseaddr_l
=
3113 (icm
[i
].icm_baseaddr
& 0xFFFFFFFF) >> 5;
3114 inithca
->context
.log_num_rdmardc
=
3115 cfg
->cp_log_num_rdb
- cfg
->cp_log_num_qp
;
3119 inithca
->multi
.mc_baseaddr
= icm
[i
].icm_baseaddr
;
3120 inithca
->multi
.log_mc_tbl_sz
= icm
[i
].log_num_entries
;
3121 inithca
->multi
.log_mc_tbl_ent
=
3122 highbit(HERMON_MCGMEM_SZ(state
)) - 1;
3123 inithca
->multi
.log_mc_tbl_hash_sz
=
3124 cfg
->cp_log_num_mcg_hash
;
3125 inithca
->multi
.mc_hash_fn
= HERMON_MCG_DEFAULT_HASH_FN
;
3129 inithca
->context
.altc_baseaddr
= icm
[i
].icm_baseaddr
;
3133 inithca
->context
.auxc_baseaddr
= icm
[i
].icm_baseaddr
;
3145 * hermon_icm_tables_init()
3146 * Context: Only called from attach() path context
3148 * Dynamic ICM breaks the various ICM tables into "span_size" chunks
3149 * to enable allocation of backing memory on demand. Arbel used a
3150 * fixed size ARBEL_ICM_SPAN_SIZE (initially was 512KB) as the
3151 * span_size for all ICM chunks. Hermon has other considerations,
3152 * so the span_size used differs from Arbel.
3154 * The basic considerations for why Hermon differs are:
3156 * 1) ICM memory is in units of HERMON pages.
3158 * 2) The AUXC table is approximately 1 byte per QP.
3160 * 3) ICM memory for AUXC, ALTC, and RDB is allocated when
3161 * the ICM memory for the corresponding QPC is allocated.
3163 * 4) ICM memory for the CMPT corresponding to the various primary
3164 * resources (QPC, SRQC, CQC, and EQC) is allocated when the ICM
3165 * memory for the primary resource is allocated.
3167 * One HERMON page (4KB) would typically map 4K QPs worth of AUXC.
3168 * So, the minimum chunk for the various QPC related ICM memory should
3169 * all be allocated to support the 4K QPs. Currently, this means the
3170 * amount of memory for the various QP chunks is:
3178 * The span_size chosen for the QP resource is 4KB of AUXC entries,
3179 * or 1 HERMON_PAGESIZE worth, which is the minimum ICM mapping size.
3181 * Other ICM resources can have their span_size be more arbitrary.
3182 * This is 4K (HERMON_ICM_SPAN), except for MTTs because they are tiny.
3185 /* macro to make the code below cleaner */
3186 #define init_dependent(rsrc, dep) \
3187 icm[dep].span = icm[rsrc].span; \
3188 icm[dep].num_spans = icm[rsrc].num_spans; \
3189 icm[dep].split_shift = icm[rsrc].split_shift; \
3190 icm[dep].span_mask = icm[rsrc].span_mask; \
3191 icm[dep].span_shift = icm[rsrc].span_shift; \
3192 icm[dep].rsrc_mask = icm[rsrc].rsrc_mask; \
3193 if (hermon_verbose) { \
3194 IBTF_DPRINTF_L2("hermon", "tables_init: " \
3195 "rsrc (0x%x) size (0x%lx) span (0x%x) " \
3196 "num_spans (0x%x)", dep, icm[dep].table_size, \
3197 icm[dep].span, icm[dep].num_spans); \
3198 IBTF_DPRINTF_L2("hermon", "tables_init: " \
3199 "span_shift (0x%x) split_shift (0x%x)", \
3200 icm[dep].span_shift, icm[dep].split_shift); \
3201 IBTF_DPRINTF_L2("hermon", "tables_init: " \
3202 "span_mask (0x%x) rsrc_mask (0x%x)", \
3203 icm[dep].span_mask, icm[dep].rsrc_mask); \
3207 hermon_icm_tables_init(hermon_state_t
*state
)
3209 hermon_icm_table_t
*icm
;
3214 icm
= state
->hs_icm
;
3216 for (i
= 0; i
< HERMON_NUM_ICM_RESOURCES
; i
++) {
3217 icm
[i
].icm_type
= i
;
3218 icm
[i
].num_entries
= 1 << icm
[i
].log_num_entries
;
3219 icm
[i
].log_object_size
= highbit(icm
[i
].object_size
) - 1;
3220 icm
[i
].table_size
= icm
[i
].num_entries
<<
3221 icm
[i
].log_object_size
;
3223 /* deal with "dependent" resource types */
3226 #ifdef HERMON_FW_WORKAROUND
3227 icm
[i
].table_size
= 0x80000000ull
;
3230 case HERMON_CMPT_QPC
:
3233 init_dependent(HERMON_QPC
, i
);
3235 case HERMON_CMPT_SRQC
:
3236 init_dependent(HERMON_SRQC
, i
);
3238 case HERMON_CMPT_CQC
:
3239 init_dependent(HERMON_CQC
, i
);
3241 case HERMON_CMPT_EQC
:
3242 init_dependent(HERMON_EQC
, i
);
3246 icm
[i
].span
= HERMON_ICM_SPAN
; /* default #rsrc's in 1 span */
3247 if (i
== HERMON_MTT
) /* Alloc enough MTTs to map 256MB */
3248 icm
[i
].span
= HERMON_ICM_SPAN
* 16;
3249 icm
[i
].num_spans
= icm
[i
].num_entries
/ icm
[i
].span
;
3250 if (icm
[i
].num_spans
== 0) {
3251 icm
[i
].span
= icm
[i
].num_entries
;
3253 icm
[i
].num_spans
= icm
[i
].num_entries
/ icm
[i
].span
;
3255 per_split
= icm
[i
].num_spans
/ HERMON_ICM_SPLIT
;
3256 if (per_split
== 0) {
3261 IBTF_DPRINTF_L2("ICM", "rsrc %x span %x num_spans %x",
3262 i
, icm
[i
].span
, icm
[i
].num_spans
);
3265 * Ensure a minimum table size of an ICM page, and a
3266 * maximum span size of the ICM table size. This ensures
3267 * that we don't have less than an ICM page to map, which is
3268 * impossible, and that we will map an entire table at
3269 * once if it's total size is less than the span size.
3271 icm
[i
].table_size
= max(icm
[i
].table_size
, HERMON_PAGESIZE
);
3273 icm
[i
].span_shift
= 0;
3274 for (k
= icm
[i
].span
; k
!= 1; k
>>= 1)
3275 icm
[i
].span_shift
++;
3276 icm
[i
].split_shift
= icm
[i
].span_shift
;
3277 for (k
= per_split
; k
!= 1; k
>>= 1)
3278 icm
[i
].split_shift
++;
3279 icm
[i
].span_mask
= (1 << icm
[i
].split_shift
) -
3280 (1 << icm
[i
].span_shift
);
3281 icm
[i
].rsrc_mask
= (1 << icm
[i
].span_shift
) - 1;
3284 /* Initialize the table lock */
3285 mutex_init(&icm
[i
].icm_table_lock
, NULL
, MUTEX_DRIVER
,
3286 DDI_INTR_PRI(state
->hs_intrmsi_pri
));
3287 cv_init(&icm
[i
].icm_table_cv
, NULL
, CV_DRIVER
, NULL
);
3289 if (hermon_verbose
) {
3290 IBTF_DPRINTF_L2("hermon", "tables_init: "
3291 "rsrc (0x%x) size (0x%lx)", i
, icm
[i
].table_size
);
3292 IBTF_DPRINTF_L2("hermon", "tables_init: "
3293 "span (0x%x) num_spans (0x%x)",
3294 icm
[i
].span
, icm
[i
].num_spans
);
3295 IBTF_DPRINTF_L2("hermon", "tables_init: "
3296 "span_shift (0x%x) split_shift (0x%x)",
3297 icm
[i
].span_shift
, icm
[i
].split_shift
);
3298 IBTF_DPRINTF_L2("hermon", "tables_init: "
3299 "span_mask (0x%x) rsrc_mask (0x%x)",
3300 icm
[i
].span_mask
, icm
[i
].rsrc_mask
);
3307 * hermon_icm_tables_fini()
3308 * Context: Only called from attach() path context
3310 * Clean up all icm_tables. Free the bitmap and dma_info arrays.
3313 hermon_icm_tables_fini(hermon_state_t
*state
)
3315 hermon_icm_table_t
*icm
;
3320 icm
= state
->hs_icm
;
3322 for (i
= 0; i
< HERMON_NUM_ICM_RESOURCES
; i
++) {
3324 mutex_enter(&icm
[i
].icm_table_lock
);
3325 nspans
= icm
[i
].num_spans
;
3327 for (j
= 0; j
< HERMON_ICM_SPLIT
; j
++) {
3328 if (icm
[i
].icm_dma
[j
])
3329 /* Free the ICM DMA slots */
3330 kmem_free(icm
[i
].icm_dma
[j
],
3331 nspans
* sizeof (hermon_dma_info_t
));
3333 if (icm
[i
].icm_bitmap
[j
])
3334 /* Free the table bitmap */
3335 kmem_free(icm
[i
].icm_bitmap
[j
],
3338 /* Destroy the table lock */
3339 cv_destroy(&icm
[i
].icm_table_cv
);
3340 mutex_exit(&icm
[i
].icm_table_lock
);
3341 mutex_destroy(&icm
[i
].icm_table_lock
);
3347 * hermon_icm_dma_init()
3348 * Context: Only called from attach() path context
3351 hermon_icm_dma_init(hermon_state_t
*state
)
3353 hermon_icm_table_t
*icm
;
3354 hermon_rsrc_type_t type
;
3359 * This routine will allocate initial ICM DMA resources for ICM
3360 * tables that have reserved ICM objects. This is the only routine
3361 * where we should have to allocate ICM outside of hermon_rsrc_alloc().
3362 * We need to allocate ICM here explicitly, rather than in
3363 * hermon_rsrc_alloc(), because we've not yet completed the resource
3364 * pool initialization. When the resource pools are initialized
3365 * (in hermon_rsrc_init_phase2(), see hermon_rsrc.c for more
3366 * information), resource preallocations will be invoked to match
3367 * the ICM allocations seen here. We will then be able to use the
3368 * normal allocation path. Note we don't need to set a refcnt on
3369 * these initial allocations because that will be done in the calls
3370 * to hermon_rsrc_alloc() from hermon_hw_entries_init() for the
3371 * "prealloc" objects (see hermon_rsrc.c for more information).
3373 for (type
= 0; type
< HERMON_NUM_ICM_RESOURCES
; type
++) {
3375 /* ICM for these is allocated within hermon_icm_alloc() */
3378 case HERMON_CMPT_QPC
:
3379 case HERMON_CMPT_SRQC
:
3380 case HERMON_CMPT_CQC
:
3381 case HERMON_CMPT_EQC
:
3388 icm
= &state
->hs_icm
[type
];
3390 mutex_enter(&icm
->icm_table_lock
);
3391 status
= hermon_icm_alloc(state
, type
, 0, 0);
3392 mutex_exit(&icm
->icm_table_lock
);
3393 if (status
!= DDI_SUCCESS
) {
3395 icm
= &state
->hs_icm
[type
];
3396 mutex_enter(&icm
->icm_table_lock
);
3397 hermon_icm_free(state
, type
, 0, 0);
3398 mutex_exit(&icm
->icm_table_lock
);
3400 return (DDI_FAILURE
);
3403 if (hermon_verbose
) {
3404 IBTF_DPRINTF_L2("hermon", "hermon_icm_dma_init: "
3405 "table (0x%x) index (0x%x) allocated", type
, 0);
3409 return (DDI_SUCCESS
);
3413 * hermon_icm_dma_fini()
3414 * Context: Only called from attach() path context
3416 * ICM has been completely unmapped. We just free the memory here.
3419 hermon_icm_dma_fini(hermon_state_t
*state
)
3421 hermon_icm_table_t
*icm
;
3422 hermon_dma_info_t
*dma_info
;
3423 hermon_rsrc_type_t type
;
3427 for (type
= 0; type
< HERMON_NUM_ICM_RESOURCES
; type
++) {
3428 icm
= &state
->hs_icm
[type
];
3429 for (index1
= 0; index1
< HERMON_ICM_SPLIT
; index1
++) {
3430 dma_info
= icm
->icm_dma
[index1
];
3431 if (dma_info
== NULL
)
3433 for (index2
= 0; index2
< icm
->num_spans
; index2
++) {
3434 if (dma_info
[index2
].dma_hdl
)
3435 hermon_dma_free(&dma_info
[index2
]);
3436 dma_info
[index2
].dma_hdl
= NULL
;
3444 * hermon_hca_port_init()
3445 * Context: Only called from attach() path context
3448 hermon_hca_port_init(hermon_state_t
*state
)
3450 hermon_hw_set_port_t
*portinits
, *initport
;
3451 hermon_cfg_profile_t
*cfgprof
;
3454 uint64_t maxval
, val
;
3455 uint64_t sysimgguid
, nodeguid
, portguid
;
3458 cfgprof
= state
->hs_cfg_profile
;
3460 /* Get number of HCA ports */
3461 num_ports
= cfgprof
->cp_num_ports
;
3463 /* Allocate space for Hermon set port struct(s) */
3464 portinits
= (hermon_hw_set_port_t
*)kmem_zalloc(num_ports
*
3465 sizeof (hermon_hw_set_port_t
), KM_SLEEP
);
3469 /* Post commands to initialize each Hermon HCA port */
3471 * In Hermon, the process is different than in previous HCAs.
3472 * Here, you have to:
3473 * QUERY_PORT - to get basic information from the HCA
3474 * set the fields accordingly
3475 * SET_PORT - to change/set everything as desired
3476 * INIT_PORT - to bring the port up
3478 * Needs to be done for each port in turn
3481 for (i
= 0; i
< num_ports
; i
++) {
3482 bzero(&state
->hs_queryport
, sizeof (hermon_hw_query_port_t
));
3483 status
= hermon_cmn_query_cmd_post(state
, QUERY_PORT
, 0,
3484 (i
+ 1), &state
->hs_queryport
,
3485 sizeof (hermon_hw_query_port_t
), HERMON_CMD_NOSLEEP_SPIN
);
3486 if (status
!= HERMON_CMD_SUCCESS
) {
3487 cmn_err(CE_CONT
, "Hermon: QUERY_PORT (port %02d) "
3488 "command failed: %08x\n", i
+ 1, status
);
3489 goto init_ports_fail
;
3491 initport
= &portinits
[i
];
3492 state
->hs_initport
= &portinits
[i
];
3494 bzero(initport
, sizeof (hermon_hw_query_port_t
));
3497 * Determine whether we need to override the firmware's
3498 * default SystemImageGUID setting.
3500 sysimgguid
= cfgprof
->cp_sysimgguid
;
3501 if (sysimgguid
!= 0) {
3503 initport
->sys_img_guid
= sysimgguid
;
3507 * Determine whether we need to override the firmware's
3508 * default NodeGUID setting.
3510 nodeguid
= cfgprof
->cp_nodeguid
;
3511 if (nodeguid
!= 0) {
3513 initport
->node_guid
= nodeguid
;
3517 * Determine whether we need to override the firmware's
3518 * default PortGUID setting.
3520 portguid
= cfgprof
->cp_portguid
[i
];
3521 if (portguid
!= 0) {
3523 initport
->guid0
= portguid
;
3526 /* Validate max MTU size */
3527 maxval
= state
->hs_queryport
.ib_mtu
;
3528 val
= cfgprof
->cp_max_mtu
;
3530 goto init_ports_fail
;
3533 /* Set mtu_cap to 4096 bytes */
3534 initport
->mmc
= 1; /* set the change bit */
3535 initport
->mtu_cap
= 5; /* for 4096 bytes */
3537 /* Validate the max port width */
3538 maxval
= state
->hs_queryport
.ib_port_wid
;
3539 val
= cfgprof
->cp_max_port_width
;
3541 goto init_ports_fail
;
3544 /* Validate max VL cap size */
3545 maxval
= state
->hs_queryport
.max_vl
;
3546 val
= cfgprof
->cp_max_vlcap
;
3548 goto init_ports_fail
;
3551 /* Since we're doing mtu_cap, cut vl_cap down */
3552 initport
->mvc
= 1; /* set this change bit */
3553 initport
->vl_cap
= 3; /* 3 means vl0-vl3, 4 total */
3555 /* Validate max GID table size */
3556 maxval
= ((uint64_t)1 << state
->hs_queryport
.log_max_gid
);
3557 val
= ((uint64_t)1 << cfgprof
->cp_log_max_gidtbl
);
3559 goto init_ports_fail
;
3561 initport
->max_gid
= (uint16_t)val
;
3564 /* Validate max PKey table size */
3565 maxval
= ((uint64_t)1 << state
->hs_queryport
.log_max_pkey
);
3566 val
= ((uint64_t)1 << cfgprof
->cp_log_max_pkeytbl
);
3568 goto init_ports_fail
;
3570 initport
->max_pkey
= (uint16_t)val
;
3573 * Post the SET_PORT cmd to Hermon firmware. This sets
3574 * the parameters of the port.
3576 status
= hermon_set_port_cmd_post(state
, initport
, i
+ 1,
3577 HERMON_CMD_NOSLEEP_SPIN
);
3578 if (status
!= HERMON_CMD_SUCCESS
) {
3579 cmn_err(CE_CONT
, "Hermon: SET_PORT (port %02d) command "
3580 "failed: %08x\n", i
+ 1, status
);
3581 goto init_ports_fail
;
3583 /* issue another SET_PORT cmd - performance fix/workaround */
3584 /* XXX - need to discuss with Mellanox */
3585 bzero(initport
, sizeof (hermon_hw_query_port_t
));
3586 initport
->cap_mask
= 0x02500868;
3587 status
= hermon_set_port_cmd_post(state
, initport
, i
+ 1,
3588 HERMON_CMD_NOSLEEP_SPIN
);
3589 if (status
!= HERMON_CMD_SUCCESS
) {
3590 cmn_err(CE_CONT
, "Hermon: SET_PORT (port %02d) command "
3591 "failed: %08x\n", i
+ 1, status
);
3592 goto init_ports_fail
;
3597 * Finally, do the INIT_PORT for each port in turn
3598 * When this command completes, the corresponding Hermon port
3599 * will be physically "Up" and initialized.
3601 for (i
= 0; i
< num_ports
; i
++) {
3602 status
= hermon_init_port_cmd_post(state
, i
+ 1,
3603 HERMON_CMD_NOSLEEP_SPIN
);
3604 if (status
!= HERMON_CMD_SUCCESS
) {
3605 cmn_err(CE_CONT
, "Hermon: INIT_PORT (port %02d) "
3606 "comman failed: %08x\n", i
+ 1, status
);
3607 goto init_ports_fail
;
3611 /* Free up the memory for Hermon port init struct(s), return success */
3612 kmem_free(portinits
, num_ports
* sizeof (hermon_hw_set_port_t
));
3613 return (DDI_SUCCESS
);
3617 * Free up the memory for Hermon port init struct(s), shutdown any
3618 * successfully initialized ports, and return failure
3620 kmem_free(portinits
, num_ports
* sizeof (hermon_hw_set_port_t
));
3621 (void) hermon_hca_ports_shutdown(state
, i
);
3623 return (DDI_FAILURE
);
3628 * hermon_hca_ports_shutdown()
3629 * Context: Only called from attach() and/or detach() path contexts
3632 hermon_hca_ports_shutdown(hermon_state_t
*state
, uint_t num_init
)
3637 * Post commands to shutdown all init'd Hermon HCA ports. Note: if
3638 * any of these commands fail for any reason, it would be entirely
3639 * unexpected and probably indicative a serious problem (HW or SW).
3640 * Although we do return void from this function, this type of failure
3641 * should not go unreported. That is why we have the warning message.
3643 for (i
= 0; i
< num_init
; i
++) {
3644 status
= hermon_close_port_cmd_post(state
, i
+ 1,
3645 HERMON_CMD_NOSLEEP_SPIN
);
3646 if (status
!= HERMON_CMD_SUCCESS
) {
3647 HERMON_WARNING(state
, "failed to shutdown HCA port");
3651 return (HERMON_CMD_SUCCESS
);
3656 * hermon_internal_uarpg_init
3657 * Context: Only called from attach() path context
3660 hermon_internal_uarpg_init(hermon_state_t
*state
)
3663 hermon_dbr_info_t
*info
;
3666 * Allocate the UAR page for kernel use. This UAR page is
3667 * the privileged UAR page through which all kernel generated
3668 * doorbells will be rung. There are a number of UAR pages
3669 * reserved by hardware at the front of the UAR BAR, indicated
3670 * by DEVCAP.num_rsvd_uar, which we have already allocated. So,
3671 * the kernel page, or UAR page index num_rsvd_uar, will be
3672 * allocated here for kernel use.
3675 status
= hermon_rsrc_alloc(state
, HERMON_UARPG
, 1, HERMON_SLEEP
,
3676 &state
->hs_uarkpg_rsrc
);
3677 if (status
!= DDI_SUCCESS
) {
3678 return (DDI_FAILURE
);
3681 /* Setup pointer to kernel UAR page */
3682 state
->hs_uar
= (hermon_hw_uar_t
*)state
->hs_uarkpg_rsrc
->hr_addr
;
3684 /* need to set up DBr tracking as well */
3685 status
= hermon_dbr_page_alloc(state
, &info
);
3686 if (status
!= DDI_SUCCESS
) {
3687 return (DDI_FAILURE
);
3689 state
->hs_kern_dbr
= info
;
3690 return (DDI_SUCCESS
);
3695 * hermon_internal_uarpg_fini
3696 * Context: Only called from attach() and/or detach() path contexts
3699 hermon_internal_uarpg_fini(hermon_state_t
*state
)
3701 /* Free up Hermon UAR page #1 (kernel driver doorbells) */
3702 hermon_rsrc_free(state
, &state
->hs_uarkpg_rsrc
);
3707 * hermon_special_qp_contexts_reserve()
3708 * Context: Only called from attach() path context
3711 hermon_special_qp_contexts_reserve(hermon_state_t
*state
)
3713 hermon_rsrc_t
*qp0_rsrc
, *qp1_rsrc
, *qp_resvd
;
3716 /* Initialize the lock used for special QP rsrc management */
3717 mutex_init(&state
->hs_spec_qplock
, NULL
, MUTEX_DRIVER
,
3718 DDI_INTR_PRI(state
->hs_intrmsi_pri
));
3721 * Reserve contexts for QP0. These QP contexts will be setup to
3722 * act as aliases for the real QP0. Note: We are required to grab
3723 * two QPs (one per port) even if we are operating in single-port
3726 status
= hermon_rsrc_alloc(state
, HERMON_QPC
, 2,
3727 HERMON_SLEEP
, &qp0_rsrc
);
3728 if (status
!= DDI_SUCCESS
) {
3729 mutex_destroy(&state
->hs_spec_qplock
);
3730 return (DDI_FAILURE
);
3732 state
->hs_spec_qp0
= qp0_rsrc
;
3735 * Reserve contexts for QP1. These QP contexts will be setup to
3736 * act as aliases for the real QP1. Note: We are required to grab
3737 * two QPs (one per port) even if we are operating in single-port
3740 status
= hermon_rsrc_alloc(state
, HERMON_QPC
, 2,
3741 HERMON_SLEEP
, &qp1_rsrc
);
3742 if (status
!= DDI_SUCCESS
) {
3743 hermon_rsrc_free(state
, &qp0_rsrc
);
3744 mutex_destroy(&state
->hs_spec_qplock
);
3745 return (DDI_FAILURE
);
3747 state
->hs_spec_qp1
= qp1_rsrc
;
3749 status
= hermon_rsrc_alloc(state
, HERMON_QPC
, 4,
3750 HERMON_SLEEP
, &qp_resvd
);
3751 if (status
!= DDI_SUCCESS
) {
3752 hermon_rsrc_free(state
, &qp1_rsrc
);
3753 hermon_rsrc_free(state
, &qp0_rsrc
);
3754 mutex_destroy(&state
->hs_spec_qplock
);
3755 return (DDI_FAILURE
);
3757 state
->hs_spec_qp_unused
= qp_resvd
;
3759 return (DDI_SUCCESS
);
3764 * hermon_special_qp_contexts_unreserve()
3765 * Context: Only called from attach() and/or detach() path contexts
3768 hermon_special_qp_contexts_unreserve(hermon_state_t
*state
)
3771 /* Unreserve contexts for spec_qp_unused */
3772 hermon_rsrc_free(state
, &state
->hs_spec_qp_unused
);
3774 /* Unreserve contexts for QP1 */
3775 hermon_rsrc_free(state
, &state
->hs_spec_qp1
);
3777 /* Unreserve contexts for QP0 */
3778 hermon_rsrc_free(state
, &state
->hs_spec_qp0
);
3780 /* Destroy the lock used for special QP rsrc management */
3781 mutex_destroy(&state
->hs_spec_qplock
);
3788 * Context: Currently called only from attach() path context
3791 hermon_sw_reset(hermon_state_t
*state
)
3793 ddi_acc_handle_t hdl
= hermon_get_pcihdl(state
);
3794 ddi_acc_handle_t cmdhdl
= hermon_get_cmdhdl(state
);
3795 uint32_t reset_delay
;
3799 uint32_t data32
; /* for devctl & linkctl */
3802 /* initialize the FMA retry loop */
3803 hermon_pio_init(fm_loop_cnt
, fm_status
, fm_test
);
3804 hermon_pio_init(fm_loop_cnt2
, fm_status2
, fm_test2
);
3807 * If the configured software reset delay is set to zero, then we
3808 * will not attempt a software reset of the Hermon device.
3810 reset_delay
= state
->hs_cfg_profile
->cp_sw_reset_delay
;
3811 if (reset_delay
== 0) {
3812 return (DDI_SUCCESS
);
3815 /* the FMA retry loop starts. */
3816 hermon_pio_start(state
, cmdhdl
, pio_error
, fm_loop_cnt
, fm_status
,
3818 hermon_pio_start(state
, hdl
, pio_error2
, fm_loop_cnt2
, fm_status2
,
3821 /* Query the PCI capabilities of the HCA device */
3822 /* but don't process the VPD until after reset */
3823 status
= hermon_pci_capability_list(state
, hdl
);
3824 if (status
!= DDI_SUCCESS
) {
3825 cmn_err(CE_NOTE
, "failed to get pci capabilities list(0x%x)\n",
3827 return (DDI_FAILURE
);
3831 * Read all PCI config info (reg0...reg63). Note: According to the
3832 * Hermon software reset application note, we should not read or
3833 * restore the values in reg22 and reg23.
3834 * NOTE: For Hermon (and Arbel too) it says to restore the command
3835 * register LAST, and technically, you need to restore the
3836 * PCIE Capability "device control" and "link control" (word-sized,
3837 * at offsets 0x08 and 0x10 from the capbility ID respectively).
3838 * We hold off restoring the command register - offset 0x4 - till last
3841 /* 1st, wait for the semaphore assure accessibility - per PRM */
3843 for (i
= 0; i
< NANOSEC
/MICROSEC
/* 1sec timeout */; i
++) {
3844 sem
= ddi_get32(cmdhdl
, state
->hs_cmd_regs
.sw_semaphore
);
3852 /* Check if timeout happens */
3855 * Remove this acc handle from Hermon, then log
3858 hermon_pci_config_teardown(state
, &hdl
);
3860 cmn_err(CE_WARN
, "hermon_sw_reset timeout: "
3861 "failed to get the semaphore(0x%p)\n",
3862 (void *)state
->hs_cmd_regs
.sw_semaphore
);
3864 hermon_fm_ereport(state
, HCA_IBA_ERR
, HCA_ERR_NON_FATAL
);
3865 return (DDI_FAILURE
);
3868 for (i
= 0; i
< HERMON_SW_RESET_NUMREGS
; i
++) {
3869 if ((i
!= HERMON_SW_RESET_REG22_RSVD
) &&
3870 (i
!= HERMON_SW_RESET_REG23_RSVD
)) {
3871 state
->hs_cfg_data
[i
] = pci_config_get32(hdl
, i
<< 2);
3876 * Perform the software reset (by writing 1 at offset 0xF0010)
3878 ddi_put32(cmdhdl
, state
->hs_cmd_regs
.sw_reset
, HERMON_SW_RESET_START
);
3881 * This delay is required so as not to cause a panic here. If the
3882 * device is accessed too soon after reset it will not respond to
3883 * config cycles, causing a Master Abort and panic.
3885 drv_usecwait(reset_delay
);
3888 * Poll waiting for the device to finish resetting.
3890 loopcnt
= 100; /* 100 times @ 100 usec - total delay 10 msec */
3891 while ((pci_config_get32(hdl
, 0) & 0x0000FFFF) != PCI_VENID_MLX
) {
3892 drv_usecwait(HERMON_SW_RESET_POLL_DELAY
);
3894 break; /* just in case, break and go on */
3897 cmn_err(CE_CONT
, "!Never see VEND_ID - read == %X",
3898 pci_config_get32(hdl
, 0));
3901 * Restore the config info
3903 for (i
= 0; i
< HERMON_SW_RESET_NUMREGS
; i
++) {
3904 if (i
== 1) continue; /* skip the status/ctrl reg */
3905 if ((i
!= HERMON_SW_RESET_REG22_RSVD
) &&
3906 (i
!= HERMON_SW_RESET_REG23_RSVD
)) {
3907 pci_config_put32(hdl
, i
<< 2, state
->hs_cfg_data
[i
]);
3912 * PCI Express Capability - we saved during capability list, and
3913 * we'll restore them here.
3915 offset
= state
->hs_pci_cap_offset
;
3916 data32
= state
->hs_pci_cap_devctl
;
3917 pci_config_put32(hdl
, offset
+ HERMON_PCI_CAP_DEV_OFFS
, data32
);
3918 data32
= state
->hs_pci_cap_lnkctl
;
3919 pci_config_put32(hdl
, offset
+ HERMON_PCI_CAP_LNK_OFFS
, data32
);
3921 pci_config_put32(hdl
, 0x04, (state
->hs_cfg_data
[1] | 0x0006));
3923 /* the FMA retry loop ends. */
3924 hermon_pio_end(state
, hdl
, pio_error2
, fm_loop_cnt2
, fm_status2
,
3926 hermon_pio_end(state
, cmdhdl
, pio_error
, fm_loop_cnt
, fm_status
,
3929 return (DDI_SUCCESS
);
3934 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_NON_FATAL
);
3935 return (DDI_FAILURE
);
3941 * Context: Only called from attach() path context
3944 hermon_mcg_init(hermon_state_t
*state
)
3950 * Allocate space for the MCG temporary copy buffer. This is
3951 * used by the Attach/Detach Multicast Group code
3953 mcg_tmp_sz
= HERMON_MCGMEM_SZ(state
);
3954 state
->hs_mcgtmp
= kmem_zalloc(mcg_tmp_sz
, KM_SLEEP
);
3957 * Initialize the multicast group mutex. This ensures atomic
3958 * access to add, modify, and remove entries in the multicast
3961 mutex_init(&state
->hs_mcglock
, NULL
, MUTEX_DRIVER
,
3962 DDI_INTR_PRI(state
->hs_intrmsi_pri
));
3964 return (DDI_SUCCESS
);
3970 * Context: Only called from attach() and/or detach() path contexts
3973 hermon_mcg_fini(hermon_state_t
*state
)
3978 /* Free up the space used for the MCG temporary copy buffer */
3979 mcg_tmp_sz
= HERMON_MCGMEM_SZ(state
);
3980 kmem_free(state
->hs_mcgtmp
, mcg_tmp_sz
);
3982 /* Destroy the multicast group mutex */
3983 mutex_destroy(&state
->hs_mcglock
);
3989 * hermon_fw_version_check()
3990 * Context: Only called from attach() path context
3993 hermon_fw_version_check(hermon_state_t
*state
)
3996 uint_t hermon_fw_ver_major
;
3997 uint_t hermon_fw_ver_minor
;
3998 uint_t hermon_fw_ver_subminor
;
4001 if (hermon_test_num
== -1) {
4002 return (DDI_FAILURE
);
4007 * Depending on which version of driver we have attached, and which
4008 * HCA we've attached, the firmware version checks will be different.
4009 * We set up the comparison values for both Arbel and Sinai HCAs.
4011 switch (state
->hs_operational_mode
) {
4012 case HERMON_HCA_MODE
:
4013 hermon_fw_ver_major
= HERMON_FW_VER_MAJOR
;
4014 hermon_fw_ver_minor
= HERMON_FW_VER_MINOR
;
4015 hermon_fw_ver_subminor
= HERMON_FW_VER_SUBMINOR
;
4019 return (DDI_FAILURE
);
4023 * If FW revision major number is less than acceptable,
4024 * return failure, else if greater return success. If
4025 * the major numbers are equal than check the minor number
4027 if (state
->hs_fw
.fw_rev_major
< hermon_fw_ver_major
) {
4028 return (DDI_FAILURE
);
4029 } else if (state
->hs_fw
.fw_rev_major
> hermon_fw_ver_major
) {
4030 return (DDI_SUCCESS
);
4034 * Do the same check as above, except for minor revision numbers
4035 * If the minor numbers are equal than check the subminor number
4037 if (state
->hs_fw
.fw_rev_minor
< hermon_fw_ver_minor
) {
4038 return (DDI_FAILURE
);
4039 } else if (state
->hs_fw
.fw_rev_minor
> hermon_fw_ver_minor
) {
4040 return (DDI_SUCCESS
);
4044 * Once again we do the same check as above, except for the subminor
4045 * revision number. If the subminor numbers are equal here, then
4046 * these are the same firmware version, return success
4048 if (state
->hs_fw
.fw_rev_subminor
< hermon_fw_ver_subminor
) {
4049 return (DDI_FAILURE
);
4050 } else if (state
->hs_fw
.fw_rev_subminor
> hermon_fw_ver_subminor
) {
4051 return (DDI_SUCCESS
);
4054 return (DDI_SUCCESS
);
4059 * hermon_device_info_report()
4060 * Context: Only called from attach() path context
4063 hermon_device_info_report(hermon_state_t
*state
)
4066 cmn_err(CE_CONT
, "?hermon%d: FW ver: %04d.%04d.%04d, "
4067 "HW rev: %02d\n", state
->hs_instance
, state
->hs_fw
.fw_rev_major
,
4068 state
->hs_fw
.fw_rev_minor
, state
->hs_fw
.fw_rev_subminor
,
4069 state
->hs_revision_id
);
4070 cmn_err(CE_CONT
, "?hermon%d: %64s (0x%016" PRIx64
")\n",
4071 state
->hs_instance
, state
->hs_nodedesc
, state
->hs_nodeguid
);
4077 * hermon_pci_capability_list()
4078 * Context: Only called from attach() path context
4081 hermon_pci_capability_list(hermon_state_t
*state
, ddi_acc_handle_t hdl
)
4083 uint_t offset
, data
;
4086 state
->hs_pci_cap_offset
= 0; /* make sure it's cleared */
4089 * Check for the "PCI Capabilities" bit in the "Status Register".
4090 * Bit 4 in this register indicates the presence of a "PCI
4091 * Capabilities" list.
4093 * PCI-Express requires this bit to be set to 1.
4095 data
= pci_config_get16(hdl
, 0x06);
4096 if ((data
& 0x10) == 0) {
4097 return (DDI_FAILURE
);
4101 * Starting from offset 0x34 in PCI config space, find the
4102 * head of "PCI capabilities" list, and walk the list. If
4103 * capabilities of a known type are encountered (e.g.
4104 * "PCI-X Capability"), then call the appropriate handler
4107 offset
= pci_config_get8(hdl
, 0x34);
4108 while (offset
!= 0x0) {
4109 data
= pci_config_get8(hdl
, offset
);
4111 * Check for known capability types. Hermon has the
4113 * o Power Mgmt (0x02)
4114 * o VPD Capability (0x03)
4115 * o PCI-E Capability (0x10)
4116 * o MSIX Capability (0x11)
4120 /* power mgmt handling */
4125 * Reading the PCIe VPD is inconsistent - that is, sometimes causes
4126 * problems on (mostly) X64, though we've also seen problems w/ Sparc
4127 * and Tavor --- so, for now until it's root caused, don't try and
4130 #ifdef HERMON_VPD_WORKS
4131 hermon_pci_capability_vpd(state
, hdl
, offset
);
4134 hermon_pci_capability_vpd(state
, hdl
, offset
);
4139 * PCI Express Capability - save offset & contents
4140 * for later in reset
4142 state
->hs_pci_cap_offset
= offset
;
4143 data32
= pci_config_get32(hdl
,
4144 offset
+ HERMON_PCI_CAP_DEV_OFFS
);
4145 state
->hs_pci_cap_devctl
= data32
;
4146 data32
= pci_config_get32(hdl
,
4147 offset
+ HERMON_PCI_CAP_LNK_OFFS
);
4148 state
->hs_pci_cap_lnkctl
= data32
;
4152 * MSIX support - nothing to do, taken care of in the
4153 * MSI/MSIX interrupt frameworkd
4157 /* just go on to the next */
4161 /* Get offset of next entry in list */
4162 offset
= pci_config_get8(hdl
, offset
+ 1);
4165 return (DDI_SUCCESS
);
4169 * hermon_pci_read_vpd()
4170 * Context: Only called from attach() path context
4171 * utility routine for hermon_pci_capability_vpd()
4174 hermon_pci_read_vpd(ddi_acc_handle_t hdl
, uint_t offset
, uint32_t addr
,
4177 int retry
= 40; /* retry counter for EEPROM poll */
4179 int vpd_addr
= offset
+ 2;
4180 int vpd_data
= offset
+ 4;
4183 * In order to read a 32-bit value from VPD, we are to write down
4184 * the address (offset in the VPD itself) to the address register.
4185 * To signal the read, we also clear bit 31. We then poll on bit 31
4186 * and when it is set, we can then read our 4 bytes from the data
4189 (void) pci_config_put32(hdl
, offset
, addr
<< 16);
4192 val
= pci_config_get16(hdl
, vpd_addr
);
4193 if (val
& 0x8000) { /* flag bit set */
4194 *data
= pci_config_get32(hdl
, vpd_data
);
4195 return (DDI_SUCCESS
);
4198 /* read of flag failed write one message but count the failures */
4201 "!Failed to see flag bit after VPD addr write\n");
4206 return (DDI_FAILURE
);
4212 * hermon_pci_capability_vpd()
4213 * Context: Only called from attach() path context
4216 hermon_pci_capability_vpd(hermon_state_t
*state
, ddi_acc_handle_t hdl
,
4219 uint8_t name_length
;
4227 #endif /* _BIG_ENDIAN */
4229 uint32_t vpd_int
[HERMON_VPD_HDR_DWSIZE
];
4230 uchar_t vpd_char
[HERMON_VPD_HDR_BSIZE
];
4235 * Read in the Vital Product Data (VPD) to the extend needed
4236 * by the fwflash utility
4238 for (i
= 0; i
< HERMON_VPD_HDR_DWSIZE
; i
++) {
4239 err
= hermon_pci_read_vpd(hdl
, offset
, i
<< 2, &vpd
.vpd_int
[i
]);
4240 if (err
!= DDI_SUCCESS
) {
4241 cmn_err(CE_NOTE
, "!VPD read failed\n");
4247 /* Need to swap bytes for big endian. */
4248 for (i
= 0; i
< HERMON_VPD_HDR_DWSIZE
; i
++) {
4249 data32
= vpd
.vpd_int
[i
];
4250 vpd
.vpd_char
[(i
<< 2) + 3] =
4251 (uchar_t
)((data32
& 0xFF000000) >> 24);
4252 vpd
.vpd_char
[(i
<< 2) + 2] =
4253 (uchar_t
)((data32
& 0x00FF0000) >> 16);
4254 vpd
.vpd_char
[(i
<< 2) + 1] =
4255 (uchar_t
)((data32
& 0x0000FF00) >> 8);
4256 vpd
.vpd_char
[i
<< 2] = (uchar_t
)(data32
& 0x000000FF);
4258 #endif /* _BIG_ENDIAN */
4260 /* Check for VPD String ID Tag */
4261 if (vpd
.vpd_char
[vpd_str_id
] == 0x82) {
4262 /* get the product name */
4263 name_length
= (uint8_t)vpd
.vpd_char
[vpd_str_id
+ 1];
4264 if (name_length
> sizeof (state
->hs_hca_name
)) {
4265 cmn_err(CE_NOTE
, "!VPD name too large (0x%x)\n",
4269 (void) memcpy(state
->hs_hca_name
, &vpd
.vpd_char
[vpd_str_id
+ 3],
4271 state
->hs_hca_name
[name_length
] = 0;
4273 /* get the part number */
4274 vpd_ro_desc
= name_length
+ 3; /* read-only tag location */
4275 vpd_ro_pn_desc
= vpd_ro_desc
+ 3; /* P/N keyword location */
4277 /* Verify read-only tag and Part Number keyword. */
4278 if (vpd
.vpd_char
[vpd_ro_desc
] != 0x90 ||
4279 (vpd
.vpd_char
[vpd_ro_pn_desc
] != 'P' &&
4280 vpd
.vpd_char
[vpd_ro_pn_desc
+ 1] != 'N')) {
4281 cmn_err(CE_NOTE
, "!VPD Part Number not found\n");
4285 pn_length
= (uint8_t)vpd
.vpd_char
[vpd_ro_pn_desc
+ 2];
4286 if (pn_length
> sizeof (state
->hs_hca_pn
)) {
4287 cmn_err(CE_NOTE
, "!VPD part number too large (0x%x)\n",
4291 (void) memcpy(state
->hs_hca_pn
,
4292 &vpd
.vpd_char
[vpd_ro_pn_desc
+ 3],
4294 state
->hs_hca_pn
[pn_length
] = 0;
4295 state
->hs_hca_pn_len
= pn_length
;
4296 cmn_err(CE_CONT
, "!vpd %s\n", state
->hs_hca_pn
);
4298 /* Wrong VPD String ID Tag */
4299 cmn_err(CE_NOTE
, "!VPD String ID Tag not found, tag: %02x\n",
4305 state
->hs_hca_pn_len
= 0;
4311 * hermon_intr_or_msi_init()
4312 * Context: Only called from attach() path context
4315 hermon_intr_or_msi_init(hermon_state_t
*state
)
4319 /* Query for the list of supported interrupt event types */
4320 status
= ddi_intr_get_supported_types(state
->hs_dip
,
4321 &state
->hs_intr_types_avail
);
4322 if (status
!= DDI_SUCCESS
) {
4323 return (DDI_FAILURE
);
4327 * If Hermon supports MSI-X in this system (and, if it
4328 * hasn't been overridden by a configuration variable), then
4329 * the default behavior is to use a single MSI-X. Otherwise,
4330 * fallback to using legacy interrupts. Also, if MSI-X is chosen,
4331 * but fails for whatever reasons, then next try MSI
4333 if ((state
->hs_cfg_profile
->cp_use_msi_if_avail
!= 0) &&
4334 (state
->hs_intr_types_avail
& DDI_INTR_TYPE_MSIX
)) {
4335 status
= hermon_add_intrs(state
, DDI_INTR_TYPE_MSIX
);
4336 if (status
== DDI_SUCCESS
) {
4337 state
->hs_intr_type_chosen
= DDI_INTR_TYPE_MSIX
;
4338 return (DDI_SUCCESS
);
4343 * If Hermon supports MSI in this system (and, if it
4344 * hasn't been overridden by a configuration variable), then
4345 * the default behavior is to use a single MSIX. Otherwise,
4346 * fallback to using legacy interrupts. Also, if MSI is chosen,
4347 * but fails for whatever reasons, then fallback to using legacy
4350 if ((state
->hs_cfg_profile
->cp_use_msi_if_avail
!= 0) &&
4351 (state
->hs_intr_types_avail
& DDI_INTR_TYPE_MSI
)) {
4352 status
= hermon_add_intrs(state
, DDI_INTR_TYPE_MSI
);
4353 if (status
== DDI_SUCCESS
) {
4354 state
->hs_intr_type_chosen
= DDI_INTR_TYPE_MSI
;
4355 return (DDI_SUCCESS
);
4360 * MSI interrupt allocation failed, or was not available. Fallback to
4361 * legacy interrupt support.
4363 if (state
->hs_intr_types_avail
& DDI_INTR_TYPE_FIXED
) {
4364 status
= hermon_add_intrs(state
, DDI_INTR_TYPE_FIXED
);
4365 if (status
== DDI_SUCCESS
) {
4366 state
->hs_intr_type_chosen
= DDI_INTR_TYPE_FIXED
;
4367 return (DDI_SUCCESS
);
4372 * None of MSI, MSI-X, nor legacy interrupts were successful.
4375 return (DDI_FAILURE
);
4380 hermon_intr_cb_handler(dev_info_t
*dip
, ddi_cb_action_t action
, void *cbarg
,
4381 void *arg1
, void *arg2
)
4383 hermon_state_t
*state
= (hermon_state_t
*)arg1
;
4385 IBTF_DPRINTF_L2("hermon", "interrupt callback: instance %d, "
4386 "action %d, cbarg %d\n", state
->hs_instance
, action
,
4387 (uint32_t)(uintptr_t)cbarg
);
4388 return (DDI_SUCCESS
);
4392 * hermon_add_intrs()
4393 * Context: Only called from attach() patch context
4396 hermon_add_intrs(hermon_state_t
*state
, int intr_type
)
4400 if (state
->hs_intr_cb_hdl
== NULL
) {
4401 status
= ddi_cb_register(state
->hs_dip
, DDI_CB_FLAG_INTR
,
4402 hermon_intr_cb_handler
, state
, NULL
,
4403 &state
->hs_intr_cb_hdl
);
4404 if (status
!= DDI_SUCCESS
) {
4405 cmn_err(CE_CONT
, "ddi_cb_register failed: 0x%x\n",
4407 state
->hs_intr_cb_hdl
= NULL
;
4408 return (DDI_FAILURE
);
4412 /* Get number of interrupts/MSI supported */
4413 status
= ddi_intr_get_nintrs(state
->hs_dip
, intr_type
,
4414 &state
->hs_intrmsi_count
);
4415 if (status
!= DDI_SUCCESS
) {
4416 (void) ddi_cb_unregister(state
->hs_intr_cb_hdl
);
4417 state
->hs_intr_cb_hdl
= NULL
;
4418 return (DDI_FAILURE
);
4421 /* Get number of available interrupts/MSI */
4422 status
= ddi_intr_get_navail(state
->hs_dip
, intr_type
,
4423 &state
->hs_intrmsi_avail
);
4424 if (status
!= DDI_SUCCESS
) {
4425 (void) ddi_cb_unregister(state
->hs_intr_cb_hdl
);
4426 state
->hs_intr_cb_hdl
= NULL
;
4427 return (DDI_FAILURE
);
4430 /* Ensure that we have at least one (1) usable MSI or interrupt */
4431 if ((state
->hs_intrmsi_avail
< 1) || (state
->hs_intrmsi_count
< 1)) {
4432 (void) ddi_cb_unregister(state
->hs_intr_cb_hdl
);
4433 state
->hs_intr_cb_hdl
= NULL
;
4434 return (DDI_FAILURE
);
4438 * Allocate the #interrupt/MSI handles.
4439 * The number we request is the minimum of these three values:
4440 * HERMON_MSIX_MAX driver maximum (array size)
4441 * hermon_msix_max /etc/system override to...
4443 * state->hs_intrmsi_avail Maximum the ddi provides.
4445 status
= ddi_intr_alloc(state
->hs_dip
, &state
->hs_intrmsi_hdl
[0],
4446 intr_type
, 0, min(min(HERMON_MSIX_MAX
, state
->hs_intrmsi_avail
),
4447 hermon_msix_max
), &state
->hs_intrmsi_allocd
, DDI_INTR_ALLOC_NORMAL
);
4448 if (status
!= DDI_SUCCESS
) {
4449 (void) ddi_cb_unregister(state
->hs_intr_cb_hdl
);
4450 state
->hs_intr_cb_hdl
= NULL
;
4451 return (DDI_FAILURE
);
4454 /* Ensure that we have allocated at least one (1) MSI or interrupt */
4455 if (state
->hs_intrmsi_allocd
< 1) {
4456 (void) ddi_cb_unregister(state
->hs_intr_cb_hdl
);
4457 state
->hs_intr_cb_hdl
= NULL
;
4458 return (DDI_FAILURE
);
4462 * Extract the priority for the allocated interrupt/MSI. This
4463 * will be used later when initializing certain mutexes.
4465 status
= ddi_intr_get_pri(state
->hs_intrmsi_hdl
[0],
4466 &state
->hs_intrmsi_pri
);
4467 if (status
!= DDI_SUCCESS
) {
4468 /* Free the allocated interrupt/MSI handle */
4469 (void) ddi_intr_free(state
->hs_intrmsi_hdl
[0]);
4471 (void) ddi_cb_unregister(state
->hs_intr_cb_hdl
);
4472 state
->hs_intr_cb_hdl
= NULL
;
4473 return (DDI_FAILURE
);
4476 /* Make sure the interrupt/MSI priority is below 'high level' */
4477 if (state
->hs_intrmsi_pri
>= ddi_intr_get_hilevel_pri()) {
4478 /* Free the allocated interrupt/MSI handle */
4479 (void) ddi_intr_free(state
->hs_intrmsi_hdl
[0]);
4481 return (DDI_FAILURE
);
4484 /* Get add'l capability information regarding interrupt/MSI */
4485 status
= ddi_intr_get_cap(state
->hs_intrmsi_hdl
[0],
4486 &state
->hs_intrmsi_cap
);
4487 if (status
!= DDI_SUCCESS
) {
4488 /* Free the allocated interrupt/MSI handle */
4489 (void) ddi_intr_free(state
->hs_intrmsi_hdl
[0]);
4491 return (DDI_FAILURE
);
4494 return (DDI_SUCCESS
);
4499 * hermon_intr_or_msi_fini()
4500 * Context: Only called from attach() and/or detach() path contexts
4503 hermon_intr_or_msi_fini(hermon_state_t
*state
)
4508 for (intr
= 0; intr
< state
->hs_intrmsi_allocd
; intr
++) {
4510 /* Free the allocated interrupt/MSI handle */
4511 status
= ddi_intr_free(state
->hs_intrmsi_hdl
[intr
]);
4512 if (status
!= DDI_SUCCESS
) {
4513 return (DDI_FAILURE
);
4516 (void) ddi_cb_unregister(state
->hs_intr_cb_hdl
);
4517 state
->hs_intr_cb_hdl
= NULL
;
4518 return (DDI_SUCCESS
);
4524 hermon_pci_capability_msix(hermon_state_t
*state
, ddi_acc_handle_t hdl
,
4529 uint32_t t_offset
; /* table offset */
4531 uint32_t p_offset
; /* pba */
4533 int t_size
; /* size in entries - each is 4 dwords */
4535 /* come in with offset pointing at the capability structure */
4537 msix_data
= pci_config_get32(hdl
, offset
);
4538 cmn_err(CE_CONT
, "Full cap structure dword = %X\n", msix_data
);
4539 msg_cntr
= pci_config_get16(hdl
, offset
+2);
4540 cmn_err(CE_CONT
, "MSIX msg_control = %X\n", msg_cntr
);
4542 msix_data
= pci_config_get32(hdl
, offset
); /* table info */
4543 t_offset
= (msix_data
& 0xFFF8) >> 3;
4544 t_bir
= msix_data
& 0x07;
4546 cmn_err(CE_CONT
, " table %X --offset = %X, bir(bar) = %X\n",
4547 msix_data
, t_offset
, t_bir
);
4548 msix_data
= pci_config_get32(hdl
, offset
); /* PBA info */
4549 p_offset
= (msix_data
& 0xFFF8) >> 3;
4550 p_bir
= msix_data
& 0x07;
4552 cmn_err(CE_CONT
, " PBA %X --offset = %X, bir(bar) = %X\n",
4553 msix_data
, p_offset
, p_bir
);
4554 t_size
= msg_cntr
& 0x7FF; /* low eleven bits */
4555 cmn_err(CE_CONT
, " table size = %X entries\n", t_size
);
4557 offset
= t_offset
; /* reuse this for offset from BAR */
4558 #ifdef HERMON_SUPPORTS_MSIX_BAR
4559 cmn_err(CE_CONT
, "First 2 table entries behind BAR2 \n");
4560 for (i
= 0; i
< 2; i
++) {
4561 for (j
= 0; j
< 4; j
++, offset
+= 4) {
4562 msix_data
= ddi_get32(state
->hs_reg_msihdl
,
4563 (uint32_t *)((uintptr_t)state
->hs_reg_msi_baseaddr
4565 cmn_err(CE_CONT
, "MSI table entry %d, dword %d == %X\n",
4574 * X86 fastreboot support functions.
4575 * These functions are used to save/restore MSI-X table/PBA and also
4576 * to disable MSI-X interrupts in hermon_quiesce().
4579 /* Return the message control for MSI-X */
4581 get_msix_ctrl(dev_info_t
*dip
)
4583 ushort_t msix_ctrl
= 0, caps_ctrl
= 0;
4584 hermon_state_t
*state
= ddi_get_soft_state(hermon_statep
,
4585 DEVI(dip
)->devi_instance
);
4586 ddi_acc_handle_t pci_cfg_hdl
= hermon_get_pcihdl(state
);
4587 ASSERT(pci_cfg_hdl
!= NULL
);
4589 if ((PCI_CAP_LOCATE(pci_cfg_hdl
,
4590 PCI_CAP_ID_MSI_X
, &caps_ctrl
) == DDI_SUCCESS
)) {
4591 if ((msix_ctrl
= PCI_CAP_GET16(pci_cfg_hdl
, 0, caps_ctrl
,
4592 PCI_MSIX_CTRL
)) == PCI_CAP_EINVAL16
)
4595 ASSERT(msix_ctrl
!= 0);
4600 /* Return the MSI-X table size */
4602 get_msix_tbl_size(dev_info_t
*dip
)
4604 ushort_t msix_ctrl
= get_msix_ctrl(dip
);
4605 ASSERT(msix_ctrl
!= 0);
4607 return (((msix_ctrl
& PCI_MSIX_TBL_SIZE_MASK
) + 1) *
4608 PCI_MSIX_VECTOR_SIZE
);
4611 /* Return the MSI-X PBA size */
4613 get_msix_pba_size(dev_info_t
*dip
)
4615 ushort_t msix_ctrl
= get_msix_ctrl(dip
);
4616 ASSERT(msix_ctrl
!= 0);
4618 return (((msix_ctrl
& PCI_MSIX_TBL_SIZE_MASK
) + 64) / 64 * 8);
4621 /* Set up the MSI-X table/PBA save area */
4623 hermon_set_msix_info(hermon_state_t
*state
)
4625 uint_t rnumber
, breg
, nregs
;
4626 ushort_t caps_ctrl
, msix_ctrl
;
4628 int reg_size
, addr_space
, offset
, *regs_list
, i
;
4631 * MSI-X BIR Index Table:
4632 * BAR indicator register (BIR) to Base Address register.
4634 uchar_t pci_msix_bir_index
[8] = {0x10, 0x14, 0x18, 0x1c,
4635 0x20, 0x24, 0xff, 0xff};
4637 /* Fastreboot data access attribute */
4638 ddi_device_acc_attr_t dev_attr
= {
4640 DDI_STRUCTURE_LE_ACC
,
4641 DDI_STRICTORDER_ACC
, /* attr access */
4645 ddi_acc_handle_t pci_cfg_hdl
= hermon_get_pcihdl(state
);
4646 ASSERT(pci_cfg_hdl
!= NULL
);
4648 if ((PCI_CAP_LOCATE(pci_cfg_hdl
,
4649 PCI_CAP_ID_MSI_X
, &caps_ctrl
) == DDI_SUCCESS
)) {
4650 if ((msix_ctrl
= PCI_CAP_GET16(pci_cfg_hdl
, 0, caps_ctrl
,
4651 PCI_MSIX_CTRL
)) == PCI_CAP_EINVAL16
)
4654 ASSERT(msix_ctrl
!= 0);
4656 state
->hs_msix_tbl_offset
= PCI_CAP_GET32(pci_cfg_hdl
, 0, caps_ctrl
,
4657 PCI_MSIX_TBL_OFFSET
);
4659 /* Get the BIR for MSI-X table */
4660 breg
= pci_msix_bir_index
[state
->hs_msix_tbl_offset
&
4661 PCI_MSIX_TBL_BIR_MASK
];
4662 ASSERT(breg
!= 0xFF);
4664 /* Set the MSI-X table offset */
4665 state
->hs_msix_tbl_offset
= state
->hs_msix_tbl_offset
&
4666 ~PCI_MSIX_TBL_BIR_MASK
;
4668 /* Set the MSI-X table size */
4669 state
->hs_msix_tbl_size
= ((msix_ctrl
& PCI_MSIX_TBL_SIZE_MASK
) + 1) *
4670 PCI_MSIX_VECTOR_SIZE
;
4672 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY
, state
->hs_dip
,
4673 DDI_PROP_DONTPASS
, "reg", (int **)®s_list
, &nregs
) !=
4677 reg_size
= sizeof (pci_regspec_t
) / sizeof (int);
4679 /* Check the register number for MSI-X table */
4680 for (i
= 1, rnumber
= 0; i
< nregs
/reg_size
; i
++) {
4681 rp
= (pci_regspec_t
*)®s_list
[i
* reg_size
];
4682 addr_space
= rp
->pci_phys_hi
& PCI_ADDR_MASK
;
4683 offset
= PCI_REG_REG_G(rp
->pci_phys_hi
);
4685 if ((offset
== breg
) && ((addr_space
== PCI_ADDR_MEM32
) ||
4686 (addr_space
== PCI_ADDR_MEM64
))) {
4691 ASSERT(rnumber
!= 0);
4692 state
->hs_msix_tbl_rnumber
= rnumber
;
4694 /* Set device attribute version and access according to Hermon FM */
4695 dev_attr
.devacc_attr_version
= hermon_devacc_attr_version(state
);
4696 dev_attr
.devacc_attr_access
= hermon_devacc_attr_access(state
);
4698 /* Map the entire MSI-X vector table */
4699 if (hermon_regs_map_setup(state
, state
->hs_msix_tbl_rnumber
,
4700 (caddr_t
*)&state
->hs_msix_tbl_addr
, state
->hs_msix_tbl_offset
,
4701 state
->hs_msix_tbl_size
, &dev_attr
,
4702 &state
->hs_fm_msix_tblhdl
) != DDI_SUCCESS
) {
4706 state
->hs_msix_pba_offset
= PCI_CAP_GET32(pci_cfg_hdl
, 0, caps_ctrl
,
4707 PCI_MSIX_PBA_OFFSET
);
4709 /* Get the BIR for MSI-X PBA */
4710 breg
= pci_msix_bir_index
[state
->hs_msix_pba_offset
&
4711 PCI_MSIX_PBA_BIR_MASK
];
4712 ASSERT(breg
!= 0xFF);
4714 /* Set the MSI-X PBA offset */
4715 state
->hs_msix_pba_offset
= state
->hs_msix_pba_offset
&
4716 ~PCI_MSIX_PBA_BIR_MASK
;
4718 /* Set the MSI-X PBA size */
4719 state
->hs_msix_pba_size
=
4720 ((msix_ctrl
& PCI_MSIX_TBL_SIZE_MASK
) + 64) / 64 * 8;
4722 /* Check the register number for MSI-X PBA */
4723 for (i
= 1, rnumber
= 0; i
< nregs
/reg_size
; i
++) {
4724 rp
= (pci_regspec_t
*)®s_list
[i
* reg_size
];
4725 addr_space
= rp
->pci_phys_hi
& PCI_ADDR_MASK
;
4726 offset
= PCI_REG_REG_G(rp
->pci_phys_hi
);
4728 if ((offset
== breg
) && ((addr_space
== PCI_ADDR_MEM32
) ||
4729 (addr_space
== PCI_ADDR_MEM64
))) {
4734 ASSERT(rnumber
!= 0);
4735 state
->hs_msix_pba_rnumber
= rnumber
;
4736 ddi_prop_free(regs_list
);
4738 /* Map in the MSI-X Pending Bit Array */
4739 if (hermon_regs_map_setup(state
, state
->hs_msix_pba_rnumber
,
4740 (caddr_t
*)&state
->hs_msix_pba_addr
, state
->hs_msix_pba_offset
,
4741 state
->hs_msix_pba_size
, &dev_attr
,
4742 &state
->hs_fm_msix_pbahdl
) != DDI_SUCCESS
) {
4743 hermon_regs_map_free(state
, &state
->hs_fm_msix_tblhdl
);
4744 state
->hs_fm_msix_tblhdl
= NULL
;
4748 /* Set the MSI-X table save area */
4749 state
->hs_msix_tbl_entries
= kmem_alloc(state
->hs_msix_tbl_size
,
4752 /* Set the MSI-X PBA save area */
4753 state
->hs_msix_pba_entries
= kmem_alloc(state
->hs_msix_pba_size
,
4757 /* Disable Hermon interrupts */
4759 hermon_intr_disable(hermon_state_t
*state
)
4761 ushort_t msix_ctrl
= 0, caps_ctrl
= 0;
4762 ddi_acc_handle_t pci_cfg_hdl
= hermon_get_pcihdl(state
);
4763 ddi_acc_handle_t msix_tblhdl
= hermon_get_msix_tblhdl(state
);
4765 ASSERT(pci_cfg_hdl
!= NULL
&& msix_tblhdl
!= NULL
);
4766 ASSERT(state
->hs_intr_types_avail
&
4767 (DDI_INTR_TYPE_FIXED
| DDI_INTR_TYPE_MSI
| DDI_INTR_TYPE_MSIX
));
4770 * Check if MSI-X interrupts are used. If so, disable MSI-X interupts.
4771 * If not, since Hermon doesn't support MSI interrupts, assuming the
4772 * legacy interrupt is used instead, disable the legacy interrupt.
4774 if ((state
->hs_cfg_profile
->cp_use_msi_if_avail
!= 0) &&
4775 (state
->hs_intr_types_avail
& DDI_INTR_TYPE_MSIX
)) {
4777 if ((PCI_CAP_LOCATE(pci_cfg_hdl
,
4778 PCI_CAP_ID_MSI_X
, &caps_ctrl
) == DDI_SUCCESS
)) {
4779 if ((msix_ctrl
= PCI_CAP_GET16(pci_cfg_hdl
, 0,
4780 caps_ctrl
, PCI_MSIX_CTRL
)) == PCI_CAP_EINVAL16
)
4781 return (DDI_FAILURE
);
4783 ASSERT(msix_ctrl
!= 0);
4785 if (!(msix_ctrl
& PCI_MSIX_ENABLE_BIT
))
4786 return (DDI_SUCCESS
);
4788 /* Clear all inums in MSI-X table */
4789 for (i
= 0; i
< get_msix_tbl_size(state
->hs_dip
);
4790 i
+= PCI_MSIX_VECTOR_SIZE
) {
4791 for (j
= 0; j
< PCI_MSIX_VECTOR_SIZE
; j
+= 4) {
4792 char *addr
= state
->hs_msix_tbl_addr
+ i
+ j
;
4793 ddi_put32(msix_tblhdl
,
4794 (uint32_t *)(uintptr_t)addr
, 0x0);
4798 /* Disable MSI-X interrupts */
4799 msix_ctrl
&= ~PCI_MSIX_ENABLE_BIT
;
4800 PCI_CAP_PUT16(pci_cfg_hdl
, 0, caps_ctrl
, PCI_MSIX_CTRL
,
4804 uint16_t cmdreg
= pci_config_get16(pci_cfg_hdl
, PCI_CONF_COMM
);
4805 ASSERT(state
->hs_intr_types_avail
& DDI_INTR_TYPE_FIXED
);
4807 /* Disable the legacy interrupts */
4808 cmdreg
|= PCI_COMM_INTX_DISABLE
;
4809 pci_config_put16(pci_cfg_hdl
, PCI_CONF_COMM
, cmdreg
);
4812 return (DDI_SUCCESS
);
4815 /* Hermon quiesce(9F) entry */
4817 hermon_quiesce(dev_info_t
*dip
)
4819 hermon_state_t
*state
= ddi_get_soft_state(hermon_statep
,
4820 DEVI(dip
)->devi_instance
);
4821 ddi_acc_handle_t pcihdl
= hermon_get_pcihdl(state
);
4822 ddi_acc_handle_t cmdhdl
= hermon_get_cmdhdl(state
);
4823 ddi_acc_handle_t msix_tbl_hdl
= hermon_get_msix_tblhdl(state
);
4824 ddi_acc_handle_t msix_pba_hdl
= hermon_get_msix_pbahdl(state
);
4825 uint32_t sem
, reset_delay
= state
->hs_cfg_profile
->cp_sw_reset_delay
;
4828 int status
, i
, j
, loopcnt
;
4831 ASSERT(state
!= NULL
);
4833 /* start fastreboot */
4834 state
->hs_quiescing
= B_TRUE
;
4836 /* If it's in maintenance mode, do nothing but return with SUCCESS */
4837 if (!HERMON_IS_OPERATIONAL(state
->hs_operational_mode
)) {
4838 return (DDI_SUCCESS
);
4841 /* suppress Hermon FM ereports */
4842 if (hermon_get_state(state
) & HCA_EREPORT_FM
) {
4843 hermon_clr_state_nolock(state
, HCA_EREPORT_FM
);
4846 /* Shutdown HCA ports */
4847 if (hermon_hca_ports_shutdown(state
,
4848 state
->hs_cfg_profile
->cp_num_ports
) != HERMON_CMD_SUCCESS
) {
4849 state
->hs_quiescing
= B_FALSE
;
4850 return (DDI_FAILURE
);
4854 if (hermon_close_hca_cmd_post(state
, HERMON_CMD_NOSLEEP_SPIN
) !=
4855 HERMON_CMD_SUCCESS
) {
4856 state
->hs_quiescing
= B_FALSE
;
4857 return (DDI_FAILURE
);
4860 /* Disable interrupts */
4861 if (hermon_intr_disable(state
) != DDI_SUCCESS
) {
4862 state
->hs_quiescing
= B_FALSE
;
4863 return (DDI_FAILURE
);
4867 * Query the PCI capabilities of the HCA device, but don't process
4868 * the VPD until after reset.
4870 if (hermon_pci_capability_list(state
, pcihdl
) != DDI_SUCCESS
) {
4871 state
->hs_quiescing
= B_FALSE
;
4872 return (DDI_FAILURE
);
4876 * Read all PCI config info (reg0...reg63). Note: According to the
4877 * Hermon software reset application note, we should not read or
4878 * restore the values in reg22 and reg23.
4879 * NOTE: For Hermon (and Arbel too) it says to restore the command
4880 * register LAST, and technically, you need to restore the
4881 * PCIE Capability "device control" and "link control" (word-sized,
4882 * at offsets 0x08 and 0x10 from the capbility ID respectively).
4883 * We hold off restoring the command register - offset 0x4 - till last
4886 /* 1st, wait for the semaphore assure accessibility - per PRM */
4888 for (i
= 0; i
< NANOSEC
/MICROSEC
/* 1sec timeout */; i
++) {
4889 sem
= ddi_get32(cmdhdl
, state
->hs_cmd_regs
.sw_semaphore
);
4897 /* Check if timeout happens */
4899 state
->hs_quiescing
= B_FALSE
;
4900 return (DDI_FAILURE
);
4903 /* MSI-X interrupts are used, save the MSI-X table */
4904 if (msix_tbl_hdl
&& msix_pba_hdl
) {
4905 /* save MSI-X table */
4906 for (i
= 0; i
< get_msix_tbl_size(state
->hs_dip
);
4907 i
+= PCI_MSIX_VECTOR_SIZE
) {
4908 for (j
= 0; j
< PCI_MSIX_VECTOR_SIZE
; j
+= 4) {
4909 char *addr
= state
->hs_msix_tbl_addr
+ i
+ j
;
4910 data32
= ddi_get32(msix_tbl_hdl
,
4911 (uint32_t *)(uintptr_t)addr
);
4912 *(uint32_t *)(uintptr_t)(state
->
4913 hs_msix_tbl_entries
+ i
+ j
) = data32
;
4916 /* save MSI-X PBA */
4917 for (i
= 0; i
< get_msix_pba_size(state
->hs_dip
); i
+= 8) {
4918 char *addr
= state
->hs_msix_pba_addr
+ i
;
4919 data64
= ddi_get64(msix_pba_hdl
,
4920 (uint64_t *)(uintptr_t)addr
);
4921 *(uint64_t *)(uintptr_t)(state
->
4922 hs_msix_pba_entries
+ i
) = data64
;
4926 /* save PCI config space */
4927 for (i
= 0; i
< HERMON_SW_RESET_NUMREGS
; i
++) {
4928 if ((i
!= HERMON_SW_RESET_REG22_RSVD
) &&
4929 (i
!= HERMON_SW_RESET_REG23_RSVD
)) {
4930 state
->hs_cfg_data
[i
] =
4931 pci_config_get32(pcihdl
, i
<< 2);
4936 ddi_put32(cmdhdl
, state
->hs_cmd_regs
.sw_reset
, HERMON_SW_RESET_START
);
4939 * This delay is required so as not to cause a panic here. If the
4940 * device is accessed too soon after reset it will not respond to
4941 * config cycles, causing a Master Abort and panic.
4943 drv_usecwait(reset_delay
);
4945 /* Poll waiting for the device to finish resetting */
4946 loopcnt
= 100; /* 100 times @ 100 usec - total delay 10 msec */
4947 while ((pci_config_get32(pcihdl
, 0) & 0x0000FFFF) != PCI_VENID_MLX
) {
4948 drv_usecwait(HERMON_SW_RESET_POLL_DELAY
);
4950 break; /* just in case, break and go on */
4953 state
->hs_quiescing
= B_FALSE
;
4954 return (DDI_FAILURE
);
4957 /* Restore the config info */
4958 for (i
= 0; i
< HERMON_SW_RESET_NUMREGS
; i
++) {
4959 if (i
== 1) continue; /* skip the status/ctrl reg */
4960 if ((i
!= HERMON_SW_RESET_REG22_RSVD
) &&
4961 (i
!= HERMON_SW_RESET_REG23_RSVD
)) {
4962 pci_config_put32(pcihdl
, i
<< 2, state
->hs_cfg_data
[i
]);
4966 /* If MSI-X interrupts are used, restore the MSI-X table */
4967 if (msix_tbl_hdl
&& msix_pba_hdl
) {
4968 /* restore MSI-X PBA */
4969 for (i
= 0; i
< get_msix_pba_size(state
->hs_dip
); i
+= 8) {
4970 char *addr
= state
->hs_msix_pba_addr
+ i
;
4971 data64
= *(uint64_t *)(uintptr_t)
4972 (state
->hs_msix_pba_entries
+ i
);
4973 ddi_put64(msix_pba_hdl
,
4974 (uint64_t *)(uintptr_t)addr
, data64
);
4976 /* restore MSI-X table */
4977 for (i
= 0; i
< get_msix_tbl_size(state
->hs_dip
);
4978 i
+= PCI_MSIX_VECTOR_SIZE
) {
4979 for (j
= 0; j
< PCI_MSIX_VECTOR_SIZE
; j
+= 4) {
4980 char *addr
= state
->hs_msix_tbl_addr
+ i
+ j
;
4981 data32
= *(uint32_t *)(uintptr_t)
4982 (state
->hs_msix_tbl_entries
+ i
+ j
);
4983 ddi_put32(msix_tbl_hdl
,
4984 (uint32_t *)(uintptr_t)addr
, data32
);
4990 * PCI Express Capability - we saved during capability list, and
4991 * we'll restore them here.
4993 offset
= state
->hs_pci_cap_offset
;
4994 data32
= state
->hs_pci_cap_devctl
;
4995 pci_config_put32(pcihdl
, offset
+ HERMON_PCI_CAP_DEV_OFFS
, data32
);
4996 data32
= state
->hs_pci_cap_lnkctl
;
4997 pci_config_put32(pcihdl
, offset
+ HERMON_PCI_CAP_LNK_OFFS
, data32
);
4999 /* restore the command register */
5000 pci_config_put32(pcihdl
, 0x04, (state
->hs_cfg_data
[1] | 0x0006));
5002 return (DDI_SUCCESS
);