9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER START
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The contents of this file are subject to the terms of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Common Development and Distribution License (the "License").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You may not use this file except in compliance with the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or http://www.opensolaris.org/os/licensing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * See the License for the specific language governing permissions
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and limitations under the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * When distributing Covered Code, include this CDDL HEADER in each
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If applicable, add the following below this CDDL HEADER, with the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER END
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor.c
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Tavor (InfiniBand) HCA Driver attach/detach Routines
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Implements all the routines necessary for the attach, setup,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * initialization (and subsequent possible teardown and detach) of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Tavor InfiniBand HCA driver.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/types.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/file.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/open.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/conf.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/sunddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/modctl.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/stat.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/pci.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/pci_cap.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/bitmap.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/policy.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ib/adapters/tavor/tavor.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/pci.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* Tavor HCA State Pointer */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorvoid *tavor_statep;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The Tavor "userland resource database" is common to instances of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Tavor HCA driver. This structure "tavor_userland_rsrc_db" contains all
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the necessary information to maintain it.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_umap_db_t tavor_userland_rsrc_db;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_attach(dev_info_t *, ddi_attach_cmd_t);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_detach(dev_info_t *, ddi_detach_cmd_t);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_open(dev_t *, int, int, cred_t *);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_close(dev_t, int, int, cred_t *);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_drv_init(tavor_state_t *state, dev_info_t *dip, int instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_drv_fini(tavor_state_t *state);
e99353559fac68ede91471daee91660d64cc7894Eiji Otastatic void tavor_drv_fini2(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_isr_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_isr_fini(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_hw_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_hw_fini(tavor_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_drv_cleanup_level_t cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_soft_state_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_soft_state_fini(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_hca_port_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_hca_ports_shutdown(tavor_state_t *state, uint_t num_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_hca_config_setup(tavor_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_initqueryhca_t *inithca);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_internal_uarpgs_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_internal_uarpgs_fini(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_special_qp_contexts_reserve(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_special_qp_contexts_unreserve(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_sw_reset(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_mcg_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_mcg_fini(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_fw_version_check(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_device_info_report(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_pci_capability_list(tavor_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_pci_capability_vpd(tavor_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t hdl, uint_t offset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_pci_read_vpd(ddi_acc_handle_t hdl, uint_t offset,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t addr, uint32_t *data);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_pci_capability_pcix(tavor_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t hdl, uint_t offset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_intr_or_msi_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_add_intrs(tavor_state_t *state, int intr_type);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_intr_or_msi_fini(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* X86 fastreboot support */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_intr_disable(tavor_state_t *);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_quiesce(dev_info_t *);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* Character/Block Operations */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic struct cb_ops tavor_cb_ops = {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_open, /* open */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_close, /* close */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* strategy (block) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* print (block) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* dump (block) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* read */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* write */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_ioctl, /* ioctl */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_devmap, /* devmap */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor NULL, /* mmap */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* segmap */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nochpoll, /* chpoll */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_prop_op, /* prop_op */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor NULL, /* streams */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor D_NEW | D_MP |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor D_64BIT | D_HOTPLUG |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor D_DEVMAP, /* flags */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor CB_REV /* rev */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor};
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* Driver Operations */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic struct dev_ops tavor_ops = {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DEVO_REV, /* struct rev */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor 0, /* refcnt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_getinfo, /* getinfo */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nulldev, /* identify */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nulldev, /* probe */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_attach, /* attach */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_detach, /* detach */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* reset */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &tavor_cb_ops, /* cb_ops */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor NULL, /* bus_ops */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodev, /* power */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_quiesce, /* devo_quiesce */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor};
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* Module Driver Info */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic struct modldrv tavor_modldrv = {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &mod_driverops,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Tavor InfiniBand HCA Driver",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &tavor_ops
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor};
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* Module Linkage */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic struct modlinkage tavor_modlinkage = {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MODREV_1,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &tavor_modldrv,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor NULL
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor};
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This extern refers to the ibc_operations_t function vector that is defined
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * in the tavor_ci.c file.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorextern ibc_operations_t tavor_ibc_ops;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef NPROBE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorextern int tnf_mod_load(void);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorextern int tnf_mod_unload(struct modlinkage *mlp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * _init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef NPROBE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tnf_mod_load();
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_soft_state_init(&tavor_statep, sizeof (tavor_state_t),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (size_t)TAVOR_INITIAL_STATES);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_init_ssi_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef NPROBE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tnf_mod_unload(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibc_init(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_init_ibc_init_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_soft_state_fini(&tavor_statep);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef NPROBE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tnf_mod_unload(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = mod_install(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_init_modi_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_fini(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_soft_state_fini(&tavor_statep);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef NPROBE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tnf_mod_unload(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the Tavor "userland resources database" */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_init();
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * _info()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor_info(struct modinfo *modinfop)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_info);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = mod_info(&tavor_modlinkage, modinfop);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_info);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * _fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = mod_remove(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_fini_modr_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Destroy the Tavor "userland resources database" */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_fini();
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_fini(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_soft_state_fini(&tavor_statep);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef NPROBE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tnf_mod_unload(&tavor_modlinkage);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_getinfo()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dev_t dev;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor minor_t instance;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_getinfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (cmd) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case DDI_INFO_DEVT2DEVINFO:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dev = (dev_t)arg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor instance = TAVOR_DEV_INSTANCE(dev);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = ddi_get_soft_state(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_getinfo_gss_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_getinfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *result = (void *)state->ts_dip;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case DDI_INFO_DEVT2INSTANCE:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dev = (dev_t)arg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor instance = TAVOR_DEV_INSTANCE(dev);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *result = (void *)(uintptr_t)instance;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_getinfo_default_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_getinfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_open()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_open(dev_t *devp, int flag, int otyp, cred_t *credp)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_t *rsrcp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_entry_t *umapdb, *umapdb2;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor minor_t instance;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t key, value;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t tr_indx;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dev_t dev;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_open);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor instance = TAVOR_DEV_INSTANCE(*devp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = ddi_get_soft_state(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_open_gss_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_open);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (ENXIO);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Only allow driver to be opened for character access, and verify
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * whether exclusive access is allowed.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((otyp != OTYP_CHR) || ((flag & FEXCL) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor secpolicy_excl_open(credp) != 0)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_open_invflags_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_open);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (EINVAL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Search for the current process PID in the "userland resources
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * database". If it is not found, then attempt to allocate a UAR
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * page and add the ("key", "value") pair to the database.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: As a last step we always return a devp appropriate for
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the open. Either we return a new minor number (based on the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * instance and the UAR page index) or we return the current minor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * number for the given client process.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also add an entry to the database to allow for lookup from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "dev_t" to the current process PID. This is necessary because,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * under certain circumstance, the process PID that calls the Tavor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * close() entry point may not be the same as the one who called
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * open(). Specifically, this can happen if a child process calls
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the Tavor's open() entry point, gets a UAR page, maps it out (using
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * mmap()), and then exits without calling munmap(). Because mmap()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * adds a reference to the file descriptor, at the exit of the child
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * process the file descriptor is "inherited" by the parent (and will
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * be close()'d by the parent's PID only when it exits).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: We use the tavor_umap_db_find_nolock() and
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_umap_db_add_nolock() database access routines below (with
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * an explicit mutex_enter of the database lock - "tdl_umapdb_lock")
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to ensure that the multiple accesses (in this case searching for,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and then adding _two_ database entries) can be done atomically.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor key = ddi_get_pid();
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_enter(&tavor_userland_rsrc_db.tdl_umapdb_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_umap_db_find_nolock(instance, key,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLNX_UMAP_UARPG_RSRC, &value, 0, NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If we are in 'maintenance mode', we cannot alloc a UAR page.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * But we still need some rsrcp value, and a mostly unique
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tr_indx value. So we set rsrcp to NULL for maintenance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * mode, and use a rolling count for tr_indx. The field
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * 'ts_open_tr_indx' is used only in this maintenance mode
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * condition.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Otherwise, if we are in operational mode then we allocate
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the UAR page as normal, and use the rsrcp value and tr_indx
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * value from that allocation.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (!TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrcp = NULL;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tr_indx = state->ts_open_tr_indx++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Allocate a new UAR page for this process */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_rsrc_alloc(state, TAVOR_UARPG, 1,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_NOSLEEP, &rsrcp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_exit(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &tavor_userland_rsrc_db.tdl_umapdb_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_open_rsrcalloc_uarpg_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_open);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (EAGAIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tr_indx = rsrcp->tr_indx;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate an entry to track the UAR page resource in the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "userland resources database".
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor umapdb = tavor_umap_db_alloc(instance, key,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLNX_UMAP_UARPG_RSRC, (uint64_t)(uintptr_t)rsrcp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (umapdb == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* If in "maintenance mode", don't free the rsrc */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &rsrcp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_open_umap_db_alloc_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_open);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (EAGAIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Create a new device number. Minor number is a function of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the UAR page index (15 bits) and the device instance number
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (3 bits).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dev = makedevice(getmajor(*devp), (tr_indx <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_MINORNUM_SHIFT) | instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate another entry in the "userland resources database"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to track the association of the device number (above) to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the current process ID (in "key").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor umapdb2 = tavor_umap_db_alloc(instance, dev,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLNX_UMAP_PID_RSRC, (uint64_t)key);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (umapdb2 == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_free(umapdb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* If in "maintenance mode", don't free the rsrc */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &rsrcp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_open_umap_db_alloc_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_open);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (EAGAIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Add the entries to the database */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_add_nolock(umapdb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_add_nolock(umapdb2);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the same device number as on the original open()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * call. This was calculated as a function of the UAR page
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * index (top 16 bits) and the device instance number
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrcp = (tavor_rsrc_t *)(uintptr_t)value;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dev = makedevice(getmajor(*devp), (rsrcp->tr_indx <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_MINORNUM_SHIFT) | instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *devp = dev;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_open);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_close()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_close(dev_t dev, int flag, int otyp, cred_t *credp)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_t *rsrcp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_entry_t *umapdb;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_priv_t *priv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor minor_t instance;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t key, value;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_close);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor instance = TAVOR_DEV_INSTANCE(dev);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = ddi_get_soft_state(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_close_gss_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_close);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (ENXIO);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Search for "dev_t" in the "userland resources database". As
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * explained above in tavor_open(), we can't depend on using the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * current process ID here to do the lookup because the process
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that ultimately closes may not be the same one who opened
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (because of inheritance).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * So we lookup the "dev_t" (which points to the PID of the process
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that opened), and we remove the entry from the database (and free
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * it up). Then we do another query based on the PID value. And when
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we find that database entry, we free it up too and then free the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Tavor UAR page resource.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: We use the tavor_umap_db_find_nolock() database access
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * routine below (with an explicit mutex_enter of the database lock)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to ensure that the multiple accesses (which attempt to remove the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * two database entries) can be done atomically.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This works the same in both maintenance mode and HCA mode, except
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * for the call to tavor_rsrc_free(). In the case of maintenance mode,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * this call is not needed, as it was not allocated in tavor_open()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * above.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor key = dev;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_enter(&tavor_userland_rsrc_db.tdl_umapdb_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_umap_db_find_nolock(instance, key, MLNX_UMAP_PID_RSRC,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &value, TAVOR_UMAP_DB_REMOVE, &umapdb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the "tdb_priv" field is non-NULL, it indicates that
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * some "on close" handling is still necessary. Call
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_umap_db_handle_onclose_cb() to do the handling (i.e.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to invoke all the registered callbacks). Then free up
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the resources associated with "tdb_priv" and continue
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * closing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor priv = (tavor_umap_db_priv_t *)umapdb->tdbe_common.tdb_priv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (priv != NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_handle_onclose_cb(priv);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(priv, sizeof (tavor_umap_db_priv_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor umapdb->tdbe_common.tdb_priv = (void *)NULL;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_free(umapdb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Now do another lookup using PID as the key (copy it from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "value"). When this lookup is complete, the "value" field
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * will contain the tavor_rsrc_t pointer for the UAR page
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * resource.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor key = value;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_umap_db_find_nolock(instance, key,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLNX_UMAP_UARPG_RSRC, &value, TAVOR_UMAP_DB_REMOVE,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &umapdb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_umap_db_free(umapdb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* If in "maintenance mode", don't free the rsrc */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrcp = (tavor_rsrc_t *)(uintptr_t)value;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &rsrcp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_close);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_attach()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_clnt_hdl_t tmp_ibtfpriv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_status_t ibc_status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int instance;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_attach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifdef __lock_lint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tavor_quiesce(dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (cmd) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case DDI_ATTACH:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor instance = ddi_get_instance(dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_soft_state_zalloc(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_attach_ssz_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "tavor%d: driver failed to attach: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "attach_ssz_fail", instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto fail_attach_nomsg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = ddi_get_soft_state(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_soft_state_free(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_attach_gss_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "tavor%d: driver failed to attach: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "attach_gss_fail", instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto fail_attach_nomsg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* clear the attach error buffer */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG_INIT(state->ts_attach_buf);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initialize Tavor driver and hardware.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: If this initialization fails we may still wish to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * create a device node and remain operational so that Tavor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware can be updated/flashed (i.e. "maintenance mode").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If this is the case, then "ts_operational_mode" will be
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * equal to TAVOR_MAINTENANCE_MODE. We will not attempt to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * attach to the IBTF or register with the IBMF (i.e. no
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * InfiniBand interfaces will be enabled).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_drv_init(state, dip, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((status != DDI_SUCCESS) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (TAVOR_IS_OPERATIONAL(state->ts_operational_mode))) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_attach_drvinit_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto fail_attach;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Create the minor node for device */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_PSEUDO, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_drv_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "attach_create_mn_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_attach_create_mn_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto fail_attach;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If we are in "maintenance mode", then we don't want to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * register with the IBTF. All InfiniBand interfaces are
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * uninitialized, and the device is only capable of handling
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * requests to update/flash firmware (or test/debug requests).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Attach to InfiniBand Transport Framework (IBTF) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_status = ibc_attach(&tmp_ibtfpriv,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_ibtfinfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ibc_status != IBC_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_remove_minor_node(dip, "devctl");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_drv_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_attach_ibcattach_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "attach_ibcattach_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto fail_attach;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Now that we've successfully attached to the IBTF,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we enable all appropriate asynch and CQ events to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * be forwarded to the IBTF.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ENABLE_IBTF_CALLB(state, tmp_ibtfpriv);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_post_attach(state->ts_ibtfpriv);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Register agents with IB Mgmt Framework (IBMF) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_agent_handlers_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ibc_pre_detach(tmp_ibtfpriv, DDI_DETACH);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_QUIESCE_IBTF_CALLB(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_in_evcallb != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "unable to "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "quiesce Tavor IBTF callbacks");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_detach(tmp_ibtfpriv);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_remove_minor_node(dip, "devctl");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_drv_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_attach_agentinit_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "attach_agentinit_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto fail_attach;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Report that driver was loaded */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_report_dev(dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Send device information to log file */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_device_info_report(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Report attach in maintenance mode, if appropriate */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (!(TAVOR_IS_OPERATIONAL(state->ts_operational_mode))) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "tavor%d: driver attached "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "(for maintenance mode only)", state->ts_instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_attach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case DDI_RESUME:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Add code here for DDI_RESUME XXX */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_attach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_attach_default_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorfail_attach:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "tavor%d: driver failed to attach: %s", instance,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_attach_buf);
e99353559fac68ede91471daee91660d64cc7894Eiji Ota tavor_drv_fini2(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_soft_state_free(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorfail_attach_nomsg:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_attach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_detach()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from detach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_clnt_hdl_t tmp_ibtfpriv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_status_t ibc_status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int instance, status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_detach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor instance = ddi_get_instance(dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = ddi_get_soft_state(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_detach_gss_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_detach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (cmd) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case DDI_DETACH:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If we are in "maintenance mode", then we do not want to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * do teardown for any of the InfiniBand interfaces.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Specifically, this means not detaching from IBTF (we never
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * attached to begin with) and not deregistering from IBMF.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Unregister agents from IB Mgmt Framework (IBMF) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_agent_handlers_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_detach_agentfini_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_detach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Attempt the "pre-detach" from InfiniBand Transport
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Framework (IBTF). At this point the IBTF is still
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * capable of handling incoming asynch and completion
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * events. This "pre-detach" is primarily a mechanism
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to notify the appropriate IBTF clients that the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * HCA is being removed/offlined.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_status = ibc_pre_detach(state->ts_ibtfpriv, cmd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ibc_status != IBC_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_agent_handlers_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "failed to "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "restart Tavor agents");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_detach_ibcpredetach_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_detach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Before we can fully detach from the IBTF we need to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ensure that we have handled all outstanding event
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * callbacks. This is accomplished by quiescing the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * event callback mechanism. Note: if we are unable
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to successfully quiesce the callbacks, then this is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * an indication that something has probably gone
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * seriously wrong. We print out a warning, but
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * continue.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmp_ibtfpriv = state->ts_ibtfpriv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_QUIESCE_IBTF_CALLB(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_in_evcallb != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "unable to quiesce Tavor "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "IBTF callbacks");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Complete the detach from the IBTF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_detach(tmp_ibtfpriv);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Remove the minor node for device */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_remove_minor_node(dip, "devctl");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Only call tavor_drv_fini() if we are in Tavor HCA mode.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (Because if we are in "maintenance mode", then we never
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * successfully finished init.) Only report successful
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * detach for normal HCA mode.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Cleanup driver resources and shutdown hardware */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_drv_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor driver successfully "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "detached\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
e99353559fac68ede91471daee91660d64cc7894Eiji Ota tavor_drv_fini2(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_soft_state_free(tavor_statep, instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_detach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case DDI_SUSPEND:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Add code here for DDI_SUSPEND XXX */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_detach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_detach_default_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_detach);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_drv_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_drv_init(tavor_state_t *state, dev_info_t *dip, int instance)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_drv_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Save away devinfo and instance */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_dip = dip;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_instance = instance;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Check and set the operational mode of the device. If the driver is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * bound to the Tavor device in "maintenance mode", then this generally
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that either the device has been specifically jumpered to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * start in this mode or the firmware boot process has failed to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * successfully load either the primary or the secondary firmware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * image.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_HCA_MODE(state->ts_dip)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_operational_mode = TAVOR_HCA_MODE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (TAVOR_IS_COMPAT_MODE(state->ts_dip)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_operational_mode = TAVOR_COMPAT_MODE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (TAVOR_IS_MAINTENANCE_MODE(state->ts_dip)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_operational_mode = TAVOR_MAINTENANCE_MODE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_operational_mode = 0; /* invalid operational mode */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "unexpected device type detected");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_unexpected_dev_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initialize the Tavor hardware.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: If this routine returns an error, it is often an reasonably
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * good indication that something Tavor firmware-related has caused
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the failure. In order to give the user an opportunity (if desired)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to update or reflash the Tavor firmware image, we set
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "ts_operational_mode" flag (described above) to indicate that we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * wish to enter maintenance mode.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_hw_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_operational_mode = TAVOR_MAINTENANCE_MODE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "tavor%d: error during attach: %s", instance,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_attach_buf);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_drv_init_hwinit_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_drv_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup Tavor interrupt handler */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_isr_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, TAVOR_DRV_CLEANUP_ALL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_drv_init_isrinit_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_drv_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize Tavor softstate */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_soft_state_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_isr_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, TAVOR_DRV_CLEANUP_ALL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_drv_init_ssiinit_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_drv_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_drv_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_drv_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_drv_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_drv_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Cleanup Tavor softstate */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_soft_state_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Teardown Tavor interrupts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_isr_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Cleanup Tavor resources and shutdown hardware */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, TAVOR_DRV_CLEANUP_ALL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_drv_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
e99353559fac68ede91471daee91660d64cc7894Eiji Ota/*
e99353559fac68ede91471daee91660d64cc7894Eiji Ota * tavor_drv_fini2()
e99353559fac68ede91471daee91660d64cc7894Eiji Ota * Context: Only called from attach() and/or detach() path contexts
e99353559fac68ede91471daee91660d64cc7894Eiji Ota */
e99353559fac68ede91471daee91660d64cc7894Eiji Otastatic void
e99353559fac68ede91471daee91660d64cc7894Eiji Otatavor_drv_fini2(tavor_state_t *state)
e99353559fac68ede91471daee91660d64cc7894Eiji Ota{
e99353559fac68ede91471daee91660d64cc7894Eiji Ota TAVOR_TNF_ENTER(tavor_drv_fini2);
e99353559fac68ede91471daee91660d64cc7894Eiji Ota
e99353559fac68ede91471daee91660d64cc7894Eiji Ota /* TAVOR_DRV_CLEANUP_LEVEL1 */
e99353559fac68ede91471daee91660d64cc7894Eiji Ota if (state->ts_reg_cmdhdl) {
e99353559fac68ede91471daee91660d64cc7894Eiji Ota ddi_regs_map_free(&state->ts_reg_cmdhdl);
e99353559fac68ede91471daee91660d64cc7894Eiji Ota state->ts_reg_cmdhdl = NULL;
e99353559fac68ede91471daee91660d64cc7894Eiji Ota }
e99353559fac68ede91471daee91660d64cc7894Eiji Ota
e99353559fac68ede91471daee91660d64cc7894Eiji Ota /* TAVOR_DRV_CLEANUP_LEVEL0 */
e99353559fac68ede91471daee91660d64cc7894Eiji Ota if (state->ts_pci_cfghdl) {
e99353559fac68ede91471daee91660d64cc7894Eiji Ota pci_config_teardown(&state->ts_pci_cfghdl);
e99353559fac68ede91471daee91660d64cc7894Eiji Ota state->ts_pci_cfghdl = NULL;
e99353559fac68ede91471daee91660d64cc7894Eiji Ota }
e99353559fac68ede91471daee91660d64cc7894Eiji Ota
e99353559fac68ede91471daee91660d64cc7894Eiji Ota TAVOR_TNF_EXIT(tavor_drv_fini2);
e99353559fac68ede91471daee91660d64cc7894Eiji Ota}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_isr_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_isr_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_isr_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Add a handler for the interrupt or MSI
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_add_handler(state->ts_intrmsi_hdl, tavor_isr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (caddr_t)state, NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_isr_init_addhndlr_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_isr_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Enable the software interrupt. Note: Even though we are only
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * using one (1) interrupt/MSI, depending on the value returned in
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the capability flag, we have to call either ddi_intr_block_enable()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or ddi_intr_enable().
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_intrmsi_cap & DDI_INTR_FLAG_BLOCK) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_block_enable(&state->ts_intrmsi_hdl, 1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_isr_init_blockenable_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_isr_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_enable(state->ts_intrmsi_hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_isr_init_intrenable_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_isr_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Now that the ISR has been setup, arm all the EQs for event
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * generation.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_eq_arm_all(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_isr_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_isr_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_isr_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_isr_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Disable the software interrupt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_intrmsi_cap & DDI_INTR_FLAG_BLOCK) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ddi_intr_block_disable(&state->ts_intrmsi_hdl, 1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ddi_intr_disable(state->ts_intrmsi_hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Remove the software handler for the interrupt or MSI
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ddi_intr_remove_handler(state->ts_intrmsi_hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_isr_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_fix_error_buf()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach().
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The error_buf_addr returned from QUERY_FW is a PCI address.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We need to convert it to an offset from the base address,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * which is stored in the assigned-addresses property.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_fix_error_buf(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int assigned_addr_len;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pci_regspec_t *assigned_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, state->ts_dip,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_PROP_DONTPASS, "assigned-addresses", (int **)&assigned_addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uint_t *)&assigned_addr_len) != DDI_PROP_SUCCESS)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.error_buf_addr -= assigned_addr[0].pci_phys_low +
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((uint64_t)(assigned_addr[0].pci_phys_mid) << 32);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_prop_free(assigned_addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_hw_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_hw_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_drv_cleanup_level_t cleanup;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sm_nodeinfo_t nodeinfo;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t errorcode;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor off_t ddr_size;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int retries;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* This is where driver initialization begins */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup device access attributes */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_reg_accattr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_reg_accattr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_reg_accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup for PCI config read/write of HCA device */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = pci_config_setup(state->ts_dip, &state->ts_pci_cfghdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_PCI_config_space_regmap_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* This case is not the degraded one */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Map in Tavor registers (CMD, UAR, DDR) and setup offsets */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_regs_map_setup(state->ts_dip, TAVOR_CMD_BAR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_cmd_baseaddr, 0, 0, &state->ts_reg_accattr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_cmdhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_CMD_ddirms_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_CMD_ddirms_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_regs_map_setup(state->ts_dip, TAVOR_UAR_BAR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_uar_baseaddr, 0, 0, &state->ts_reg_accattr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_uarhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_UAR_ddirms_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_UAR_ddirms_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL2;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_dev_regsize(state->ts_dip, TAVOR_DDR_BAR, &ddr_size);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: ddi_dev_regsize() failed "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "(check HCA-attached DIMM memory?)\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_DDR_ddi_regsize_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_DDR_ddi_regsize_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#if !defined(_ELF64) && !defined(__sparc)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * For 32 bit x86/x64 kernels, where there is limited kernel virtual
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * memory available, define a minimal memory footprint. This is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * specified in order to not take up too much resources, thus starving
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * out others. Only specified if the HCA DIMM is equal to or greater
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * than 256MB.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: x86/x64 install and safemode boot are both 32bit.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddr_size = TAVOR_DDR_SIZE_MIN;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif /* !(_ELF64) && !(__sparc) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile_setting = ddr_size;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_regs_map_setup(state->ts_dip, TAVOR_DDR_BAR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_ddr_baseaddr, 0, ddr_size, &state->ts_reg_accattr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_ddrhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * On 32-bit platform testing (primarily x86), it was seen that the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ddi_regs_map_setup() call would fail because there wasn't enough
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * kernel virtual address space available to map in the entire 256MB
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DDR. So we add this check in here, so that if the 256 (or other
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * larger value of DDR) map in fails, that we fallback to try the lower
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * size of 128MB.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: If we only have 128MB of DDR in the system in the first place,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we don't try another ddi_regs_map_setup(), and just skip over this
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * check and return failures.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_ME_NORESOURCES && ddr_size > TAVOR_DDR_SIZE_128) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Try falling back to 128MB DDR mapping */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_regs_map_setup(state->ts_dip, TAVOR_DDR_BAR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_ddr_baseaddr, 0, TAVOR_DDR_SIZE_128,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_reg_accattr, &state->ts_reg_ddrhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * 128MB DDR mapping worked.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Set the updated config profile setting here.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_DDR_128mb_fallback_success,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_TRACE, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile_setting = TAVOR_DDR_SIZE_128;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_ME_RNUMBER_RANGE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: ddi_regs_map_setup() failed "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "(check HCA-attached DIMM memory?)\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_DDR_ddirms_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_DDR_ddirms_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL3;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup Tavor Host Command Register (HCR) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cmd_regs.hcr = (tavor_hw_hcr_t *)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_HCR_OFFSET);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup Tavor Event Cause Register (ecr and clr_ecr) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cmd_regs.ecr = (uint64_t *)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_ECR_OFFSET);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cmd_regs.clr_ecr = (uint64_t *)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_CLR_ECR_OFFSET);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup Tavor Software Reset register (sw_reset) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cmd_regs.sw_reset = (uint32_t *)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_SW_RESET_OFFSET);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup Tavor Clear Interrupt register (clr_int) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cmd_regs.clr_int = (uint64_t *)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_CLR_INT_OFFSET);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the Phase1 Tavor configuration profile */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_cfg_profile_init_phase1(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_cfginit_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_cfginit_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL4;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Do a software reset of the Tavor HW to ensure proper state */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_sw_reset(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_sw_reset_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_sw_reset_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Post the SYS_EN command to start the hardware */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_sys_en_cmd_post(state, TAVOR_CMD_SYS_EN_NORMAL,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &errorcode, TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((status == TAVOR_CMD_BAD_NVMEM) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (status == TAVOR_CMD_DDR_MEM_ERR)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: SYS_EN command failed: 0x%x "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "0x%" PRIx64 " (invalid firmware image?)\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status, errorcode);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: SYS_EN command failed: 0x%x "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "0x%" PRIx64 "\n", status, errorcode);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_sys_en_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_sys_en_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL5;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* First phase of init for Tavor configuration/resources */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_rsrc_init_phase1(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_rsrcinit1_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_rsrcinit1_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL6;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Query the DDR properties (e.g. total DDR size) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_cmn_query_cmd_post(state, QUERY_DDR, 0,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_ddr, sizeof (tavor_hw_queryddr_t),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: QUERY_DDR command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_query_ddr_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_query_ddr_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Figure out how big the firmware image (in DDR) is */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_cmn_query_cmd_post(state, QUERY_FW, 0, &state->ts_fw,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (tavor_hw_queryfw_t), TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: QUERY_FW command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_query_fw_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_query_fw_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (tavor_fix_error_buf(state) != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_fixerrorbuf_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_fixerrorbuf_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Validate that the FW version is appropriate */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_fw_version_check(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_operational_mode == TAVOR_HCA_MODE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Unsupported Tavor FW version: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "expected: %04d.%04d.%04d, "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "actual: %04d.%04d.%04d\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_FW_VER_MAJOR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_FW_VER_MINOR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_FW_VER_SUBMINOR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_major,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_minor,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_subminor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (state->ts_operational_mode == TAVOR_COMPAT_MODE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Unsupported Tavor Compat FW version: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "expected: %04d.%04d.%04d, "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "actual: %04d.%04d.%04d\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_COMPAT_FW_VER_MAJOR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_COMPAT_FW_VER_MINOR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_COMPAT_FW_VER_SUBMINOR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_major,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_minor,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_subminor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Unsupported FW version: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%04d.%04d.%04d\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_major,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_minor,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_subminor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_checkfwver_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_checkfwver_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_usecwait(10);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retries = 1000; /* retry up to 1 second before giving up */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorretry:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Call MOD_STAT_CFG to setup SRQ support (or disable) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_mod_stat_cfg_cmd_post(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retries > 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_usecwait(1000);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retries--;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto retry;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: MOD_STAT_CFG command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_mod_stat_cfg_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_mod_stat_cfg_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Figure out Tavor device limits */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_cmn_query_cmd_post(state, QUERY_DEV_LIM, 0,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_devlim, sizeof (tavor_hw_querydevlim_t),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: QUERY_DEV_LIM command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_query_devlim_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_query_devlim_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the Phase2 Tavor configuration profile */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_cfg_profile_init_phase2(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_cfginit2_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_cfginit2_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Second phase of init for Tavor configuration/resources */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_rsrc_init_phase2(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_rsrcinit2_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_rsrcinit2_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL7;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Miscellaneous query information */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_cmn_query_cmd_post(state, QUERY_ADAPTER, 0,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_adapter, sizeof (tavor_hw_queryadapter_t),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: QUERY_ADAPTER command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_query_adapter_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_query_adapter_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Prepare configuration for Tavor INIT_HCA command */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hca_config_setup(state, &state->ts_hcaparams);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Post command to init Tavor HCA */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_init_hca_cmd_post(state, &state->ts_hcaparams,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: INIT_HCA command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_init_hca_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_init_hca_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL8;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Allocate protection domain (PD) for Tavor internal use */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_pd_alloc(state, &state->ts_pdhdl_internal, TAVOR_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_internal_pd_alloc_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_internal_pd_alloc_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL9;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup Tavor internal UAR pages (0 and 1) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_internal_uarpgs_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_internal_uarpgs_alloc_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_internal_uarpgs_alloc_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL10;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Query and initialize the Tavor interrupt/MSI information */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_intr_or_msi_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_intr_or_msi_init_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "intr_or_msi_init_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL11;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup all of the Tavor EQs */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_eq_init_all(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_eqinitall_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_eqinitall_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL12;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Set aside contexts for QP0 and QP1 */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_special_qp_contexts_reserve(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_reserve_special_qp_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_reserve_special_qp_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL13;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize for multicast group handling */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_mcg_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_mcg_init_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_mcg_init_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_LEVEL14;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the Tavor IB port(s) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_hca_port_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_hca_port_init_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_hca_port_init_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cleanup = TAVOR_DRV_CLEANUP_ALL;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine NodeGUID and SystemImageGUID */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_getnodeinfo_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &nodeinfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: GetNodeInfo command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_getnodeinfo_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_getnodeinfo_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the NodeGUID value was set in OBP properties, then we use that
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * value. But we still print a message if the value we queried from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware does not match this value.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Otherwise if OBP value is not set then we use the value from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware unconditionally.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_cfg_profile->cp_nodeguid) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_nodeguid = state->ts_cfg_profile->cp_nodeguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_nodeguid = nodeinfo.NodeGUID;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_nodeguid != nodeinfo.NodeGUID) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!NodeGUID value queried from firmware "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "does not match value set by device property");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the SystemImageGUID value was set in OBP properties, then we use
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that value. But we still print a message if the value we queried
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * from firmware does not match this value.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Otherwise if OBP value is not set then we use the value from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware unconditionally.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_cfg_profile->cp_sysimgguid) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_sysimgguid = state->ts_cfg_profile->cp_sysimgguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_sysimgguid = nodeinfo.SystemImageGUID;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_sysimgguid != nodeinfo.SystemImageGUID) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!SystemImageGUID value queried from firmware "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "does not match value set by device property");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get NodeDescription */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_getnodedesc_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (sm_nodedesc_t *)&state->ts_nodedesc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: GetNodeDesc command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_fini(state, cleanup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_init_getnodedesc_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "hw_init_getnodedesc_cmd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_hw_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_hw_fini(tavor_state_t *state, tavor_drv_cleanup_level_t cleanup)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (cleanup) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If we add more driver initialization steps that should be cleaned
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * up here, we need to ensure that TAVOR_DRV_CLEANUP_ALL is still the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * first entry (i.e. corresponds to the last init step).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_ALL:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Shutdown the Tavor IB port(s) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_ports = state->ts_cfg_profile->cp_num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tavor_hca_ports_shutdown(state, num_ports);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL14:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Teardown resources used for multicast group handling */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_mcg_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL13:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Unreserve the special QP contexts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_special_qp_contexts_unreserve(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL12:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Attempt to teardown all event queues (EQ). If we fail
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * here then print a warning message and return. Something
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (either in HW or SW) has gone seriously wrong.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_eq_fini_all(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "failed to teardown EQs");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_fini_eqfiniall_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL11:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_intr_or_msi_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "failed to free intr/MSI");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_fini_intrmsifini_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL10:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the resources for the Tavor internal UAR pages */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_internal_uarpgs_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL9:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Free the PD that was used internally by Tavor software. If
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we fail here then print a warning and return. Something
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (probably software-related, but perhaps HW) has gone wrong.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_pd_free(state, &state->ts_pdhdl_internal);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "failed to free internal PD");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_fini_internal_pd_free_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL8:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Post the CLOSE_HCA command to Tavor firmware. If we fail
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * here then print a warning and return. Something (either in
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * HW or SW) has gone seriously wrong.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_close_hca_cmd_post(state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "failed to shutdown HCA");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_fini_closehcacmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL7:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Cleanup all the phase2 resources first */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_fini(state, TAVOR_RSRC_CLEANUP_ALL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL6:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Then cleanup the phase1 resources */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_fini(state, TAVOR_RSRC_CLEANUP_PHASE1_COMPLETE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL5:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Post the SYS_DIS command to Tavor firmware to shut
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * everything down again. If we fail here then print a
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * warning and return. Something (probably in HW, but maybe
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * in SW) has gone seriously wrong.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_sys_dis_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "failed to shutdown hardware");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_fini_sys_dis_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL4:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Teardown any resources allocated for the config profile */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_cfg_profile_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL3:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_regs_map_free(&state->ts_reg_ddrhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL2:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_regs_map_free(&state->ts_reg_uarhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* FALLTHROUGH */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL1:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_DRV_CLEANUP_LEVEL0:
e99353559fac68ede91471daee91660d64cc7894Eiji Ota /*
e99353559fac68ede91471daee91660d64cc7894Eiji Ota * LEVEL1 and LEVEL0 resources are freed in
e99353559fac68ede91471daee91660d64cc7894Eiji Ota * tavor_drv_fini2().
e99353559fac68ede91471daee91660d64cc7894Eiji Ota */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "unexpected driver cleanup level");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_hw_fini_default_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hw_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_soft_state_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_soft_state_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_hca_attr_t *hca_attr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t maxval, val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_hca_flags_t caps = IBT_HCA_NO_FLAGS;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The ibc_hca_info_t struct is passed to the IBTF. This is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * routine where we initialize it. Many of the init values come from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * either configuration variables or successful queries of the Tavor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hardware abilities
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor state->ts_ibtfinfo.hca_ci_vers = IBCI_V4;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_ibtfinfo.hca_handle = (ibc_hca_hdl_t)state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_ibtfinfo.hca_ops = &tavor_ibc_ops;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr = kmem_zalloc(sizeof (ibt_hca_attr_t), KM_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_ibtfinfo.hca_attr = hca_attr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor hca_attr->hca_dip = state->ts_dip;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_fw_major_version = state->ts_fw.fw_rev_major;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_fw_minor_version = state->ts_fw.fw_rev_minor;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_fw_micro_version = state->ts_fw.fw_rev_subminor;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine HCA capabilities:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * No default support for IBT_HCA_RD, IBT_HCA_RAW_MULTICAST,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * IBT_HCA_ATOMICS_GLOBAL, IBT_HCA_RESIZE_CHAN, IBT_HCA_INIT_TYPE,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or IBT_HCA_SHUTDOWN_PORT
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * But IBT_HCA_AH_PORT_CHECK, IBT_HCA_SQD_RTS_PORT, IBT_HCA_SI_GUID,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * IBT_HCA_RNR_NAK, and IBT_HCA_CURRENT_QP_STATE are always
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * supported
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * All other features are conditionally supported, depending on the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * status return by the Tavor HCA (in QUERY_DEV_LIM)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_devlim.ud_multi) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps |= IBT_HCA_UD_MULTICAST;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_devlim.atomic) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps |= IBT_HCA_ATOMICS_HCA;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_devlim.apm) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps |= IBT_HCA_AUTO_PATH_MIG;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_devlim.pkey_v) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps |= IBT_HCA_PKEY_CNTR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_devlim.qkey_v) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps |= IBT_HCA_QKEY_CNTR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_cfg_profile->cp_srq_enable) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps |= IBT_HCA_SRQ | IBT_HCA_RESIZE_SRQ;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps |= (IBT_HCA_AH_PORT_CHECK | IBT_HCA_SQD_SQD_PORT |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IBT_HCA_SI_GUID | IBT_HCA_RNR_NAK | IBT_HCA_CURRENT_QP_STATE |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IBT_HCA_PORT_UP | IBT_HCA_SQD_STATE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_flags = caps;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor hca_attr->hca_flags2 = IBT_HCA2_DMA_MR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine VendorID, DeviceID, and revision ID */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_vendor_id = state->ts_adapter.vendor_id;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_device_id = state->ts_adapter.device_id;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_version_id = state->ts_adapter.rev_id;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine number of available QPs and max QP size. Number of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * available QPs is determined by subtracting the number of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "reserved QPs" (i.e. reserved for firmware use) from the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * total number configured.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_qp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_qp = val - ((uint64_t)1 <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_devlim.log_rsvd_qp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_qp_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_qp_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_maxqpsz_toobig_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max QP size "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxsz, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_maxqpsz_toobig_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_qp_sz = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine max scatter-gather size in WQEs */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = state->ts_devlim.max_sg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_wqe_max_sgl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_toomanysgl_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of sgl "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxsgl, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_toomanysgl_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* If the rounded value for max SGL is too large, cap it */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_cfg_profile->cp_wqe_real_max_sgl > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_wqe_real_max_sgl = maxval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = maxval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_wqe_real_max_sgl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_sgl = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_rd_sgl = 0; /* zero because RD is unsupported */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine number of available CQs and max CQ size. Number of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * available CQs is determined by subtracting the number of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "reserved CQs" (i.e. reserved for firmware use) from the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * total number configured.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_cq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_cq = val - ((uint64_t)1 <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_devlim.log_rsvd_cq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_cq_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_cq_sz) - 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_maxcqsz_toobig_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max CQ size "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxsz, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_maxcqsz_toobig_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_cq_sz = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine number of available SRQs and max SRQ size. Number of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * available SRQs is determined by subtracting the number of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "reserved SRQs" (i.e. reserved for firmware use) from the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * total number configured.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_srq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_srqs = val - ((uint64_t)1 <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_devlim.log_rsvd_srq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_srq_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_srq_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_maxsrqsz_toobig_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max SRQ size "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxsz, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_maxsrqsz_toobig_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_srqs_sz = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_srq_max_sgl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = state->ts_devlim.max_sg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_toomanysrqsgl_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of srq "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "sgl exceeds device maximum", tnf_uint, maxsgl, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_toomanysrqsgl_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_srq_sgl = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine supported HCA page sizes
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * XXX
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * For now we simply return the system pagesize as the only supported
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * pagesize
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_page_sz = ((PAGESIZE == (1 << 13)) ? IBT_PAGE_8K :
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IBT_PAGE_4K);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine number of available MemReg, MemWin, and their max size.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Number of available MRs and MWs is determined by subtracting
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the number of "reserved MPTs" (i.e. reserved for firmware use)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * from the total number configured for each.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_mpt);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_memr = val - ((uint64_t)1 <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_devlim.log_rsvd_mpt);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_mem_win = val - ((uint64_t)1 <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_devlim.log_rsvd_mpt);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = state->ts_devlim.log_max_mrw_sz;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_log_max_mrw_sz;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_maxmrwsz_toobig_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max mrw size "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxsz, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_maxmrwsz_toobig_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_memr_len = ((uint64_t)1 << val);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine RDMA/Atomic properties */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_rdb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_rsc = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_hca_max_rdma_in_qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_rdma_in_qp = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_hca_max_rdma_out_qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_rdma_out_qp = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_rdma_in_ee = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_rdma_out_ee = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine maximum number of raw IPv6 and Ether QPs. Set to 0
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * because neither type of raw QP is supported
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_ipv6_qp = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_ether_qp = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine max number of MCGs and max QP-per-MCG */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_qp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_mcg_qps = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_mcg);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_mcg = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_num_qp_per_mcg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_qp_per_mcg = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine max number partitions (i.e. PKeys) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_pkey);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)state->ts_cfg_profile->cp_num_ports <<
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_log_max_pkeytbl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_toomanypkey_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of PKeys "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxpkey, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_toomanypkey_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_partitions = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine number of ports */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = state->ts_devlim.num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = state->ts_cfg_profile->cp_num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((val > maxval) || (val == 0)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_toomanyports_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of ports "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxports, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_toomanyports_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_nports = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Copy NodeGUID and SystemImageGUID from softstate */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_node_guid = state->ts_nodeguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_si_guid = state->ts_sysimgguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine local ACK delay. Use the value suggested by the Tavor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hardware (from the QUERY_DEV_LIM command)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_local_ack_delay = state->ts_devlim.ca_ack_delay;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine max SGID table and PKey table sizes */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_gidtbl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_port_sgid_tbl_sz = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_pkeytbl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_port_pkey_tbl_sz = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine max number of PDs */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_pd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_pd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_toomanypd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of PD "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxpd, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_toomanypd_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_pd = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine max number of Address Handles */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_av);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_ah);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_soft_state_init_toomanyah_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of AH "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "exceeds device maximum", tnf_uint, maxah, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_toomanyah_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_ah = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* No RDDs or EECs (since Reliable Datagram is not supported) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_rdd = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hca_attr->hca_max_eec = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize lock for reserved UAR page access */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_init(&state->ts_uar_lock, NULL, MUTEX_DRIVER,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the flash fields */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw_flashstarted = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_init(&state->ts_fw_flashlock, NULL, MUTEX_DRIVER,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the lock for the info ioctl */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_init(&state->ts_info_lock, NULL, MUTEX_DRIVER,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the AVL tree for QP number support */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_qpn_avl_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the kstat info structure */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_kstat_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_qpn_avl_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_info_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_fw_flashlock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_uar_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_soft_state_init_kstatinit_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_ATTACH_MSG(state->ts_attach_buf,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "soft_state_init_kstatinit_fail");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_soft_state_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Called only from detach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_soft_state_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_soft_state_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Teardown the kstat info */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_kstat_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Teardown the AVL tree for QP number support */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_qpn_avl_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up info ioctl mutex */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_info_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up flash mutex */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_fw_flashlock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the UAR page access mutex */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_uar_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the hca_attr struct */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(state->ts_ibtfinfo.hca_attr, sizeof (ibt_hca_attr_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_soft_state_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_hca_config_setup()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_hca_config_setup(tavor_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_initqueryhca_t *inithca)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t ddr_baseaddr, ddr_base_map_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t offset, addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t mcg_size;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_hca_config_setup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Set "host endianness". Default is big endian */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifdef _LITTLE_ENDIAN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->big_endian = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#else
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->big_endian = 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* No Address Vector Protection, but Port Checking on by default */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->udav_chk = TAVOR_UDAV_PROTECT_DISABLED;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->udav_port_chk = TAVOR_UDAV_PORTCHK_ENABLED;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddr_baseaddr = (uint64_t)(uintptr_t)state->ts_reg_ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddr_base_map_addr = (uint64_t)state->ts_ddr.ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup QPC table */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_QPC];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.qpc_baseaddr_h = (addr >> 32);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.qpc_baseaddr_l = (addr & 0xFFFFFFFF) >> 7;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.log_num_qp = state->ts_cfg_profile->cp_log_num_qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup EEC table (initialize to zero - RD unsupported) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.eec_baseaddr_h = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.eec_baseaddr_l = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.log_num_ee = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup CQC table */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_CQC];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.cqc_baseaddr_h = (addr >> 32);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.cqc_baseaddr_l = (addr & 0xFFFFFFFF) >> 6;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.log_num_cq = state->ts_cfg_profile->cp_log_num_cq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup SRQC table */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_SRQC];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.srqc_baseaddr_h = (addr >> 32);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.srqc_baseaddr_l = (addr & 0xFFFFFFFF) >> 6;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.log_num_srq =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_log_num_srq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup EQPC table */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_EQPC];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.eqpc_baseaddr = addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup EEEC table (initialize to zero - RD unsupported) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.eeec_baseaddr = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup EQC table */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_EQC];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.eqc_baseaddr_h = (addr >> 32);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.eqc_baseaddr_l = (addr & 0xFFFFFFFF) >> 6;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.log_num_eq = TAVOR_NUM_EQ_SHIFT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup RDB table */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_RDB];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.rdb_baseaddr_h = (addr >> 32);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->context.rdb_baseaddr_l = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup Multicast */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MCG];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->multi.mc_baseaddr = addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mcg_size = TAVOR_MCGMEM_SZ(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->multi.log_mc_tbl_ent = highbit(mcg_size) - 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->multi.mc_tbl_hash_sz =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (1 << state->ts_cfg_profile->cp_log_num_mcg_hash);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->multi.mc_hash_fn = TAVOR_MCG_DEFAULT_HASH_FN;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->multi.log_mc_tbl_sz = state->ts_cfg_profile->cp_log_num_mcg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup TPT */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MPT];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->tpt.mpt_baseaddr = addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->tpt.mttseg_sz = TAVOR_MTTSEG_SIZE_SHIFT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->tpt.log_mpt_sz = state->ts_cfg_profile->cp_log_num_mpt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->tpt.mtt_version = TAVOR_MTT_PG_WALK_VER;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MTT];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->tpt.mtt_baseaddr = addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup UAR */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_UAR_SCR];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr = ddr_base_map_addr + offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->uar.uarscr_baseaddr = addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor inithca->uar.uar_pg_sz = PAGESHIFT - 0xC;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_config_setup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_hca_port_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_hca_port_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_hw_initib_t *portinits, *initib;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_cfg_profile_t *cfgprof;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t maxval, val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t sysimgguid, nodeguid, portguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cfgprof = state->ts_cfg_profile;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get number of HCA ports */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_ports = cfgprof->cp_num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Allocate space for Tavor port init struct(s) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor portinits = (tavor_hw_initib_t *)kmem_zalloc(num_ports *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (tavor_hw_initib_t), KM_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Post command to initialize Tavor HCA port */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_ports; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib = &portinits[i];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine whether we need to override the firmware's
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * default SystemImageGUID setting.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sysimgguid = cfgprof->cp_sysimgguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (sysimgguid != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->set_sysimg_guid = 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->sysimg_guid = sysimgguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine whether we need to override the firmware's
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * default NodeGUID setting.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodeguid = cfgprof->cp_nodeguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (nodeguid != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->set_node_guid = 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->node_guid = nodeguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Determine whether we need to override the firmware's
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * default PortGUID setting.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor portguid = cfgprof->cp_portguid[i];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (portguid != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->set_port_guid0 = 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->guid0 = portguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Validate max MTU size */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = state->ts_devlim.max_mtu;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = cfgprof->cp_max_mtu;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_hca_port_init_maxmtu_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "MTU size exceeds device maximum", tnf_uint,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxmtu, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto init_ports_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->mtu_cap = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Validate the max port width */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = state->ts_devlim.max_port_width;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = cfgprof->cp_max_port_width;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_hca_port_init_maxportwidth_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "port width exceeds device maximum", tnf_uint,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxportwidth, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto init_ports_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->port_width_cap = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Validate max VL cap size */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = state->ts_devlim.max_vl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = cfgprof->cp_max_vlcap;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_hca_port_init_maxvlcap_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "VLcap size exceeds device maximum", tnf_uint,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxvlcap, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto init_ports_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->vl_cap = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Validate max GID table size */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_gid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << cfgprof->cp_log_max_gidtbl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_hca_port_init_gidtable_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "GID table size exceeds device maximum", tnf_uint,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxgidtbl, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto init_ports_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->max_gid = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Validate max PKey table size */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxval = ((uint64_t)1 << state->ts_devlim.log_max_pkey);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = ((uint64_t)1 << cfgprof->cp_log_max_pkeytbl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (val > maxval) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_hca_port_init_pkeytable_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "PKey table size exceeds device maximum", tnf_uint,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor maxpkeytbl, maxval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto init_ports_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor initib->max_pkey = val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Post the INIT_IB command to Tavor firmware. When this
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * command completes, the corresponding Tavor port will be
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * physically "Up" and initialized.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_init_ib_cmd_post(state, initib, i + 1,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: INIT_IB (port %02d) command "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "failed: %08x\n", i + 1, status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_hca_port_init_init_ib_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_uint, cmd_status, status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tnf_uint, port, i + 1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto init_ports_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the memory for Tavor port init struct(s), return success */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(portinits, num_ports * sizeof (tavor_hw_initib_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorinit_ports_fail:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Free up the memory for Tavor port init struct(s), shutdown any
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * successfully initialized ports, and return failure
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(portinits, num_ports * sizeof (tavor_hw_initib_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tavor_hca_ports_shutdown(state, i);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_port_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_hca_ports_shutdown()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_hca_ports_shutdown(tavor_state_t *state, uint_t num_init)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_hca_ports_shutdown);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Post commands to shutdown all init'd Tavor HCA ports. Note: if
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * any of these commands fail for any reason, it would be entirely
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * unexpected and probably indicative a serious problem (HW or SW).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Although we do return void from this function, this type of failure
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not go unreported. That is why we have the warning message
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and the detailed TNF information.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_init; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_close_ib_cmd_post(state, i + 1,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_WARNING(state, "failed to shutdown HCA port");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_2(tavor_hca_ports_shutdown_close_ib_cmd_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_uint, cmd_status, status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tnf_uint, port, i + 1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_ports_shutdown);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_hca_ports_shutdown);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (TAVOR_CMD_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_internal_uarpgs_init
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_internal_uarpgs_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_internal_uarpgs_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Save away reserved Tavor UAR page #0. This UAR page is not to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * be used by software.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_rsrc_alloc(state, TAVOR_UARPG, 1, TAVOR_SLEEP,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_uarpg0_rsrc_rsrvd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_uarpg0_rsrcalloc_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_internal_uarpgs_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Save away Tavor UAR page #1 (for internal use). This UAR page is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the privileged UAR page through which all kernel generated
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * doorbells will be rung.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_rsrc_alloc(state, TAVOR_UARPG, 1, TAVOR_SLEEP,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_uarpg1_rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &state->ts_uarpg0_rsrc_rsrvd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_uarpg1_rsrcalloc_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_internal_uarpgs_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup pointer to UAR page #1 doorbells */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_uar = (tavor_hw_uar_t *)state->ts_uarpg1_rsrc->tr_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_internal_uarpgs_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_internal_uarpgs_fini
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_internal_uarpgs_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_internal_uarpgs_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up Tavor UAR page #1 (kernel driver doorbells) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &state->ts_uarpg1_rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up Tavor UAR page #0 (reserved) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &state->ts_uarpg0_rsrc_rsrvd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_internal_uarpgs_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_special_qp_contexts_reserve()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_special_qp_contexts_reserve(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_t *qp0_rsrc, *qp1_rsrc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_special_qp_contexts_reserve);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the lock used for special QP rsrc management */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_init(&state->ts_spec_qplock, NULL, MUTEX_DRIVER,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Reserve contexts for QP0. These QP contexts will be setup to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * act as aliases for the real QP0. Note: We are required to grab
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * two QPs (one per port) even if we are operating in single-port
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * mode.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_rsrc_alloc(state, TAVOR_QPC, 2, TAVOR_SLEEP, &qp0_rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_spec_qplock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_special_qp_contexts_reserve_qp0_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_special_qp_contexts_reserve);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_spec_qp0 = qp0_rsrc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Reserve contexts for QP1. These QP contexts will be setup to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * act as aliases for the real QP1. Note: We are required to grab
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * two QPs (one per port) even if we are operating in single-port
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * mode.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_rsrc_alloc(state, TAVOR_QPC, 2, TAVOR_SLEEP, &qp1_rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &qp0_rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_spec_qplock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_special_qp_contexts_reserve_qp1_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_special_qp_contexts_reserve);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_spec_qp1 = qp1_rsrc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_special_qp_contexts_reserve);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_special_qp_contexts_unreserve()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_special_qp_contexts_unreserve(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_special_qp_contexts_unreserve);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Unreserve contexts for QP1 */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &state->ts_spec_qp1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Unreserve contexts for QP0 */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_rsrc_free(state, &state->ts_spec_qp0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Destroy the lock used for special QP rsrc management */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_spec_qplock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_special_qp_contexts_unreserve);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_sw_reset()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Currently called only from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_sw_reset(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dev_info_t *dip, *pdip;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t hdl = state->ts_pci_cfghdl, phdl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t reset_delay;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status, i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_sw_reset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the configured software reset delay is set to zero, then we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * will not attempt a software reset of the Tavor device.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor reset_delay = state->ts_cfg_profile->cp_sw_reset_delay;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (reset_delay == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_sw_reset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Get dip for HCA device _and_ parent device as well. Parent access
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * is necessary here because software reset of the Tavor hardware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * will reinitialize both the config registers of the PCI bridge
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (parent, if it exists) and the IB HCA (self)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dip = state->ts_dip;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pdip = ddi_get_parent(dip);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Query the PCI capabilities of the HCA device */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_pci_capability_list(state, hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Read all PCI config info (reg0...reg63). Note: According to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Tavor software reset application note, we should not read or
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * restore the values in reg22 and reg23.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((i != TAVOR_SW_RESET_REG22_RSVD) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (i != TAVOR_SW_RESET_REG23_RSVD)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_data[i] = pci_config_get32(hdl, i << 2);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_PARENT_IS_BRIDGE(pdip)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Setup for PCI config read/write of bridge device
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = pci_config_setup(pdip, &phdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_sw_reset_pcicfg_p_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_sw_reset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Read all PCI config info (reg0...reg63). Note: According to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the Tavor software reset application note, we should not
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * read or restore the values in reg22 and reg23.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((i != TAVOR_SW_RESET_REG22_RSVD) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (i != TAVOR_SW_RESET_REG23_RSVD)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_pdata[i] =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pci_config_get32(phdl, i << 2);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Perform the software reset (by writing 1 at offset 0xF0010)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_put32(state->ts_reg_cmdhdl, state->ts_cmd_regs.sw_reset,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_SW_RESET_START);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_usecwait(reset_delay);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_PARENT_IS_BRIDGE(pdip)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Bridge exists, so wait for the bridge to become ready.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The above delay is necessary to avoid system panic from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Master Abort. If the device is accessed before this delay,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * device will not respond to config cycles and they will be
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * terminate with a Master Abort which will panic the system.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Below is the loop we use to poll status from the device to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * determine if it is OK to proceed.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor i = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor while (pci_config_get32(phdl, 0) == TAVOR_SW_RESET_NOTDONE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_usecwait(TAVOR_SW_RESET_POLL_DELAY);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Write all the PCI config registers back into each device
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (except for reg22 and reg23 - see above)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((i != TAVOR_SW_RESET_REG22_RSVD) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (i != TAVOR_SW_RESET_REG23_RSVD)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pci_config_put32(phdl, i << 2,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_pdata[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Tear down the config setup (for bridge device)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pci_config_teardown(&phdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* No Bridge Device */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Bridge does not exist, so instead wait for the device itself
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to become ready.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The above delay is necessary to avoid system panic from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Master Abort. If the device is accessed before this delay,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * device will not respond to config cycles and they will be
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * terminate with a Master Abort which will panic the system.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Below is the loop we use to poll status from the device to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * determine if it is OK to proceed.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor i = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor while (pci_config_get32(hdl, 0) == TAVOR_SW_RESET_NOTDONE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_usecwait(TAVOR_SW_RESET_POLL_DELAY);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((i != TAVOR_SW_RESET_REG22_RSVD) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (i != TAVOR_SW_RESET_REG23_RSVD)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pci_config_put32(hdl, i << 2, state->ts_cfg_data[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_sw_reset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_mcg_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_mcg_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t mcg_tmp_sz;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_mcg_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate space for the MCG temporary copy buffer. This is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * used by the Attach/Detach Multicast Group code
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mcg_tmp_sz = TAVOR_MCGMEM_SZ(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_mcgtmp = kmem_zalloc(mcg_tmp_sz, KM_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initialize the multicast group mutex. This ensures atomic
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * access to add, modify, and remove entries in the multicast
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * group hash lists.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_init(&state->ts_mcglock, NULL, MUTEX_DRIVER,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_mcg_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_mcg_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_mcg_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t mcg_tmp_sz;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_mcg_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the space used for the MCG temporary copy buffer */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mcg_tmp_sz = TAVOR_MCGMEM_SZ(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(state->ts_mcgtmp, mcg_tmp_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Destroy the multicast group mutex */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_destroy(&state->ts_mcglock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_mcg_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_fw_version_check()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_fw_version_check(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t tavor_fw_ver_major;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t tavor_fw_ver_minor;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t tavor_fw_ver_subminor;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Depending on which version of driver we have attached, the firmware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * version checks will be different. We set up the comparison values
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * for both HCA Mode (Tavor hardware) or COMPAT Mode (Arbel hardware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * running in tavor mode).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (state->ts_operational_mode) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_HCA_MODE:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_fw_ver_major = TAVOR_FW_VER_MAJOR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_fw_ver_minor = TAVOR_FW_VER_MINOR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_fw_ver_subminor = TAVOR_FW_VER_SUBMINOR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case TAVOR_COMPAT_MODE:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_fw_ver_major = TAVOR_COMPAT_FW_VER_MAJOR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_fw_ver_minor = TAVOR_COMPAT_FW_VER_MINOR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_fw_ver_subminor = TAVOR_COMPAT_FW_VER_SUBMINOR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If FW revision major number is less than acceptable,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * return failure, else if greater return success. If
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the major numbers are equal than check the minor number
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_fw.fw_rev_major < tavor_fw_ver_major) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (state->ts_fw.fw_rev_major > tavor_fw_ver_major) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Do the same check as above, except for minor revision numbers
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the minor numbers are equal than check the subminor number
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_fw.fw_rev_minor < tavor_fw_ver_minor) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (state->ts_fw.fw_rev_minor > tavor_fw_ver_minor) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Once again we do the same check as above, except for the subminor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * revision number. If the subminor numbers are equal here, then
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * these are the same firmware version, return success
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_fw.fw_rev_subminor < tavor_fw_ver_subminor) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (state->ts_fw.fw_rev_subminor > tavor_fw_ver_subminor) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_device_info_report()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_device_info_report(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "?tavor%d: FW ver: %04d.%04d.%04d, "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "HW rev: %02x\n", state->ts_instance, state->ts_fw.fw_rev_major,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_fw.fw_rev_minor, state->ts_fw.fw_rev_subminor,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_adapter.rev_id);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "?tavor%d: %64s (0x%016" PRIx64 ")\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_instance, state->ts_nodedesc, state->ts_nodeguid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_pci_capability_list()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_pci_capability_list(tavor_state_t *state, ddi_acc_handle_t hdl)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t offset, data;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_pci_capability_list);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Check for the "PCI Capabilities" bit in the "Status Register".
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Bit 4 in this register indicates the presence of a "PCI
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Capabilities" list.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data = pci_config_get16(hdl, 0x6);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((data & 0x10) == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_pci_capab_list_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_pci_capability_list);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Starting from offset 0x34 in PCI config space, find the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * head of "PCI capabilities" list, and walk the list. If
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * capabilities of a known type are encountered (e.g.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "PCI-X Capability"), then call the appropriate handler
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * function.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = pci_config_get8(hdl, 0x34);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor while (offset != 0x0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data = pci_config_get8(hdl, offset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Check for known capability types. Tavor has the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * following:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * o VPD Capability (0x03)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * o PCI-X Capability (0x07)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * o MSI Capability (0x05)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * o MSIX Capability (0x11)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (data) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 0x03:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_pci_capability_vpd(state, hdl, offset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 0x07:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_pci_capability_pcix(state, hdl, offset);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case 0x05:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get offset of next entry in list */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = pci_config_get8(hdl, offset + 1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_pci_capability_list);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_pci_read_vpd()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * utility routine for tavor_pci_capability_vpd()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_pci_read_vpd(ddi_acc_handle_t hdl, uint_t offset, uint32_t addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t *data)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int retry = 4; /* retry counter for EEPROM poll */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t val;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int vpd_addr = offset + 2;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int vpd_data = offset + 4;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_pci_read_vpd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * In order to read a 32-bit value from VPD, we are to write down
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the address (offset in the VPD itself) to the address register.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * To signal the read, we also clear bit 31. We then poll on bit 31
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and when it is set, we can then read our 4 bytes from the data
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * register.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) pci_config_put32(hdl, offset, addr << 16);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor do {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor drv_usecwait(1000);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor val = pci_config_get16(hdl, vpd_addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((val >> 15) & 0x01) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *data = pci_config_get32(hdl, vpd_data);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_pci_read_vpd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } while (--retry);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_pci_read_vpd_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_pci_read_vpd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_pci_capability_vpd()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_pci_capability_vpd(tavor_state_t *state, ddi_acc_handle_t hdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t offset)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint8_t name_length;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint8_t pn_length;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, err = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int vpd_str_id = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int vpd_ro_desc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int vpd_ro_pn_desc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef _LITTLE_ENDIAN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t data32;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif /* _LITTLE_ENDIAN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor union {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t vpd_int[TAVOR_VPD_HDR_DWSIZE];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uchar_t vpd_char[TAVOR_VPD_HDR_BSIZE];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } vpd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_pci_capability_vpd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Read Vital Product Data (VPD) from PCI-X capability.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < TAVOR_VPD_HDR_DWSIZE; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err = tavor_pci_read_vpd(hdl, offset, i << 2, &vpd.vpd_int[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (err != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!VPD read failed\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto out;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifndef _LITTLE_ENDIAN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Need to swap bytes for big endian.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < TAVOR_VPD_HDR_DWSIZE; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data32 = vpd.vpd_int[i];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd.vpd_char[(i << 2) + 3] =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uchar_t)((data32 & 0xFF000000) >> 24);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd.vpd_char[(i << 2) + 2] =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uchar_t)((data32 & 0x00FF0000) >> 16);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd.vpd_char[(i << 2) + 1] =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uchar_t)((data32 & 0x0000FF00) >> 8);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd.vpd_char[i << 2] = (uchar_t)(data32 & 0x000000FF);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif /* _LITTLE_ENDIAN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Check for VPD String ID Tag */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (vpd.vpd_char[vpd_str_id] == 0x82) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* get the product name */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor name_length = (uint8_t)vpd.vpd_char[vpd_str_id + 1];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (name_length > sizeof (state->ts_hca_name)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!VPD name too large (0x%x)\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor name_length);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto out;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) memcpy(state->ts_hca_name, &vpd.vpd_char[vpd_str_id + 3],
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor name_length);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_hca_name[name_length] = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* get the part number */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd_ro_desc = name_length + 3; /* read-only tag location */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd_ro_pn_desc = vpd_ro_desc + 3; /* P/N keyword location */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Verify read-only tag and Part Number keyword.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (vpd.vpd_char[vpd_ro_desc] != 0x90 ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (vpd.vpd_char[vpd_ro_pn_desc] != 'P' &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd.vpd_char[vpd_ro_pn_desc + 1] != 'N')) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!VPD Part Number not found\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto out;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pn_length = (uint8_t)vpd.vpd_char[vpd_ro_pn_desc + 2];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (pn_length > sizeof (state->ts_hca_pn)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!VPD part number too large (0x%x)\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor name_length);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto out;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) memcpy(state->ts_hca_pn,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &vpd.vpd_char[vpd_ro_pn_desc + 3],
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pn_length);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_hca_pn[pn_length] = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_hca_pn_len = pn_length;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Wrong VPD String ID Tag */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!VPD String ID Tag not found, tag: %02x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vpd.vpd_char[0]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto out;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_pci_capability_vpd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorout:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_hca_pn_len = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_pci_capability_vpd_fail, TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_pci_capability_vpd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_pci_capability_pcix()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_pci_capability_pcix(tavor_state_t *state, ddi_acc_handle_t hdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t offset)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t command, status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int max_out_splt_trans, max_mem_rd_byte_cnt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int designed_max_out_splt_trans, designed_max_mem_rd_byte_cnt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_pci_capability_pcix);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Query the current values for the PCI-X Command Register and
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the PCI-X Status Register.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor command = pci_config_get16(hdl, offset + 2);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = pci_config_get32(hdl, offset + 4);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Check for config property specifying "maximum outstanding
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * split transactions". If the property is defined and valid
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (i.e. no larger than the so-called "designed maximum"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * then use the specified value to update the PCI-X Command Register.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Otherwise, extract the value from the Tavor config profile.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor designed_max_out_splt_trans = ((status >> 23) & 7);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_out_splt_trans = ddi_prop_get_int(DDI_DEV_T_ANY, state->ts_dip,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_PROP_DONTPASS, "pcix-max-outstanding-split-trans", -1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((max_out_splt_trans != -1) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((max_out_splt_trans < 0) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (max_out_splt_trans > designed_max_out_splt_trans))) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!tavor%d: property \"pcix-max-outstanding-"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "split-trans\" (%d) invalid or exceeds device maximum"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor " (%d), using default value (%d)\n", state->ts_instance,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_out_splt_trans, designed_max_out_splt_trans,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_max_out_splt_trans);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_out_splt_trans =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_max_out_splt_trans;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (max_out_splt_trans == -1) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_out_splt_trans =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_max_out_splt_trans;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The config profile setting for max_out_splt_trans is determined
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * based on arch. Check tavor_cfg.c for more information. A value of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * '-1' in the patchable variable means "do not change". A value of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * '0' means 1 outstanding splt trans and other values as defined by
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * PCI. So we do one more check here, that if 'max_out_splt_trans' is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * -1 (ie: < 0) we do not set the PCI command and leave it at the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * default.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (max_out_splt_trans >= 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor command = ((command & 0xFF8F) | max_out_splt_trans << 4);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Check for config property specifying "maximum memory read
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * byte count. If the property is defined and valid
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (i.e. no larger than the so-called "designed maximum"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * then use the specified value to update the PCI-X Command Register.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Otherwise, extract the value from the Tavor config profile.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor designed_max_mem_rd_byte_cnt = ((status >> 21) & 3);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_mem_rd_byte_cnt = ddi_prop_get_int(DDI_DEV_T_ANY, state->ts_dip,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_PROP_DONTPASS, "pcix-max-read-byte-count", -1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((max_mem_rd_byte_cnt != -1) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((max_mem_rd_byte_cnt < 0) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (max_mem_rd_byte_cnt > designed_max_mem_rd_byte_cnt))) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "!tavor%d: property \"pcix-max-read-byte-"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "count\" (%d) invalid or exceeds device maximum"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor " (%d), using default value (%d)\n", state->ts_instance,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_mem_rd_byte_cnt, designed_max_mem_rd_byte_cnt,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_max_mem_rd_byte_cnt);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_mem_rd_byte_cnt =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_max_mem_rd_byte_cnt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (max_mem_rd_byte_cnt == -1) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor max_mem_rd_byte_cnt =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_max_mem_rd_byte_cnt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The config profile setting for max_mem_rd_byte_cnt is determined
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * based on arch. Check tavor_cfg.c for more information. A value of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * '-1' in the patchable variable means "do not change". A value of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * '0' means minimum (512B) read, and other values as defined by
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * PCI. So we do one more check here, that if 'max_mem_rd_byte_cnt' is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * -1 (ie: < 0) we do not set the PCI command and leave it at the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * default.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (max_mem_rd_byte_cnt >= 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor command = ((command & 0xFFF3) | max_mem_rd_byte_cnt << 2);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Update the PCI-X Command Register with the newly configured
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * values.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pci_config_put16(hdl, offset + 2, command);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_pci_capability_pcix);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_intr_or_msi_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_intr_or_msi_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_intr_or_msi_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Query for the list of supported interrupt event types */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_get_supported_types(state->ts_dip,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_intr_types_avail);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_intr_or_msi_init_gettypes_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_intr_or_msi_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If Tavor/Arbel supports MSI in this system (and, if it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hasn't been overridden by a configuration variable), then
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the default behavior is to use a single MSI. Otherwise,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fallback to using legacy interrupts. Also, if MSI allocatis chosen,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * but fails for whatever reasons, then fallback to using legacy
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * interrupts.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((state->ts_cfg_profile->cp_use_msi_if_avail != 0) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->ts_intr_types_avail & DDI_INTR_TYPE_MSI)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_add_intrs(state, DDI_INTR_TYPE_MSI);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_intr_type_chosen = DDI_INTR_TYPE_MSI;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_intr_or_msi_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MSI interrupt allocation failed, or was not available. Fallback to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * legacy interrupt support.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_intr_types_avail & DDI_INTR_TYPE_FIXED) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_add_intrs(state, DDI_INTR_TYPE_FIXED);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_intr_type_chosen = DDI_INTR_TYPE_FIXED;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_intr_or_msi_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Neither MSI or legacy interrupts were successful. return failure.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_intr_or_msi_setup);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_add_intrs()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() patch context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_add_intrs(tavor_state_t *state, int intr_type)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get number of interrupts/MSI supported */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_get_nintrs(state->ts_dip, intr_type,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_intrmsi_count);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_getnintrs_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get number of available interrupts/MSI */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_get_navail(state->ts_dip, intr_type,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_intrmsi_avail);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_getnavail_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Ensure that we have at least one (1) usable MSI or interrupt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((state->ts_intrmsi_avail < 1) || (state->ts_intrmsi_count < 1)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_notenoughts_intrmsi_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Attempt to allocate a single interrupt/MSI handle */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_alloc(state->ts_dip, &state->ts_intrmsi_hdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor intr_type, 0, 1, &state->ts_intrmsi_allocd,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_INTR_ALLOC_STRICT);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_intralloc_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Ensure that we have allocated at least one (1) MSI or interrupt */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_intrmsi_allocd < 1) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_noallocts_intrmsi_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Extract the priority for the allocated interrupt/MSI. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * will be used later when initializing certain mutexes.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_get_pri(state->ts_intrmsi_hdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_intrmsi_pri);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the allocated interrupt/MSI handle */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ddi_intr_free(state->ts_intrmsi_hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_getpri_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Make sure the interrupt/MSI priority is below 'high level' */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_intrmsi_pri >= ddi_intr_get_hilevel_pri()) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the allocated interrupt/MSI handle */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ddi_intr_free(state->ts_intrmsi_hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_hilevelpri_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get add'l capability information regarding interrupt/MSI */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_get_cap(state->ts_intrmsi_hdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &state->ts_intrmsi_cap);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the allocated interrupt/MSI handle */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ddi_intr_free(state->ts_intrmsi_hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_add_intrs_getcap_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_add_intrs);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_intr_or_msi_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_intr_or_msi_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_intr_or_msi_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the allocated interrupt/MSI handle */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_intr_free(state->ts_intrmsi_hdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_intr_or_msi_fini_freehdl_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_intr_or_msi_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_intr_or_msi_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* Disable Tavor interrupts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_intr_disable(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ushort_t msi_ctrl = 0, caps_ctrl = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t pci_cfg_hdl = state->ts_pci_cfghdl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ASSERT(pci_cfg_hdl != NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ASSERT(state->ts_intr_types_avail &
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (DDI_INTR_TYPE_FIXED | DDI_INTR_TYPE_MSI));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Check if MSI interrupts are used. If so, disable MSI interupts.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If not, since Tavor doesn't support MSI-X interrupts, assuming the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * legacy interrupt is used instead, disable the legacy interrupt.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((state->ts_cfg_profile->cp_use_msi_if_avail != 0) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->ts_intr_types_avail & DDI_INTR_TYPE_MSI)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((PCI_CAP_LOCATE(pci_cfg_hdl, PCI_CAP_ID_MSI,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &caps_ctrl) == DDI_SUCCESS)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((msi_ctrl = PCI_CAP_GET16(pci_cfg_hdl, NULL,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor caps_ctrl, PCI_MSI_CTRL)) == PCI_CAP_EINVAL16)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ASSERT(msi_ctrl != 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (!(msi_ctrl & PCI_MSI_ENABLE_BIT))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (msi_ctrl & PCI_MSI_PVM_MASK) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int offset = (msi_ctrl & PCI_MSI_64BIT_MASK) ?
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor PCI_MSI_64BIT_MASKBITS : PCI_MSI_32BIT_MASK;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Clear all inums in MSI */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor PCI_CAP_PUT32(pci_cfg_hdl, NULL, caps_ctrl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset, 0x0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Disable MSI interrupts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor msi_ctrl &= ~PCI_MSI_ENABLE_BIT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor PCI_CAP_PUT16(pci_cfg_hdl, NULL, caps_ctrl, PCI_MSI_CTRL,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor msi_ctrl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint16_t cmdreg = pci_config_get16(pci_cfg_hdl, PCI_CONF_COMM);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ASSERT(state->ts_intr_types_avail & DDI_INTR_TYPE_FIXED);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Disable the legacy interrupts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmdreg |= PCI_COMM_INTX_DISABLE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pci_config_put16(pci_cfg_hdl, PCI_CONF_COMM, cmdreg);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* Tavor quiesce(9F) entry */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_quiesce(dev_info_t *dip)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state = ddi_get_soft_state(tavor_statep,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DEVI(dip)->devi_instance);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ASSERT(state != NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* start fastreboot */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_quiescing = B_TRUE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
332f545bce1434913a4e2bffd942656ef0906846Eiji Ota /* If it's in maintenance mode, do nothing but return with SUCCESS */
332f545bce1434913a4e2bffd942656ef0906846Eiji Ota if (!TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) {
332f545bce1434913a4e2bffd942656ef0906846Eiji Ota return (DDI_SUCCESS);
332f545bce1434913a4e2bffd942656ef0906846Eiji Ota }
332f545bce1434913a4e2bffd942656ef0906846Eiji Ota
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Shutdown HCA ports */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (tavor_hca_ports_shutdown(state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_cfg_profile->cp_num_ports) != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_quiescing = B_FALSE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Close HCA */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (tavor_close_hca_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN) !=
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_quiescing = B_FALSE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Shutdown FW */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (tavor_sys_dis_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN) !=
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_quiescing = B_FALSE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Disable interrupts */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (tavor_intr_disable(state) != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_quiescing = B_FALSE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* SW-reset */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (tavor_sw_reset(state) != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_quiescing = B_FALSE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}