1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * hermon.c
  28  *    Hermon (InfiniBand) HCA Driver attach/detach Routines
  29  *
  30  *    Implements all the routines necessary for the attach, setup,
  31  *    initialization (and subsequent possible teardown and detach) of the
  32  *    Hermon InfiniBand HCA driver.
  33  */
  34 
  35 #include <sys/types.h>
  36 #include <sys/file.h>
  37 #include <sys/open.h>
  38 #include <sys/conf.h>
  39 #include <sys/ddi.h>
  40 #include <sys/sunddi.h>
  41 #include <sys/modctl.h>
  42 #include <sys/stat.h>
  43 #include <sys/pci.h>
  44 #include <sys/pci_cap.h>
  45 #include <sys/bitmap.h>
  46 #include <sys/policy.h>
  47 
  48 #include <sys/ib/adapters/hermon/hermon.h>
  49 
  50 /* /etc/system can tune this down, if that is desirable. */
  51 int hermon_msix_max = HERMON_MSIX_MAX;
  52 
  53 /* The following works around a problem in pre-2_7_000 firmware. */
  54 #define HERMON_FW_WORKAROUND
  55 
  56 int hermon_verbose = 0;
  57 
  58 /* Hermon HCA State Pointer */
  59 void *hermon_statep;
  60 
  61 int debug_vpd = 0;
  62 
  63 /* Disable the internal error-check polling thread */
  64 int hermon_no_inter_err_chk = 0;
  65 
  66 /*
  67  * The Hermon "userland resource database" is common to instances of the
  68  * Hermon HCA driver.  This structure "hermon_userland_rsrc_db" contains all
  69  * the necessary information to maintain it.
  70  */
  71 hermon_umap_db_t hermon_userland_rsrc_db;
  72 
  73 static int hermon_attach(dev_info_t *, ddi_attach_cmd_t);
  74 static int hermon_detach(dev_info_t *, ddi_detach_cmd_t);
  75 static int hermon_open(dev_t *, int, int, cred_t *);
  76 static int hermon_close(dev_t, int, int, cred_t *);
  77 static int hermon_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
  78 
  79 static int hermon_drv_init(hermon_state_t *state, dev_info_t *dip,
  80     int instance);
  81 static void hermon_drv_fini(hermon_state_t *state);
  82 static void hermon_drv_fini2(hermon_state_t *state);
  83 static int hermon_isr_init(hermon_state_t *state);
  84 static void hermon_isr_fini(hermon_state_t *state);
  85 
  86 static int hermon_hw_init(hermon_state_t *state);
  87 
  88 static void hermon_hw_fini(hermon_state_t *state,
  89     hermon_drv_cleanup_level_t cleanup);
  90 static int hermon_soft_state_init(hermon_state_t *state);
  91 static void hermon_soft_state_fini(hermon_state_t *state);
  92 static int hermon_icm_config_setup(hermon_state_t *state,
  93     hermon_hw_initqueryhca_t *inithca);
  94 static void hermon_icm_tables_init(hermon_state_t *state);
  95 static void hermon_icm_tables_fini(hermon_state_t *state);
  96 static int hermon_icm_dma_init(hermon_state_t *state);
  97 static void hermon_icm_dma_fini(hermon_state_t *state);
  98 static void hermon_inithca_set(hermon_state_t *state,
  99     hermon_hw_initqueryhca_t *inithca);
 100 static int hermon_hca_port_init(hermon_state_t *state);
 101 static int hermon_hca_ports_shutdown(hermon_state_t *state, uint_t num_init);
 102 static int hermon_internal_uarpg_init(hermon_state_t *state);
 103 static void hermon_internal_uarpg_fini(hermon_state_t *state);
 104 static int hermon_special_qp_contexts_reserve(hermon_state_t *state);
 105 static void hermon_special_qp_contexts_unreserve(hermon_state_t *state);
 106 static int hermon_sw_reset(hermon_state_t *state);
 107 static int hermon_mcg_init(hermon_state_t *state);
 108 static void hermon_mcg_fini(hermon_state_t *state);
 109 static int hermon_fw_version_check(hermon_state_t *state);
 110 static void hermon_device_info_report(hermon_state_t *state);
 111 static int hermon_pci_capability_list(hermon_state_t *state,
 112     ddi_acc_handle_t hdl);
 113 static void hermon_pci_capability_vpd(hermon_state_t *state,
 114     ddi_acc_handle_t hdl, uint_t offset);
 115 static int hermon_pci_read_vpd(ddi_acc_handle_t hdl, uint_t offset,
 116     uint32_t addr, uint32_t *data);
 117 static int hermon_intr_or_msi_init(hermon_state_t *state);
 118 static int hermon_add_intrs(hermon_state_t *state, int intr_type);
 119 static int hermon_intr_or_msi_fini(hermon_state_t *state);
 120 void hermon_pci_capability_msix(hermon_state_t *state, ddi_acc_handle_t hdl,
 121     uint_t offset);
 122 
 123 static uint64_t hermon_size_icm(hermon_state_t *state);
 124 
 125 /* X86 fastreboot support */
 126 static ushort_t get_msix_ctrl(dev_info_t *);
 127 static size_t get_msix_tbl_size(dev_info_t *);
 128 static size_t get_msix_pba_size(dev_info_t *);
 129 static void hermon_set_msix_info(hermon_state_t *);
 130 static int hermon_intr_disable(hermon_state_t *);
 131 static int hermon_quiesce(dev_info_t *);
 132 
 133 
 134 /* Character/Block Operations */
 135 static struct cb_ops hermon_cb_ops = {
 136         hermon_open,            /* open */
 137         hermon_close,           /* close */
 138         nodev,                  /* strategy (block) */
 139         nodev,                  /* print (block) */
 140         nodev,                  /* dump (block) */
 141         nodev,                  /* read */
 142         nodev,                  /* write */
 143         hermon_ioctl,           /* ioctl */
 144         hermon_devmap,          /* devmap */
 145         NULL,                   /* mmap */
 146         nodev,                  /* segmap */
 147         nochpoll,               /* chpoll */
 148         ddi_prop_op,            /* prop_op */
 149         NULL,                   /* streams */
 150         D_NEW | D_MP |
 151         D_64BIT | D_HOTPLUG |
 152         D_DEVMAP,               /* flags */
 153         CB_REV                  /* rev */
 154 };
 155 
 156 /* Driver Operations */
 157 static struct dev_ops hermon_ops = {
 158         DEVO_REV,               /* struct rev */
 159         0,                      /* refcnt */
 160         hermon_getinfo,         /* getinfo */
 161         nulldev,                /* identify */
 162         nulldev,                /* probe */
 163         hermon_attach,          /* attach */
 164         hermon_detach,          /* detach */
 165         nodev,                  /* reset */
 166         &hermon_cb_ops,             /* cb_ops */
 167         NULL,                   /* bus_ops */
 168         nodev,                  /* power */
 169         hermon_quiesce,         /* devo_quiesce */
 170 };
 171 
 172 /* Module Driver Info */
 173 static struct modldrv hermon_modldrv = {
 174         &mod_driverops,
 175         "ConnectX IB Driver",
 176         &hermon_ops
 177 };
 178 
 179 /* Module Linkage */
 180 static struct modlinkage hermon_modlinkage = {
 181         MODREV_1,
 182         &hermon_modldrv,
 183         NULL
 184 };
 185 
 186 /*
 187  * This extern refers to the ibc_operations_t function vector that is defined
 188  * in the hermon_ci.c file.
 189  */
 190 extern ibc_operations_t hermon_ibc_ops;
 191 
 192 /*
 193  * _init()
 194  */
 195 int
 196 _init()
 197 {
 198         int     status;
 199 
 200         status = ddi_soft_state_init(&hermon_statep, sizeof (hermon_state_t),
 201             (size_t)HERMON_INITIAL_STATES);
 202         if (status != 0) {
 203                 return (status);
 204         }
 205 
 206         status = ibc_init(&hermon_modlinkage);
 207         if (status != 0) {
 208                 ddi_soft_state_fini(&hermon_statep);
 209                 return (status);
 210         }
 211 
 212         status = mod_install(&hermon_modlinkage);
 213         if (status != 0) {
 214                 ibc_fini(&hermon_modlinkage);
 215                 ddi_soft_state_fini(&hermon_statep);
 216                 return (status);
 217         }
 218 
 219         /* Initialize the Hermon "userland resources database" */
 220         hermon_umap_db_init();
 221 
 222         return (status);
 223 }
 224 
 225 
 226 /*
 227  * _info()
 228  */
 229 int
 230 _info(struct modinfo *modinfop)
 231 {
 232         int     status;
 233 
 234         status = mod_info(&hermon_modlinkage, modinfop);
 235         return (status);
 236 }
 237 
 238 
 239 /*
 240  * _fini()
 241  */
 242 int
 243 _fini()
 244 {
 245         int     status;
 246 
 247         status = mod_remove(&hermon_modlinkage);
 248         if (status != 0) {
 249                 return (status);
 250         }
 251 
 252         /* Destroy the Hermon "userland resources database" */
 253         hermon_umap_db_fini();
 254 
 255         ibc_fini(&hermon_modlinkage);
 256         ddi_soft_state_fini(&hermon_statep);
 257 
 258         return (status);
 259 }
 260 
 261 
 262 /*
 263  * hermon_getinfo()
 264  */
 265 /* ARGSUSED */
 266 static int
 267 hermon_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
 268 {
 269         dev_t           dev;
 270         hermon_state_t  *state;
 271         minor_t         instance;
 272 
 273         switch (cmd) {
 274         case DDI_INFO_DEVT2DEVINFO:
 275                 dev = (dev_t)arg;
 276                 instance = HERMON_DEV_INSTANCE(dev);
 277                 state = ddi_get_soft_state(hermon_statep, instance);
 278                 if (state == NULL) {
 279                         return (DDI_FAILURE);
 280                 }
 281                 *result = (void *)state->hs_dip;
 282                 return (DDI_SUCCESS);
 283 
 284         case DDI_INFO_DEVT2INSTANCE:
 285                 dev = (dev_t)arg;
 286                 instance = HERMON_DEV_INSTANCE(dev);
 287                 *result = (void *)(uintptr_t)instance;
 288                 return (DDI_SUCCESS);
 289 
 290         default:
 291                 break;
 292         }
 293 
 294         return (DDI_FAILURE);
 295 }
 296 
 297 
 298 /*
 299  * hermon_open()
 300  */
 301 /* ARGSUSED */
 302 static int
 303 hermon_open(dev_t *devp, int flag, int otyp, cred_t *credp)
 304 {
 305         hermon_state_t          *state;
 306         hermon_rsrc_t           *rsrcp;
 307         hermon_umap_db_entry_t  *umapdb, *umapdb2;
 308         minor_t                 instance;
 309         uint64_t                key, value;
 310         uint_t                  hr_indx;
 311         dev_t                   dev;
 312         int                     status;
 313 
 314         instance = HERMON_DEV_INSTANCE(*devp);
 315         state = ddi_get_soft_state(hermon_statep, instance);
 316         if (state == NULL) {
 317                 return (ENXIO);
 318         }
 319 
 320         /*
 321          * Only allow driver to be opened for character access, and verify
 322          * whether exclusive access is allowed.
 323          */
 324         if ((otyp != OTYP_CHR) || ((flag & FEXCL) &&
 325             secpolicy_excl_open(credp) != 0)) {
 326                 return (EINVAL);
 327         }
 328 
 329         /*
 330          * Search for the current process PID in the "userland resources
 331          * database".  If it is not found, then attempt to allocate a UAR
 332          * page and add the ("key", "value") pair to the database.
 333          * Note:  As a last step we always return a devp appropriate for
 334          * the open.  Either we return a new minor number (based on the
 335          * instance and the UAR page index) or we return the current minor
 336          * number for the given client process.
 337          *
 338          * We also add an entry to the database to allow for lookup from
 339          * "dev_t" to the current process PID.  This is necessary because,
 340          * under certain circumstance, the process PID that calls the Hermon
 341          * close() entry point may not be the same as the one who called
 342          * open().  Specifically, this can happen if a child process calls
 343          * the Hermon's open() entry point, gets a UAR page, maps it out (using
 344          * mmap()), and then exits without calling munmap().  Because mmap()
 345          * adds a reference to the file descriptor, at the exit of the child
 346          * process the file descriptor is "inherited" by the parent (and will
 347          * be close()'d by the parent's PID only when it exits).
 348          *
 349          * Note: We use the hermon_umap_db_find_nolock() and
 350          * hermon_umap_db_add_nolock() database access routines below (with
 351          * an explicit mutex_enter of the database lock - "hdl_umapdb_lock")
 352          * to ensure that the multiple accesses (in this case searching for,
 353          * and then adding _two_ database entries) can be done atomically.
 354          */
 355         key = ddi_get_pid();
 356         mutex_enter(&hermon_userland_rsrc_db.hdl_umapdb_lock);
 357         status = hermon_umap_db_find_nolock(instance, key,
 358             MLNX_UMAP_UARPG_RSRC, &value, 0, NULL);
 359         if (status != DDI_SUCCESS) {
 360                 /*
 361                  * If we are in 'maintenance mode', we cannot alloc a UAR page.
 362                  * But we still need some rsrcp value, and a mostly unique
 363                  * hr_indx value.  So we set rsrcp to NULL for maintenance
 364                  * mode, and use a rolling count for hr_indx.  The field
 365                  * 'hs_open_hr_indx' is used only in this maintenance mode
 366                  * condition.
 367                  *
 368                  * Otherwise, if we are in operational mode then we allocate
 369                  * the UAR page as normal, and use the rsrcp value and tr_indx
 370                  * value from that allocation.
 371                  */
 372                 if (!HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 373                         rsrcp = NULL;
 374                         hr_indx = state->hs_open_ar_indx++;
 375                 } else {
 376                         /* Allocate a new UAR page for this process */
 377                         status = hermon_rsrc_alloc(state, HERMON_UARPG, 1,
 378                             HERMON_NOSLEEP, &rsrcp);
 379                         if (status != DDI_SUCCESS) {
 380                                 mutex_exit(
 381                                     &hermon_userland_rsrc_db.hdl_umapdb_lock);
 382                                 return (EAGAIN);
 383                         }
 384 
 385                         hr_indx = rsrcp->hr_indx;
 386                 }
 387 
 388                 /*
 389                  * Allocate an entry to track the UAR page resource in the
 390                  * "userland resources database".
 391                  */
 392                 umapdb = hermon_umap_db_alloc(instance, key,
 393                     MLNX_UMAP_UARPG_RSRC, (uint64_t)(uintptr_t)rsrcp);
 394                 if (umapdb == NULL) {
 395                         mutex_exit(&hermon_userland_rsrc_db.hdl_umapdb_lock);
 396                         /* If in "maintenance mode", don't free the rsrc */
 397                         if (HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 398                                 hermon_rsrc_free(state, &rsrcp);
 399                         }
 400                         return (EAGAIN);
 401                 }
 402 
 403                 /*
 404                  * Create a new device number.  Minor number is a function of
 405                  * the UAR page index (15 bits) and the device instance number
 406                  * (3 bits).
 407                  */
 408                 dev = makedevice(getmajor(*devp), (hr_indx <<
 409                     HERMON_MINORNUM_SHIFT) | instance);
 410 
 411                 /*
 412                  * Allocate another entry in the "userland resources database"
 413                  * to track the association of the device number (above) to
 414                  * the current process ID (in "key").
 415                  */
 416                 umapdb2 = hermon_umap_db_alloc(instance, dev,
 417                     MLNX_UMAP_PID_RSRC, (uint64_t)key);
 418                 if (umapdb2 == NULL) {
 419                         mutex_exit(&hermon_userland_rsrc_db.hdl_umapdb_lock);
 420                         hermon_umap_db_free(umapdb);
 421                         /* If in "maintenance mode", don't free the rsrc */
 422                         if (HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 423                                 hermon_rsrc_free(state, &rsrcp);
 424                         }
 425                         return (EAGAIN);
 426                 }
 427 
 428                 /* Add the entries to the database */
 429                 hermon_umap_db_add_nolock(umapdb);
 430                 hermon_umap_db_add_nolock(umapdb2);
 431 
 432         } else {
 433                 /*
 434                  * Return the same device number as on the original open()
 435                  * call.  This was calculated as a function of the UAR page
 436                  * index (top 16 bits) and the device instance number
 437                  */
 438                 rsrcp = (hermon_rsrc_t *)(uintptr_t)value;
 439                 dev = makedevice(getmajor(*devp), (rsrcp->hr_indx <<
 440                     HERMON_MINORNUM_SHIFT) | instance);
 441         }
 442         mutex_exit(&hermon_userland_rsrc_db.hdl_umapdb_lock);
 443 
 444         *devp = dev;
 445 
 446         return (0);
 447 }
 448 
 449 
 450 /*
 451  * hermon_close()
 452  */
 453 /* ARGSUSED */
 454 static int
 455 hermon_close(dev_t dev, int flag, int otyp, cred_t *credp)
 456 {
 457         hermon_state_t          *state;
 458         hermon_rsrc_t           *rsrcp;
 459         hermon_umap_db_entry_t  *umapdb;
 460         hermon_umap_db_priv_t   *priv;
 461         minor_t                 instance;
 462         uint64_t                key, value;
 463         int                     status, reset_status = 0;
 464 
 465         instance = HERMON_DEV_INSTANCE(dev);
 466         state = ddi_get_soft_state(hermon_statep, instance);
 467         if (state == NULL) {
 468                 return (ENXIO);
 469         }
 470 
 471         /*
 472          * Search for "dev_t" in the "userland resources database".  As
 473          * explained above in hermon_open(), we can't depend on using the
 474          * current process ID here to do the lookup because the process
 475          * that ultimately closes may not be the same one who opened
 476          * (because of inheritance).
 477          * So we lookup the "dev_t" (which points to the PID of the process
 478          * that opened), and we remove the entry from the database (and free
 479          * it up).  Then we do another query based on the PID value.  And when
 480          * we find that database entry, we free it up too and then free the
 481          * Hermon UAR page resource.
 482          *
 483          * Note: We use the hermon_umap_db_find_nolock() database access
 484          * routine below (with an explicit mutex_enter of the database lock)
 485          * to ensure that the multiple accesses (which attempt to remove the
 486          * two database entries) can be done atomically.
 487          *
 488          * This works the same in both maintenance mode and HCA mode, except
 489          * for the call to hermon_rsrc_free().  In the case of maintenance mode,
 490          * this call is not needed, as it was not allocated in hermon_open()
 491          * above.
 492          */
 493         key = dev;
 494         mutex_enter(&hermon_userland_rsrc_db.hdl_umapdb_lock);
 495         status = hermon_umap_db_find_nolock(instance, key, MLNX_UMAP_PID_RSRC,
 496             &value, HERMON_UMAP_DB_REMOVE, &umapdb);
 497         if (status == DDI_SUCCESS) {
 498                 /*
 499                  * If the "hdb_priv" field is non-NULL, it indicates that
 500                  * some "on close" handling is still necessary.  Call
 501                  * hermon_umap_db_handle_onclose_cb() to do the handling (i.e.
 502                  * to invoke all the registered callbacks).  Then free up
 503                  * the resources associated with "hdb_priv" and continue
 504                  * closing.
 505                  */
 506                 priv = (hermon_umap_db_priv_t *)umapdb->hdbe_common.hdb_priv;
 507                 if (priv != NULL) {
 508                         reset_status = hermon_umap_db_handle_onclose_cb(priv);
 509                         kmem_free(priv, sizeof (hermon_umap_db_priv_t));
 510                         umapdb->hdbe_common.hdb_priv = (void *)NULL;
 511                 }
 512 
 513                 hermon_umap_db_free(umapdb);
 514 
 515                 /*
 516                  * Now do another lookup using PID as the key (copy it from
 517                  * "value").  When this lookup is complete, the "value" field
 518                  * will contain the hermon_rsrc_t pointer for the UAR page
 519                  * resource.
 520                  */
 521                 key = value;
 522                 status = hermon_umap_db_find_nolock(instance, key,
 523                     MLNX_UMAP_UARPG_RSRC, &value, HERMON_UMAP_DB_REMOVE,
 524                     &umapdb);
 525                 if (status == DDI_SUCCESS) {
 526                         hermon_umap_db_free(umapdb);
 527                         /* If in "maintenance mode", don't free the rsrc */
 528                         if (HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 529                                 rsrcp = (hermon_rsrc_t *)(uintptr_t)value;
 530                                 hermon_rsrc_free(state, &rsrcp);
 531                         }
 532                 }
 533         }
 534         mutex_exit(&hermon_userland_rsrc_db.hdl_umapdb_lock);
 535         return (reset_status);
 536 }
 537 
 538 
 539 /*
 540  * hermon_attach()
 541  *    Context: Only called from attach() path context
 542  */
 543 static int
 544 hermon_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 545 {
 546         hermon_state_t  *state;
 547         ibc_clnt_hdl_t  tmp_ibtfpriv;
 548         ibc_status_t    ibc_status;
 549         int             instance;
 550         int             status;
 551 
 552         switch (cmd) {
 553         case DDI_ATTACH:
 554                 instance = ddi_get_instance(dip);
 555                 status = ddi_soft_state_zalloc(hermon_statep, instance);
 556                 if (status != DDI_SUCCESS) {
 557                         cmn_err(CE_NOTE, "hermon%d: driver failed to attach: "
 558                             "attach_ssz_fail", instance);
 559                         goto fail_attach_nomsg;
 560 
 561                 }
 562                 state = ddi_get_soft_state(hermon_statep, instance);
 563                 if (state == NULL) {
 564                         ddi_soft_state_free(hermon_statep, instance);
 565                         cmn_err(CE_NOTE, "hermon%d: driver failed to attach: "
 566                             "attach_gss_fail", instance);
 567                         goto fail_attach_nomsg;
 568                 }
 569 
 570                 /* clear the attach error buffer */
 571                 HERMON_ATTACH_MSG_INIT(state->hs_attach_buf);
 572 
 573                 /* Save away devinfo and instance before hermon_fm_init() */
 574                 state->hs_dip = dip;
 575                 state->hs_instance = instance;
 576 
 577                 hermon_fm_init(state);
 578 
 579                 /*
 580                  * Initialize Hermon driver and hardware.
 581                  *
 582                  * Note: If this initialization fails we may still wish to
 583                  * create a device node and remain operational so that Hermon
 584                  * firmware can be updated/flashed (i.e. "maintenance mode").
 585                  * If this is the case, then "hs_operational_mode" will be
 586                  * equal to HERMON_MAINTENANCE_MODE.  We will not attempt to
 587                  * attach to the IBTF or register with the IBMF (i.e. no
 588                  * InfiniBand interfaces will be enabled).
 589                  */
 590                 status = hermon_drv_init(state, dip, instance);
 591                 if ((status != DDI_SUCCESS) &&
 592                     (HERMON_IS_OPERATIONAL(state->hs_operational_mode))) {
 593                         goto fail_attach;
 594                 }
 595 
 596                 /*
 597                  * Change the Hermon FM mode
 598                  */
 599                 if ((hermon_get_state(state) & HCA_PIO_FM) &&
 600                     HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 601                         /*
 602                          * Now we wait for 50ms to give an opportunity
 603                          * to Solaris FMA so that HW errors can be notified.
 604                          * Then check if there are HW errors or not. If
 605                          * a HW error is detected, the Hermon attachment
 606                          * must be failed.
 607                          */
 608                         delay(drv_usectohz(50000));
 609                         if (hermon_init_failure(state)) {
 610                                 hermon_drv_fini(state);
 611                                 HERMON_WARNING(state, "unable to "
 612                                     "attach Hermon due to a HW error");
 613                                 HERMON_ATTACH_MSG(state->hs_attach_buf,
 614                                     "hermon_attach_failure");
 615                                 goto fail_attach;
 616                         }
 617 
 618                         /*
 619                          * There seems no HW errors during the attachment,
 620                          * so let's change the Hermon FM state to the
 621                          * ereport only mode.
 622                          */
 623                         if (hermon_fm_ereport_init(state) != DDI_SUCCESS) {
 624                                 /* unwind the resources */
 625                                 hermon_drv_fini(state);
 626                                 HERMON_ATTACH_MSG(state->hs_attach_buf,
 627                                     "hermon_attach_failure");
 628                                 goto fail_attach;
 629                         }
 630                 }
 631 
 632                 /* Create the minor node for device */
 633                 status = ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
 634                     DDI_PSEUDO, 0);
 635                 if (status != DDI_SUCCESS) {
 636                         hermon_drv_fini(state);
 637                         HERMON_ATTACH_MSG(state->hs_attach_buf,
 638                             "attach_create_mn_fail");
 639                         goto fail_attach;
 640                 }
 641 
 642                 /*
 643                  * If we are in "maintenance mode", then we don't want to
 644                  * register with the IBTF.  All InfiniBand interfaces are
 645                  * uninitialized, and the device is only capable of handling
 646                  * requests to update/flash firmware (or test/debug requests).
 647                  */
 648                 if (HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 649                         cmn_err(CE_NOTE, "!Hermon is operational\n");
 650 
 651                         /* Attach to InfiniBand Transport Framework (IBTF) */
 652                         ibc_status = ibc_attach(&tmp_ibtfpriv,
 653                             &state->hs_ibtfinfo);
 654                         if (ibc_status != IBC_SUCCESS) {
 655                                 cmn_err(CE_CONT, "hermon_attach: ibc_attach "
 656                                     "failed\n");
 657                                 ddi_remove_minor_node(dip, "devctl");
 658                                 hermon_drv_fini(state);
 659                                 HERMON_ATTACH_MSG(state->hs_attach_buf,
 660                                     "attach_ibcattach_fail");
 661                                 goto fail_attach;
 662                         }
 663 
 664                         /*
 665                          * Now that we've successfully attached to the IBTF,
 666                          * we enable all appropriate asynch and CQ events to
 667                          * be forwarded to the IBTF.
 668                          */
 669                         HERMON_ENABLE_IBTF_CALLB(state, tmp_ibtfpriv);
 670 
 671                         ibc_post_attach(state->hs_ibtfpriv);
 672 
 673                         /* Register agents with IB Mgmt Framework (IBMF) */
 674                         status = hermon_agent_handlers_init(state);
 675                         if (status != DDI_SUCCESS) {
 676                                 (void) ibc_pre_detach(tmp_ibtfpriv, DDI_DETACH);
 677                                 HERMON_QUIESCE_IBTF_CALLB(state);
 678                                 if (state->hs_in_evcallb != 0) {
 679                                         HERMON_WARNING(state, "unable to "
 680                                             "quiesce Hermon IBTF callbacks");
 681                                 }
 682                                 ibc_detach(tmp_ibtfpriv);
 683                                 ddi_remove_minor_node(dip, "devctl");
 684                                 hermon_drv_fini(state);
 685                                 HERMON_ATTACH_MSG(state->hs_attach_buf,
 686                                     "attach_agentinit_fail");
 687                                 goto fail_attach;
 688                         }
 689                 }
 690 
 691                 /* Report attach in maintenance mode, if appropriate */
 692                 if (!(HERMON_IS_OPERATIONAL(state->hs_operational_mode))) {
 693                         cmn_err(CE_NOTE, "hermon%d: driver attached "
 694                             "(for maintenance mode only)", state->hs_instance);
 695                         hermon_fm_ereport(state, HCA_IBA_ERR, HCA_ERR_DEGRADED);
 696                 }
 697 
 698                 /* Report that driver was loaded */
 699                 ddi_report_dev(dip);
 700 
 701                 /* Send device information to log file */
 702                 hermon_device_info_report(state);
 703 
 704                 /* DEBUG PRINT */
 705                 cmn_err(CE_CONT, "!Hermon attach complete\n");
 706                 return (DDI_SUCCESS);
 707 
 708         case DDI_RESUME:
 709                 /* Add code here for DDI_RESUME XXX */
 710                 return (DDI_FAILURE);
 711 
 712         default:
 713                 cmn_err(CE_WARN, "hermon_attach: unknown cmd (0x%x)\n", cmd);
 714                 break;
 715         }
 716 
 717 fail_attach:
 718         cmn_err(CE_NOTE, "hermon%d: driver failed to attach: %s", instance,
 719             state->hs_attach_buf);
 720         if (hermon_get_state(state) & HCA_EREPORT_FM) {
 721                 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_SRV_LOST);
 722         }
 723         hermon_drv_fini2(state);
 724         hermon_fm_fini(state);
 725         ddi_soft_state_free(hermon_statep, instance);
 726 
 727 fail_attach_nomsg:
 728         return (DDI_FAILURE);
 729 }
 730 
 731 
 732 /*
 733  * hermon_detach()
 734  *    Context: Only called from detach() path context
 735  */
 736 static int
 737 hermon_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 738 {
 739         hermon_state_t  *state;
 740         ibc_clnt_hdl_t  tmp_ibtfpriv;
 741         ibc_status_t    ibc_status;
 742         int             instance, status;
 743 
 744         instance = ddi_get_instance(dip);
 745         state = ddi_get_soft_state(hermon_statep, instance);
 746         if (state == NULL) {
 747                 return (DDI_FAILURE);
 748         }
 749 
 750         switch (cmd) {
 751         case DDI_DETACH:
 752                 /*
 753                  * If we are in "maintenance mode", then we do not want to
 754                  * do teardown for any of the InfiniBand interfaces.
 755                  * Specifically, this means not detaching from IBTF (we never
 756                  * attached to begin with) and not deregistering from IBMF.
 757                  */
 758                 if (HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 759                         /* Unregister agents from IB Mgmt Framework (IBMF) */
 760                         status = hermon_agent_handlers_fini(state);
 761                         if (status != DDI_SUCCESS) {
 762                                 return (DDI_FAILURE);
 763                         }
 764 
 765                         /*
 766                          * Attempt the "pre-detach" from InfiniBand Transport
 767                          * Framework (IBTF).  At this point the IBTF is still
 768                          * capable of handling incoming asynch and completion
 769                          * events.  This "pre-detach" is primarily a mechanism
 770                          * to notify the appropriate IBTF clients that the
 771                          * HCA is being removed/offlined.
 772                          */
 773                         ibc_status = ibc_pre_detach(state->hs_ibtfpriv, cmd);
 774                         if (ibc_status != IBC_SUCCESS) {
 775                                 status = hermon_agent_handlers_init(state);
 776                                 if (status != DDI_SUCCESS) {
 777                                         HERMON_WARNING(state, "failed to "
 778                                             "restart Hermon agents");
 779                                 }
 780                                 return (DDI_FAILURE);
 781                         }
 782 
 783                         /*
 784                          * Before we can fully detach from the IBTF we need to
 785                          * ensure that we have handled all outstanding event
 786                          * callbacks.  This is accomplished by quiescing the
 787                          * event callback mechanism.  Note: if we are unable
 788                          * to successfully quiesce the callbacks, then this is
 789                          * an indication that something has probably gone
 790                          * seriously wrong.  We print out a warning, but
 791                          * continue.
 792                          */
 793                         tmp_ibtfpriv = state->hs_ibtfpriv;
 794                         HERMON_QUIESCE_IBTF_CALLB(state);
 795                         if (state->hs_in_evcallb != 0) {
 796                                 HERMON_WARNING(state, "unable to quiesce "
 797                                     "Hermon IBTF callbacks");
 798                         }
 799 
 800                         /* Complete the detach from the IBTF */
 801                         ibc_detach(tmp_ibtfpriv);
 802                 }
 803 
 804                 /* Remove the minor node for device */
 805                 ddi_remove_minor_node(dip, "devctl");
 806 
 807                 /*
 808                  * Only call hermon_drv_fini() if we are in Hermon HCA mode.
 809                  * (Because if we are in "maintenance mode", then we never
 810                  * successfully finished init.)  Only report successful
 811                  * detach for normal HCA mode.
 812                  */
 813                 if (HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
 814                         /* Cleanup driver resources and shutdown hardware */
 815                         hermon_drv_fini(state);
 816                         cmn_err(CE_CONT, "!Hermon driver successfully "
 817                             "detached\n");
 818                 }
 819 
 820                 hermon_drv_fini2(state);
 821                 hermon_fm_fini(state);
 822                 ddi_soft_state_free(hermon_statep, instance);
 823 
 824                 return (DDI_SUCCESS);
 825 
 826         case DDI_SUSPEND:
 827                 /* Add code here for DDI_SUSPEND XXX */
 828                 return (DDI_FAILURE);
 829 
 830         default:
 831                 cmn_err(CE_WARN, "hermon_detach: unknown cmd (0x%x)\n", cmd);
 832                 break;
 833         }
 834 
 835         return (DDI_FAILURE);
 836 }
 837 
 838 /*
 839  * hermon_dma_attr_init()
 840  *    Context: Can be called from interrupt or base context.
 841  */
 842 
 843 /* ARGSUSED */
 844 void
 845 hermon_dma_attr_init(hermon_state_t *state, ddi_dma_attr_t *dma_attr)
 846 {
 847         dma_attr->dma_attr_version   = DMA_ATTR_V0;
 848         dma_attr->dma_attr_addr_lo   = 0;
 849         dma_attr->dma_attr_addr_hi   = 0xFFFFFFFFFFFFFFFFull;
 850         dma_attr->dma_attr_count_max = 0xFFFFFFFFFFFFFFFFull;
 851         dma_attr->dma_attr_align     = HERMON_PAGESIZE;  /* default 4K */
 852         dma_attr->dma_attr_burstsizes        = 0x3FF;
 853         dma_attr->dma_attr_minxfer   = 1;
 854         dma_attr->dma_attr_maxxfer   = 0xFFFFFFFFFFFFFFFFull;
 855         dma_attr->dma_attr_seg               = 0xFFFFFFFFFFFFFFFFull;
 856         dma_attr->dma_attr_sgllen    = 0x7FFFFFFF;
 857         dma_attr->dma_attr_granular  = 1;
 858         dma_attr->dma_attr_flags     = 0;
 859 }
 860 
 861 /*
 862  * hermon_dma_alloc()
 863  *    Context: Can be called from base context.
 864  */
 865 int
 866 hermon_dma_alloc(hermon_state_t *state, hermon_dma_info_t *dma_info,
 867     uint16_t opcode)
 868 {
 869         ddi_dma_handle_t        dma_hdl;
 870         ddi_dma_attr_t          dma_attr;
 871         ddi_acc_handle_t        acc_hdl;
 872         ddi_dma_cookie_t        cookie;
 873         uint64_t                kaddr;
 874         uint64_t                real_len;
 875         uint_t                  ccount;
 876         int                     status;
 877 
 878         hermon_dma_attr_init(state, &dma_attr);
 879 #ifdef  __sparc
 880         if (state->hs_cfg_profile->cp_iommu_bypass == HERMON_BINDMEM_BYPASS)
 881                 dma_attr.dma_attr_flags = DDI_DMA_FORCE_PHYSICAL;
 882 #endif
 883 
 884         /* Allocate a DMA handle */
 885         status = ddi_dma_alloc_handle(state->hs_dip, &dma_attr, DDI_DMA_SLEEP,
 886             NULL, &dma_hdl);
 887         if (status != DDI_SUCCESS) {
 888                 IBTF_DPRINTF_L2("DMA", "alloc handle failed: %d", status);
 889                 cmn_err(CE_CONT, "DMA alloc handle failed(status %d)", status);
 890                 return (DDI_FAILURE);
 891         }
 892 
 893         /* Allocate DMA memory */
 894         status = ddi_dma_mem_alloc(dma_hdl, dma_info->length,
 895             &state->hs_reg_accattr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
 896             (caddr_t *)&kaddr, (size_t *)&real_len, &acc_hdl);
 897         if (status != DDI_SUCCESS) {
 898                 ddi_dma_free_handle(&dma_hdl);
 899                 IBTF_DPRINTF_L2("DMA", "memory alloc failed: %d", status);
 900                 cmn_err(CE_CONT, "DMA memory alloc failed(status %d)", status);
 901                 return (DDI_FAILURE);
 902         }
 903         bzero((caddr_t)(uintptr_t)kaddr, real_len);
 904 
 905         /* Bind the memory to the handle */
 906         status = ddi_dma_addr_bind_handle(dma_hdl, NULL,
 907             (caddr_t)(uintptr_t)kaddr, (size_t)real_len, DDI_DMA_RDWR |
 908             DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &cookie, &ccount);
 909         if (status != DDI_SUCCESS) {
 910                 ddi_dma_mem_free(&acc_hdl);
 911                 ddi_dma_free_handle(&dma_hdl);
 912                 IBTF_DPRINTF_L2("DMA", "bind handle failed: %d", status);
 913                 cmn_err(CE_CONT, "DMA bind handle failed(status %d)", status);
 914                 return (DDI_FAILURE);
 915         }
 916 
 917         /* Package the hermon_dma_info contents and return */
 918         dma_info->vaddr   = kaddr;
 919         dma_info->dma_hdl = dma_hdl;
 920         dma_info->acc_hdl = acc_hdl;
 921 
 922         /* Pass the mapping information to the firmware */
 923         status = hermon_map_cmd_post(state, dma_info, opcode, cookie, ccount);
 924         if (status != DDI_SUCCESS) {
 925                 char *s;
 926                 hermon_dma_free(dma_info);
 927                 switch (opcode) {
 928                 case MAP_ICM:
 929                         s = "MAP_ICM";
 930                         break;
 931                 case MAP_FA:
 932                         s = "MAP_FA";
 933                         break;
 934                 case MAP_ICM_AUX:
 935                         s = "MAP_ICM_AUX";
 936                         break;
 937                 default:
 938                         s = "UNKNOWN";
 939                 }
 940                 cmn_err(CE_NOTE, "Map cmd '%s' failed, status %08x\n",
 941                     s, status);
 942                 return (DDI_FAILURE);
 943         }
 944 
 945         return (DDI_SUCCESS);
 946 }
 947 
 948 /*
 949  * hermon_dma_free()
 950  *    Context: Can be called from base context.
 951  */
 952 void
 953 hermon_dma_free(hermon_dma_info_t *info)
 954 {
 955         /* Unbind the handles and free the memory */
 956         (void) ddi_dma_unbind_handle(info->dma_hdl);
 957         ddi_dma_mem_free(&info->acc_hdl);
 958         ddi_dma_free_handle(&info->dma_hdl);
 959 }
 960 
 961 /* These macros are valid for use only in hermon_icm_alloc/hermon_icm_free. */
 962 #define HERMON_ICM_ALLOC(rsrc) \
 963         hermon_icm_alloc(state, rsrc, index1, index2)
 964 #define HERMON_ICM_FREE(rsrc) \
 965         hermon_icm_free(state, rsrc, index1, index2)
 966 
 967 /*
 968  * hermon_icm_alloc()
 969  *    Context: Can be called from base context.
 970  *
 971  * Only one thread can be here for a given hermon_rsrc_type_t "type".
 972  *
 973  * "num_to_hdl" is set if there is a need for lookups from resource
 974  * number/index to resource handle.  This is needed for QPs/CQs/SRQs
 975  * for the various affiliated events/errors.
 976  */
 977 int
 978 hermon_icm_alloc(hermon_state_t *state, hermon_rsrc_type_t type,
 979     uint32_t index1, uint32_t index2)
 980 {
 981         hermon_icm_table_t      *icm;
 982         hermon_dma_info_t       *dma_info;
 983         uint8_t                 *bitmap;
 984         int                     status;
 985         int                     num_to_hdl = 0;
 986 
 987         if (hermon_verbose) {
 988                 IBTF_DPRINTF_L2("hermon", "hermon_icm_alloc: rsrc_type (0x%x) "
 989                     "index1/2 (0x%x/0x%x)", type, index1, index2);
 990         }
 991 
 992         icm = &state->hs_icm[type];
 993 
 994         switch (type) {
 995         case HERMON_QPC:
 996                 status = HERMON_ICM_ALLOC(HERMON_CMPT_QPC);
 997                 if (status != DDI_SUCCESS) {
 998                         return (status);
 999                 }
1000                 status = HERMON_ICM_ALLOC(HERMON_RDB);
1001                 if (status != DDI_SUCCESS) {    /* undo icm_alloc's */
1002                         HERMON_ICM_FREE(HERMON_CMPT_QPC);
1003                         return (status);
1004                 }
1005                 status = HERMON_ICM_ALLOC(HERMON_ALTC);
1006                 if (status != DDI_SUCCESS) {    /* undo icm_alloc's */
1007                         HERMON_ICM_FREE(HERMON_RDB);
1008                         HERMON_ICM_FREE(HERMON_CMPT_QPC);
1009                         return (status);
1010                 }
1011                 status = HERMON_ICM_ALLOC(HERMON_AUXC);
1012                 if (status != DDI_SUCCESS) {    /* undo icm_alloc's */
1013                         HERMON_ICM_FREE(HERMON_ALTC);
1014                         HERMON_ICM_FREE(HERMON_RDB);
1015                         HERMON_ICM_FREE(HERMON_CMPT_QPC);
1016                         return (status);
1017                 }
1018                 num_to_hdl = 1;
1019                 break;
1020         case HERMON_SRQC:
1021                 status = HERMON_ICM_ALLOC(HERMON_CMPT_SRQC);
1022                 if (status != DDI_SUCCESS) {
1023                         return (status);
1024                 }
1025                 num_to_hdl = 1;
1026                 break;
1027         case HERMON_CQC:
1028                 status = HERMON_ICM_ALLOC(HERMON_CMPT_CQC);
1029                 if (status != DDI_SUCCESS) {
1030                         return (status);
1031                 }
1032                 num_to_hdl = 1;
1033                 break;
1034         case HERMON_EQC:
1035                 status = HERMON_ICM_ALLOC(HERMON_CMPT_EQC);
1036                 if (status != DDI_SUCCESS) {    /* undo icm_alloc's */
1037                         return (status);
1038                 }
1039                 break;
1040         }
1041 
1042         /* ensure existence of bitmap and dmainfo, sets "dma_info" */
1043         hermon_bitmap(bitmap, dma_info, icm, index1, num_to_hdl);
1044 
1045         /* Set up the DMA handle for allocation and mapping */
1046         dma_info += index2;
1047         dma_info->length  = icm->span << icm->log_object_size;
1048         dma_info->icmaddr = icm->icm_baseaddr +
1049             (((index1 << icm->split_shift) +
1050             (index2 << icm->span_shift)) << icm->log_object_size);
1051 
1052         /* Allocate memory for the num_to_qp/cq/srq pointers */
1053         if (num_to_hdl)
1054                 icm->num_to_hdl[index1][index2] =
1055                     kmem_zalloc(HERMON_ICM_SPAN * sizeof (void *), KM_SLEEP);
1056 
1057         if (hermon_verbose) {
1058                 IBTF_DPRINTF_L2("hermon", "alloc DMA: "
1059                     "rsrc (0x%x) index (%x, %x) "
1060                     "icm_addr/len (%llx/%x) bitmap %p", type, index1, index2,
1061                     (longlong_t)dma_info->icmaddr, dma_info->length, bitmap);
1062         }
1063 
1064         /* Allocate and map memory for this span */
1065         status = hermon_dma_alloc(state, dma_info, MAP_ICM);
1066         if (status != DDI_SUCCESS) {
1067                 IBTF_DPRINTF_L2("hermon", "hermon_icm_alloc: DMA "
1068                     "allocation failed, status 0x%x", status);
1069                 switch (type) {
1070                 case HERMON_QPC:
1071                         HERMON_ICM_FREE(HERMON_AUXC);
1072                         HERMON_ICM_FREE(HERMON_ALTC);
1073                         HERMON_ICM_FREE(HERMON_RDB);
1074                         HERMON_ICM_FREE(HERMON_CMPT_QPC);
1075                         break;
1076                 case HERMON_SRQC:
1077                         HERMON_ICM_FREE(HERMON_CMPT_SRQC);
1078                         break;
1079                 case HERMON_CQC:
1080                         HERMON_ICM_FREE(HERMON_CMPT_CQC);
1081                         break;
1082                 case HERMON_EQC:
1083                         HERMON_ICM_FREE(HERMON_CMPT_EQC);
1084                         break;
1085                 }
1086 
1087                 return (DDI_FAILURE);
1088         }
1089         if (hermon_verbose) {
1090                 IBTF_DPRINTF_L2("hermon", "hermon_icm_alloc: mapping ICM: "
1091                     "rsrc_type (0x%x) index (0x%x, 0x%x) alloc length (0x%x) "
1092                     "icm_addr (0x%lx)", type, index1, index2, dma_info->length,
1093                     dma_info->icmaddr);
1094         }
1095 
1096         /* Set the bit for this slot in the table bitmap */
1097         HERMON_BMAP_BIT_SET(icm->icm_bitmap[index1], index2);
1098 
1099         return (DDI_SUCCESS);
1100 }
1101 
1102 /*
1103  * hermon_icm_free()
1104  *    Context: Can be called from base context.
1105  *
1106  * ICM resources have been successfully returned from hermon_icm_alloc().
1107  * Associated dma_info is no longer in use.  Free the ICM backing memory.
1108  */
1109 void
1110 hermon_icm_free(hermon_state_t *state, hermon_rsrc_type_t type,
1111     uint32_t index1, uint32_t index2)
1112 {
1113         hermon_icm_table_t      *icm;
1114         hermon_dma_info_t       *dma_info;
1115         int                     status;
1116 
1117         icm = &state->hs_icm[type];
1118         ASSERT(icm->icm_dma[index1][index2].icm_refcnt == 0);
1119 
1120         if (hermon_verbose) {
1121                 IBTF_DPRINTF_L2("hermon", "hermon_icm_free: rsrc_type (0x%x) "
1122                     "index (0x%x, 0x%x)", type, index1, index2);
1123         }
1124 
1125         dma_info = icm->icm_dma[index1] + index2;
1126 
1127         /* The following only happens if attach() is failing. */
1128         if (dma_info == NULL)
1129                 return;
1130 
1131         /* Unmap the ICM allocation, then free the backing DMA memory */
1132         status = hermon_unmap_icm_cmd_post(state, dma_info);
1133         if (status != DDI_SUCCESS) {
1134                 HERMON_WARNING(state, "UNMAP_ICM failure");
1135         }
1136         hermon_dma_free(dma_info);
1137 
1138         /* Clear the bit in the ICM table bitmap */
1139         HERMON_BMAP_BIT_CLR(icm->icm_bitmap[index1], index2);
1140 
1141         switch (type) {
1142         case HERMON_QPC:
1143                 HERMON_ICM_FREE(HERMON_AUXC);
1144                 HERMON_ICM_FREE(HERMON_ALTC);
1145                 HERMON_ICM_FREE(HERMON_RDB);
1146                 HERMON_ICM_FREE(HERMON_CMPT_QPC);
1147                 break;
1148         case HERMON_SRQC:
1149                 HERMON_ICM_FREE(HERMON_CMPT_SRQC);
1150                 break;
1151         case HERMON_CQC:
1152                 HERMON_ICM_FREE(HERMON_CMPT_CQC);
1153                 break;
1154         case HERMON_EQC:
1155                 HERMON_ICM_FREE(HERMON_CMPT_EQC);
1156                 break;
1157 
1158         }
1159 }
1160 
1161 
1162 /*
1163  * hermon_icm_num_to_hdl()
1164  *    Context: Can be called from base or interrupt context.
1165  *
1166  * Given an index of a resource, index through the sparsely allocated
1167  * arrays to find the pointer to its software handle.  Return NULL if
1168  * any of the arrays of pointers has been freed (should never happen).
1169  */
1170 void *
1171 hermon_icm_num_to_hdl(hermon_state_t *state, hermon_rsrc_type_t type,
1172     uint32_t idx)
1173 {
1174         hermon_icm_table_t      *icm;
1175         uint32_t                span_offset;
1176         uint32_t                index1, index2;
1177         void                    ***p1, **p2;
1178 
1179         icm = &state->hs_icm[type];
1180         hermon_index(index1, index2, idx, icm, span_offset);
1181         p1 = icm->num_to_hdl[index1];
1182         if (p1 == NULL) {
1183                 IBTF_DPRINTF_L2("hermon", "icm_num_to_hdl failed at level 1"
1184                     ": rsrc_type %d, index 0x%x", type, idx);
1185                 return (NULL);
1186         }
1187         p2 = p1[index2];
1188         if (p2 == NULL) {
1189                 IBTF_DPRINTF_L2("hermon", "icm_num_to_hdl failed at level 2"
1190                     ": rsrc_type %d, index 0x%x", type, idx);
1191                 return (NULL);
1192         }
1193         return (p2[span_offset]);
1194 }
1195 
1196 /*
1197  * hermon_icm_set_num_to_hdl()
1198  *    Context: Can be called from base or interrupt context.
1199  *
1200  * Given an index of a resource, we index through the sparsely allocated
1201  * arrays to store the software handle, used by hermon_icm_num_to_hdl().
1202  * This function is used to both set and reset (set to NULL) the handle.
1203  * This table is allocated during ICM allocation for the given resource,
1204  * so its existence is a given, and the store location does not conflict
1205  * with any other stores to the table (no locking needed).
1206  */
1207 void
1208 hermon_icm_set_num_to_hdl(hermon_state_t *state, hermon_rsrc_type_t type,
1209     uint32_t idx, void *hdl)
1210 {
1211         hermon_icm_table_t      *icm;
1212         uint32_t                span_offset;
1213         uint32_t                index1, index2;
1214 
1215         icm = &state->hs_icm[type];
1216         hermon_index(index1, index2, idx, icm, span_offset);
1217         ASSERT((hdl == NULL) ^
1218             (icm->num_to_hdl[index1][index2][span_offset] == NULL));
1219         icm->num_to_hdl[index1][index2][span_offset] = hdl;
1220 }
1221 
1222 /*
1223  * hermon_device_mode()
1224  *    Context: Can be called from base or interrupt context.
1225  *
1226  * Return HERMON_HCA_MODE for operational mode
1227  * Return HERMON_MAINTENANCE_MODE for maintenance mode
1228  * Return 0 otherwise
1229  *
1230  * A non-zero return for either operational or maintenance mode simplifies
1231  * one of the 2 uses of this function.
1232  */
1233 int
1234 hermon_device_mode(hermon_state_t *state)
1235 {
1236         if (state->hs_vendor_id != PCI_VENID_MLX)
1237                 return (0);
1238 
1239         switch (state->hs_device_id) {
1240         case PCI_DEVID_HERMON_SDR:
1241         case PCI_DEVID_HERMON_DDR:
1242         case PCI_DEVID_HERMON_DDRG2:
1243         case PCI_DEVID_HERMON_QDRG2:
1244         case PCI_DEVID_HERMON_QDRG2V:
1245                 return (HERMON_HCA_MODE);
1246         case PCI_DEVID_HERMON_MAINT:
1247                 return (HERMON_MAINTENANCE_MODE);
1248         default:
1249                 return (0);
1250         }
1251 }
1252 
1253 /*
1254  * hermon_drv_init()
1255  *    Context: Only called from attach() path context
1256  */
1257 /* ARGSUSED */
1258 static int
1259 hermon_drv_init(hermon_state_t *state, dev_info_t *dip, int instance)
1260 {
1261         int     status;
1262 
1263         /* Retrieve PCI device, vendor and rev IDs */
1264         state->hs_vendor_id   = HERMON_GET_VENDOR_ID(state->hs_dip);
1265         state->hs_device_id   = HERMON_GET_DEVICE_ID(state->hs_dip);
1266         state->hs_revision_id         = HERMON_GET_REVISION_ID(state->hs_dip);
1267 
1268         /*
1269          * Check and set the operational mode of the device. If the driver is
1270          * bound to the Hermon device in "maintenance mode", then this generally
1271          * means that either the device has been specifically jumpered to
1272          * start in this mode or the firmware boot process has failed to
1273          * successfully load either the primary or the secondary firmware
1274          * image.
1275          */
1276         state->hs_operational_mode = hermon_device_mode(state);
1277         switch (state->hs_operational_mode) {
1278         case HERMON_HCA_MODE:
1279                 state->hs_cfg_profile_setting = HERMON_CFG_MEMFREE;
1280                 break;
1281         case HERMON_MAINTENANCE_MODE:
1282                 HERMON_FMANOTE(state, HERMON_FMA_MAINT);
1283                 state->hs_fm_degraded_reason = HCA_FW_MISC; /* not fw reason */
1284                 return (DDI_FAILURE);
1285         default:
1286                 HERMON_FMANOTE(state, HERMON_FMA_PCIID);
1287                 HERMON_WARNING(state, "unexpected device type detected");
1288                 return (DDI_FAILURE);
1289         }
1290 
1291         /*
1292          * Initialize the Hermon hardware.
1293          *
1294          * Note:  If this routine returns an error, it is often a reasonably
1295          * good indication that something Hermon firmware-related has caused
1296          * the failure or some HW related errors have caused the failure.
1297          * (also there are few possibilities that SW (e.g. SW resource
1298          * shortage) can cause the failure, but the majority case is due to
1299          * either a firmware related error or a HW related one) In order to
1300          * give the user an opportunity (if desired) to update or reflash
1301          * the Hermon firmware image, we set "hs_operational_mode" flag
1302          * (described above) to indicate that we wish to enter maintenance
1303          * mode in case of the firmware-related issue.
1304          */
1305         status = hermon_hw_init(state);
1306         if (status != DDI_SUCCESS) {
1307                 cmn_err(CE_NOTE, "hermon%d: error during attach: %s", instance,
1308                     state->hs_attach_buf);
1309                 return (DDI_FAILURE);
1310         }
1311 
1312         /*
1313          * Now that the ISR has been setup, arm all the EQs for event
1314          * generation.
1315          */
1316 
1317         status = hermon_eq_arm_all(state);
1318         if (status != DDI_SUCCESS) {
1319                 cmn_err(CE_NOTE, "EQ Arm All failed\n");
1320                 hermon_hw_fini(state, HERMON_DRV_CLEANUP_ALL);
1321                 return (DDI_FAILURE);
1322         }
1323 
1324         /* test interrupts and event queues */
1325         status = hermon_nop_post(state, 0x0, 0x0);
1326         if (status != DDI_SUCCESS) {
1327                 cmn_err(CE_NOTE, "Interrupts/EQs failed\n");
1328                 hermon_hw_fini(state, HERMON_DRV_CLEANUP_ALL);
1329                 return (DDI_FAILURE);
1330         }
1331 
1332         /* Initialize Hermon softstate */
1333         status = hermon_soft_state_init(state);
1334         if (status != DDI_SUCCESS) {
1335                 cmn_err(CE_NOTE, "Failed to init soft state\n");
1336                 hermon_hw_fini(state, HERMON_DRV_CLEANUP_ALL);
1337                 return (DDI_FAILURE);
1338         }
1339 
1340         return (DDI_SUCCESS);
1341 }
1342 
1343 
1344 /*
1345  * hermon_drv_fini()
1346  *    Context: Only called from attach() and/or detach() path contexts
1347  */
1348 static void
1349 hermon_drv_fini(hermon_state_t *state)
1350 {
1351         /* Cleanup Hermon softstate */
1352         hermon_soft_state_fini(state);
1353 
1354         /* Cleanup Hermon resources and shutdown hardware */
1355         hermon_hw_fini(state, HERMON_DRV_CLEANUP_ALL);
1356 }
1357 
1358 
1359 /*
1360  * hermon_drv_fini2()
1361  *    Context: Only called from attach() and/or detach() path contexts
1362  */
1363 static void
1364 hermon_drv_fini2(hermon_state_t *state)
1365 {
1366         if (state->hs_fm_poll_thread) {
1367                 ddi_periodic_delete(state->hs_fm_poll_thread);
1368                 state->hs_fm_poll_thread = NULL;
1369         }
1370 
1371         /* HERMON_DRV_CLEANUP_LEVEL1 */
1372         if (state->hs_fm_cmdhdl) {
1373                 hermon_regs_map_free(state, &state->hs_fm_cmdhdl);
1374                 state->hs_fm_cmdhdl = NULL;
1375         }
1376 
1377         if (state->hs_reg_cmdhdl) {
1378                 ddi_regs_map_free(&state->hs_reg_cmdhdl);
1379                 state->hs_reg_cmdhdl = NULL;
1380         }
1381 
1382         /* HERMON_DRV_CLEANUP_LEVEL0 */
1383         if (state->hs_msix_tbl_entries) {
1384                 kmem_free(state->hs_msix_tbl_entries,
1385                     state->hs_msix_tbl_size);
1386                 state->hs_msix_tbl_entries = NULL;
1387         }
1388 
1389         if (state->hs_msix_pba_entries) {
1390                 kmem_free(state->hs_msix_pba_entries,
1391                     state->hs_msix_pba_size);
1392                 state->hs_msix_pba_entries = NULL;
1393         }
1394 
1395         if (state->hs_fm_msix_tblhdl) {
1396                 hermon_regs_map_free(state, &state->hs_fm_msix_tblhdl);
1397                 state->hs_fm_msix_tblhdl = NULL;
1398         }
1399 
1400         if (state->hs_reg_msix_tblhdl) {
1401                 ddi_regs_map_free(&state->hs_reg_msix_tblhdl);
1402                 state->hs_reg_msix_tblhdl = NULL;
1403         }
1404 
1405         if (state->hs_fm_msix_pbahdl) {
1406                 hermon_regs_map_free(state, &state->hs_fm_msix_pbahdl);
1407                 state->hs_fm_msix_pbahdl = NULL;
1408         }
1409 
1410         if (state->hs_reg_msix_pbahdl) {
1411                 ddi_regs_map_free(&state->hs_reg_msix_pbahdl);
1412                 state->hs_reg_msix_pbahdl = NULL;
1413         }
1414 
1415         if (state->hs_fm_pcihdl) {
1416                 hermon_pci_config_teardown(state, &state->hs_fm_pcihdl);
1417                 state->hs_fm_pcihdl = NULL;
1418         }
1419 
1420         if (state->hs_reg_pcihdl) {
1421                 pci_config_teardown(&state->hs_reg_pcihdl);
1422                 state->hs_reg_pcihdl = NULL;
1423         }
1424 }
1425 
1426 
1427 /*
1428  * hermon_isr_init()
1429  *    Context: Only called from attach() path context
1430  */
1431 static int
1432 hermon_isr_init(hermon_state_t *state)
1433 {
1434         int     status;
1435         int     intr;
1436 
1437         for (intr = 0; intr < state->hs_intrmsi_allocd; intr++) {
1438 
1439                 /*
1440                  * Add a handler for the interrupt or MSI
1441                  */
1442                 status = ddi_intr_add_handler(state->hs_intrmsi_hdl[intr],
1443                     hermon_isr, (caddr_t)state, (void *)(uintptr_t)intr);
1444                 if (status  != DDI_SUCCESS) {
1445                         return (DDI_FAILURE);
1446                 }
1447 
1448                 /*
1449                  * Enable the software interrupt.  Note: depending on the value
1450                  * returned in the capability flag, we have to call either
1451                  * ddi_intr_block_enable() or ddi_intr_enable().
1452                  */
1453                 if (state->hs_intrmsi_cap & DDI_INTR_FLAG_BLOCK) {
1454                         status = ddi_intr_block_enable(
1455                             &state->hs_intrmsi_hdl[intr], 1);
1456                         if (status != DDI_SUCCESS) {
1457                                 return (DDI_FAILURE);
1458                         }
1459                 } else {
1460                         status = ddi_intr_enable(state->hs_intrmsi_hdl[intr]);
1461                         if (status != DDI_SUCCESS) {
1462                                 return (DDI_FAILURE);
1463                         }
1464                 }
1465         }
1466 
1467         /*
1468          * Now that the ISR has been enabled, defer arm_all  EQs for event
1469          * generation until later, in case MSIX is enabled
1470          */
1471         return (DDI_SUCCESS);
1472 }
1473 
1474 
1475 /*
1476  * hermon_isr_fini()
1477  *    Context: Only called from attach() and/or detach() path contexts
1478  */
1479 static void
1480 hermon_isr_fini(hermon_state_t *state)
1481 {
1482         int     intr;
1483 
1484         for (intr = 0; intr < state->hs_intrmsi_allocd; intr++) {
1485                 /* Disable the software interrupt */
1486                 if (state->hs_intrmsi_cap & DDI_INTR_FLAG_BLOCK) {
1487                         (void) ddi_intr_block_disable(
1488                             &state->hs_intrmsi_hdl[intr], 1);
1489                 } else {
1490                         (void) ddi_intr_disable(state->hs_intrmsi_hdl[intr]);
1491                 }
1492 
1493                 /*
1494                  * Remove the software handler for the interrupt or MSI
1495                  */
1496                 (void) ddi_intr_remove_handler(state->hs_intrmsi_hdl[intr]);
1497         }
1498 }
1499 
1500 
1501 /*
1502  * Sum of ICM configured values:
1503  *     cMPT, dMPT, MTT, QPC, SRQC, RDB, CQC, ALTC, AUXC, EQC, MCG
1504  *
1505  */
1506 static uint64_t
1507 hermon_size_icm(hermon_state_t *state)
1508 {
1509         hermon_hw_querydevlim_t *devlim;
1510         hermon_cfg_profile_t    *cfg;
1511         uint64_t                num_cmpts, num_dmpts, num_mtts;
1512         uint64_t                num_qpcs, num_srqc, num_rdbs;
1513 #ifndef HERMON_FW_WORKAROUND
1514         uint64_t                num_auxc;
1515 #endif
1516         uint64_t                num_cqcs, num_altc;
1517         uint64_t                num_eqcs, num_mcgs;
1518         uint64_t                size;
1519 
1520         devlim = &state->hs_devlim;
1521         cfg = state->hs_cfg_profile;
1522         /* number of respective entries */
1523         num_cmpts = (uint64_t)0x1 << cfg->cp_log_num_cmpt;
1524         num_mtts = (uint64_t)0x1 << cfg->cp_log_num_mtt;
1525         num_dmpts = (uint64_t)0x1 << cfg->cp_log_num_dmpt;
1526         num_qpcs = (uint64_t)0x1 << cfg->cp_log_num_qp;
1527         num_srqc = (uint64_t)0x1 << cfg->cp_log_num_srq;
1528         num_rdbs = (uint64_t)0x1 << cfg->cp_log_num_rdb;
1529         num_cqcs = (uint64_t)0x1 << cfg->cp_log_num_cq;
1530         num_altc = (uint64_t)0x1 << cfg->cp_log_num_qp;
1531 #ifndef HERMON_FW_WORKAROUND
1532         num_auxc = (uint64_t)0x1 << cfg->cp_log_num_qp;
1533 #endif
1534         num_eqcs = (uint64_t)0x1 << cfg->cp_log_num_eq;
1535         num_mcgs = (uint64_t)0x1 << cfg->cp_log_num_mcg;
1536 
1537         size =
1538             num_cmpts   * devlim->cmpt_entry_sz +
1539             num_dmpts   * devlim->dmpt_entry_sz +
1540             num_mtts    * devlim->mtt_entry_sz +
1541             num_qpcs    * devlim->qpc_entry_sz +
1542             num_srqc    * devlim->srq_entry_sz +
1543             num_rdbs    * devlim->rdmardc_entry_sz +
1544             num_cqcs    * devlim->cqc_entry_sz +
1545             num_altc    * devlim->altc_entry_sz +
1546 #ifdef HERMON_FW_WORKAROUND
1547             0x80000000ull +
1548 #else
1549             num_auxc    * devlim->aux_entry_sz       +
1550 #endif
1551             num_eqcs    * devlim->eqc_entry_sz +
1552             num_mcgs    * HERMON_MCGMEM_SZ(state);
1553         return (size);
1554 }
1555 
1556 
1557 /*
1558  * hermon_hw_init()
1559  *    Context: Only called from attach() path context
1560  */
1561 static int
1562 hermon_hw_init(hermon_state_t *state)
1563 {
1564         hermon_drv_cleanup_level_t      cleanup;
1565         sm_nodeinfo_t                   nodeinfo;
1566         uint64_t                        clr_intr_offset;
1567         int                             status;
1568         uint32_t                        fw_size;        /* in page */
1569         uint64_t                        offset;
1570 
1571         /* This is where driver initialization begins */
1572         cleanup = HERMON_DRV_CLEANUP_LEVEL0;
1573 
1574         /* Setup device access attributes */
1575         state->hs_reg_accattr.devacc_attr_version = DDI_DEVICE_ATTR_V1;
1576         state->hs_reg_accattr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC;
1577         state->hs_reg_accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1578         state->hs_reg_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
1579 
1580         /* Setup fma-protected access attributes */
1581         state->hs_fm_accattr.devacc_attr_version =
1582             hermon_devacc_attr_version(state);
1583         state->hs_fm_accattr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC;
1584         state->hs_fm_accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1585         /* set acc err protection type */
1586         state->hs_fm_accattr.devacc_attr_access =
1587             hermon_devacc_attr_access(state);
1588 
1589         /* Setup for PCI config read/write of HCA device */
1590         status = hermon_pci_config_setup(state, &state->hs_fm_pcihdl);
1591         if (status != DDI_SUCCESS) {
1592                 hermon_hw_fini(state, cleanup);
1593                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1594                     "hw_init_PCI_config_space_regmap_fail");
1595                 /* This case is not the degraded one */
1596                 return (DDI_FAILURE);
1597         }
1598 
1599         /* Map PCI config space and MSI-X tables/pba */
1600         hermon_set_msix_info(state);
1601 
1602         /* Map in Hermon registers (CMD, UAR, MSIX) and setup offsets */
1603         status = hermon_regs_map_setup(state, HERMON_CMD_BAR,
1604             &state->hs_reg_cmd_baseaddr, 0, 0, &state->hs_fm_accattr,
1605             &state->hs_fm_cmdhdl);
1606         if (status != DDI_SUCCESS) {
1607                 hermon_hw_fini(state, cleanup);
1608                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1609                     "hw_init_CMD_BAR_regmap_fail");
1610                 /* This case is not the degraded one */
1611                 return (DDI_FAILURE);
1612         }
1613 
1614         cleanup = HERMON_DRV_CLEANUP_LEVEL1;
1615         /*
1616          * We defer UAR-BAR mapping until later.  Need to know if
1617          * blueflame mapping is to be done, and don't know that until after
1618          * we get the dev_caps, so do it right after that
1619          */
1620 
1621         /*
1622          * There is a third BAR defined for Hermon - it is for MSIX
1623          *
1624          * Will need to explore it's possible need/use w/ Mellanox
1625          * [es] Temporary mapping maybe
1626          */
1627 
1628 #ifdef HERMON_SUPPORTS_MSIX_BAR
1629         status = ddi_regs_map_setup(state->hs_dip, HERMON_MSIX_BAR,
1630             &state->hs_reg_msi_baseaddr, 0, 0, &state->hs_reg_accattr,
1631             &state->hs_reg_msihdl);
1632         if (status != DDI_SUCCESS) {
1633                 hermon_hw_fini(state, cleanup);
1634                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1635                     "hw_init_MSIX_BAR_regmap_fail");
1636                 /* This case is not the degraded one */
1637                 return (DDI_FAILURE);
1638         }
1639 #endif
1640 
1641         cleanup = HERMON_DRV_CLEANUP_LEVEL2;
1642 
1643         /*
1644          * Save interesting registers away. The offsets of the first two
1645          * here (HCR and sw_reset) are detailed in the PRM, the others are
1646          * derived from values in the QUERY_FW output, so we'll save them
1647          * off later.
1648          */
1649         /* Host Command Register (HCR) */
1650         state->hs_cmd_regs.hcr = (hermon_hw_hcr_t *)
1651             ((uintptr_t)state->hs_reg_cmd_baseaddr + HERMON_CMD_HCR_OFFSET);
1652         state->hs_cmd_toggle = 0;    /* initialize it for use */
1653 
1654         /* Software Reset register (sw_reset) and semaphore */
1655         state->hs_cmd_regs.sw_reset = (uint32_t *)
1656             ((uintptr_t)state->hs_reg_cmd_baseaddr +
1657             HERMON_CMD_SW_RESET_OFFSET);
1658         state->hs_cmd_regs.sw_semaphore = (uint32_t *)
1659             ((uintptr_t)state->hs_reg_cmd_baseaddr +
1660             HERMON_CMD_SW_SEMAPHORE_OFFSET);
1661 
1662         /* make sure init'd before we start filling things in */
1663         bzero(&state->hs_hcaparams, sizeof (struct hermon_hw_initqueryhca_s));
1664 
1665         /* Initialize the Phase1 configuration profile */
1666         status = hermon_cfg_profile_init_phase1(state);
1667         if (status != DDI_SUCCESS) {
1668                 hermon_hw_fini(state, cleanup);
1669                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1670                     "hw_init_cfginit1_fail");
1671                 /* This case is not the degraded one */
1672                 return (DDI_FAILURE);
1673         }
1674         cleanup = HERMON_DRV_CLEANUP_LEVEL3;
1675 
1676         /* Do a software reset of the adapter to ensure proper state */
1677         status = hermon_sw_reset(state);
1678         if (status != HERMON_CMD_SUCCESS) {
1679                 hermon_hw_fini(state, cleanup);
1680                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1681                     "hw_init_sw_reset_fail");
1682                 /* This case is not the degraded one */
1683                 return (DDI_FAILURE);
1684         }
1685 
1686         /* Initialize mailboxes */
1687         status = hermon_rsrc_init_phase1(state);
1688         if (status != DDI_SUCCESS) {
1689                 hermon_hw_fini(state, cleanup);
1690                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1691                     "hw_init_rsrcinit1_fail");
1692                 /* This case is not the degraded one */
1693                 return (DDI_FAILURE);
1694         }
1695         cleanup = HERMON_DRV_CLEANUP_LEVEL4;
1696 
1697         /* Post QUERY_FW */
1698         status = hermon_cmn_query_cmd_post(state, QUERY_FW, 0, 0, &state->hs_fw,
1699             sizeof (hermon_hw_queryfw_t), HERMON_CMD_NOSLEEP_SPIN);
1700         if (status != HERMON_CMD_SUCCESS) {
1701                 cmn_err(CE_NOTE, "QUERY_FW command failed: %08x\n", status);
1702                 hermon_hw_fini(state, cleanup);
1703                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1704                     "hw_init_query_fw_cmd_fail");
1705                 /* This case is not the degraded one */
1706                 return (DDI_FAILURE);
1707         }
1708 
1709         /* Validate what/that HERMON FW version is appropriate */
1710 
1711         status = hermon_fw_version_check(state);
1712         if (status != DDI_SUCCESS) {
1713                 HERMON_FMANOTE(state, HERMON_FMA_FWVER);
1714                 if (state->hs_operational_mode == HERMON_HCA_MODE) {
1715                         cmn_err(CE_CONT, "Unsupported Hermon FW version: "
1716                             "expected: %04d.%04d.%04d, "
1717                             "actual: %04d.%04d.%04d\n",
1718                             HERMON_FW_VER_MAJOR,
1719                             HERMON_FW_VER_MINOR,
1720                             HERMON_FW_VER_SUBMINOR,
1721                             state->hs_fw.fw_rev_major,
1722                             state->hs_fw.fw_rev_minor,
1723                             state->hs_fw.fw_rev_subminor);
1724                 } else {
1725                         cmn_err(CE_CONT, "Unsupported FW version: "
1726                             "%04d.%04d.%04d\n",
1727                             state->hs_fw.fw_rev_major,
1728                             state->hs_fw.fw_rev_minor,
1729                             state->hs_fw.fw_rev_subminor);
1730                 }
1731                 state->hs_operational_mode = HERMON_MAINTENANCE_MODE;
1732                 state->hs_fm_degraded_reason = HCA_FW_MISMATCH;
1733                 hermon_hw_fini(state, cleanup);
1734                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1735                     "hw_init_checkfwver_fail");
1736                 /* This case is the degraded one */
1737                 return (HERMON_CMD_BAD_NVMEM);
1738         }
1739 
1740         /*
1741          * Save off the rest of the interesting registers that we'll be using.
1742          * Setup the offsets for the other registers.
1743          */
1744 
1745         /*
1746          * Hermon does the intr_offset from the BAR - technically should get the
1747          * BAR info from the response, but PRM says it's from BAR0-1, which is
1748          * for us the CMD BAR
1749          */
1750 
1751         clr_intr_offset  = state->hs_fw.clr_intr_offs & HERMON_CMD_OFFSET_MASK;
1752 
1753         /* Save Clear Interrupt address */
1754         state->hs_cmd_regs.clr_intr = (uint64_t *)
1755             (uintptr_t)(state->hs_reg_cmd_baseaddr + clr_intr_offset);
1756 
1757         /*
1758          * Set the error buffer also into the structure - used in hermon_event.c
1759          * to check for internal error on the HCA, not reported in eqe or
1760          * (necessarily) by interrupt
1761          */
1762         state->hs_cmd_regs.fw_err_buf = (uint32_t *)(uintptr_t)
1763             (state->hs_reg_cmd_baseaddr + state->hs_fw.error_buf_addr);
1764 
1765         /*
1766          * Invoke a polling thread to check the error buffer periodically.
1767          */
1768         if (!hermon_no_inter_err_chk) {
1769                 state->hs_fm_poll_thread = ddi_periodic_add(
1770                     hermon_inter_err_chk, (void *)state, FM_POLL_INTERVAL,
1771                     DDI_IPL_0);
1772         }
1773 
1774         cleanup = HERMON_DRV_CLEANUP_LEVEL5;
1775 
1776         /*
1777          * Allocate, map, and run the HCA Firmware.
1778          */
1779 
1780         /* Allocate memory for the firmware to load into and map it */
1781 
1782         /* get next higher power of 2 */
1783         fw_size = 1 << highbit(state->hs_fw.fw_pages);
1784         state->hs_fw_dma.length = fw_size << HERMON_PAGESHIFT;
1785         status = hermon_dma_alloc(state, &state->hs_fw_dma, MAP_FA);
1786         if (status != DDI_SUCCESS) {
1787                 cmn_err(CE_NOTE, "FW alloc failed\n");
1788                 hermon_hw_fini(state, cleanup);
1789                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1790                     "hw_init_dma_alloc_fw_fail");
1791                 /* This case is not the degraded one */
1792                 return (DDI_FAILURE);
1793         }
1794 
1795         cleanup = HERMON_DRV_CLEANUP_LEVEL6;
1796 
1797         /* Invoke the RUN_FW cmd to run the firmware */
1798         status = hermon_run_fw_cmd_post(state);
1799         if (status != DDI_SUCCESS) {
1800                 cmn_err(CE_NOTE, "RUN_FW command failed: 0x%08x\n", status);
1801                 if (status == HERMON_CMD_BAD_NVMEM) {
1802                         state->hs_operational_mode = HERMON_MAINTENANCE_MODE;
1803                         state->hs_fm_degraded_reason = HCA_FW_CORRUPT;
1804                 }
1805                 hermon_hw_fini(state, cleanup);
1806                 HERMON_ATTACH_MSG(state->hs_attach_buf, "hw_init_run_fw_fail");
1807                 /*
1808                  * If the status is HERMON_CMD_BAD_NVMEM, it's likely the
1809                  * firmware is corrupted, so the mode falls into the
1810                  * maintenance mode.
1811                  */
1812                 return (status == HERMON_CMD_BAD_NVMEM ? HERMON_CMD_BAD_NVMEM :
1813                     DDI_FAILURE);
1814         }
1815 
1816 
1817         /*
1818          * QUERY DEVICE LIMITS/CAPABILITIES
1819          * NOTE - in Hermon, the command is changed to QUERY_DEV_CAP,
1820          * but for familiarity we have kept the structure name the
1821          * same as Tavor/Arbel
1822          */
1823 
1824         status = hermon_cmn_query_cmd_post(state, QUERY_DEV_CAP, 0, 0,
1825             &state->hs_devlim, sizeof (hermon_hw_querydevlim_t),
1826             HERMON_CMD_NOSLEEP_SPIN);
1827         if (status != HERMON_CMD_SUCCESS) {
1828                 cmn_err(CE_NOTE, "QUERY_DEV_CAP command failed: 0x%08x\n",
1829                     status);
1830                 hermon_hw_fini(state, cleanup);
1831                 HERMON_ATTACH_MSG(state->hs_attach_buf, "hw_init_devcap_fail");
1832                 /* This case is not the degraded one */
1833                 return (DDI_FAILURE);
1834         }
1835 
1836         state->hs_rsvd_eqs = max(state->hs_devlim.num_rsvd_eq,
1837             (4 * state->hs_devlim.num_rsvd_uar));
1838 
1839         /* now we have enough info to map in the UAR BAR */
1840         /*
1841          * First, we figure out how to map the BAR for UAR - use only half if
1842          * BlueFlame is enabled - in that case the mapped length is 1/2 the
1843          * log_max_uar_sz (max__uar - 1) * 1MB ( +20).
1844          */
1845 
1846         if (state->hs_devlim.blu_flm) {              /* Blue Flame Enabled */
1847                 offset = (uint64_t)1 << (state->hs_devlim.log_max_uar_sz + 20);
1848         } else {
1849                 offset = 0;     /* a zero length means map the whole thing */
1850         }
1851         status = hermon_regs_map_setup(state, HERMON_UAR_BAR,
1852             &state->hs_reg_uar_baseaddr, 0, offset, &state->hs_fm_accattr,
1853             &state->hs_fm_uarhdl);
1854         if (status != DDI_SUCCESS) {
1855                 HERMON_ATTACH_MSG(state->hs_attach_buf, "UAR BAR mapping");
1856                 /* This case is not the degraded one */
1857                 return (DDI_FAILURE);
1858         }
1859 
1860         /* and if BlueFlame is enabled, map the other half there */
1861         if (state->hs_devlim.blu_flm) {              /* Blue Flame Enabled */
1862                 offset = (uint64_t)1 << (state->hs_devlim.log_max_uar_sz + 20);
1863                 status = ddi_regs_map_setup(state->hs_dip, HERMON_UAR_BAR,
1864                     &state->hs_reg_bf_baseaddr, offset, offset,
1865                     &state->hs_reg_accattr, &state->hs_reg_bfhdl);
1866                 if (status != DDI_SUCCESS) {
1867                         HERMON_ATTACH_MSG(state->hs_attach_buf,
1868                             "BlueFlame BAR mapping");
1869                         /* This case is not the degraded one */
1870                         return (DDI_FAILURE);
1871                 }
1872                 /* This will be used in hw_fini if we fail to init. */
1873                 state->hs_bf_offset = offset;
1874         }
1875         cleanup = HERMON_DRV_CLEANUP_LEVEL7;
1876 
1877         /* Hermon has a couple of things needed for phase 2 in query port */
1878 
1879         status = hermon_cmn_query_cmd_post(state, QUERY_PORT, 0, 0x01,
1880             &state->hs_queryport, sizeof (hermon_hw_query_port_t),
1881             HERMON_CMD_NOSLEEP_SPIN);
1882         if (status != HERMON_CMD_SUCCESS) {
1883                 cmn_err(CE_NOTE, "QUERY_PORT command failed: 0x%08x\n",
1884                     status);
1885                 hermon_hw_fini(state, cleanup);
1886                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1887                     "hw_init_queryport_fail");
1888                 /* This case is not the degraded one */
1889                 return (DDI_FAILURE);
1890         }
1891 
1892         /* Initialize the Phase2 Hermon configuration profile */
1893         status = hermon_cfg_profile_init_phase2(state);
1894         if (status != DDI_SUCCESS) {
1895                 cmn_err(CE_NOTE, "CFG phase 2 failed: 0x%08x\n", status);
1896                 hermon_hw_fini(state, cleanup);
1897                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1898                     "hw_init_cfginit2_fail");
1899                 /* This case is not the degraded one */
1900                 return (DDI_FAILURE);
1901         }
1902 
1903         /* Determine and set the ICM size */
1904         state->hs_icm_sz = hermon_size_icm(state);
1905         status           = hermon_set_icm_size_cmd_post(state);
1906         if (status != DDI_SUCCESS) {
1907                 cmn_err(CE_NOTE, "Hermon: SET_ICM_SIZE cmd failed: 0x%08x\n",
1908                     status);
1909                 hermon_hw_fini(state, cleanup);
1910                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1911                     "hw_init_seticmsz_fail");
1912                 /* This case is not the degraded one */
1913                 return (DDI_FAILURE);
1914         }
1915         /* alloc icm aux physical memory and map it */
1916 
1917         state->hs_icma_dma.length = 1 << highbit(state->hs_icma_sz);
1918 
1919         status = hermon_dma_alloc(state, &state->hs_icma_dma, MAP_ICM_AUX);
1920         if (status != DDI_SUCCESS) {
1921                 cmn_err(CE_NOTE, "failed to alloc (0x%llx) bytes for ICMA\n",
1922                     (longlong_t)state->hs_icma_dma.length);
1923                 hermon_hw_fini(state, cleanup);
1924                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1925                     "hw_init_dma_alloc_icm_aux_fail");
1926                 /* This case is not the degraded one */
1927                 return (DDI_FAILURE);
1928         }
1929         cleanup = HERMON_DRV_CLEANUP_LEVEL8;
1930 
1931         cleanup = HERMON_DRV_CLEANUP_LEVEL9;
1932 
1933         /* Allocate an array of structures to house the ICM tables */
1934         state->hs_icm = kmem_zalloc(HERMON_NUM_ICM_RESOURCES *
1935             sizeof (hermon_icm_table_t), KM_SLEEP);
1936 
1937         /* Set up the ICM address space and the INIT_HCA command input */
1938         status = hermon_icm_config_setup(state, &state->hs_hcaparams);
1939         if (status != HERMON_CMD_SUCCESS) {
1940                 cmn_err(CE_NOTE, "ICM configuration failed\n");
1941                 hermon_hw_fini(state, cleanup);
1942                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1943                     "hw_init_icm_config_setup_fail");
1944                 /* This case is not the degraded one */
1945                 return (DDI_FAILURE);
1946         }
1947         cleanup = HERMON_DRV_CLEANUP_LEVEL10;
1948 
1949         /* Initialize the adapter with the INIT_HCA cmd */
1950         status = hermon_init_hca_cmd_post(state, &state->hs_hcaparams,
1951             HERMON_CMD_NOSLEEP_SPIN);
1952         if (status != HERMON_CMD_SUCCESS) {
1953                 cmn_err(CE_NOTE, "INIT_HCA command failed: %08x\n", status);
1954                 hermon_hw_fini(state, cleanup);
1955                 HERMON_ATTACH_MSG(state->hs_attach_buf, "hw_init_hca_fail");
1956                 /* This case is not the degraded one */
1957                 return (DDI_FAILURE);
1958         }
1959         cleanup = HERMON_DRV_CLEANUP_LEVEL11;
1960 
1961         /* Enter the second phase of init for Hermon configuration/resources */
1962         status = hermon_rsrc_init_phase2(state);
1963         if (status != DDI_SUCCESS) {
1964                 hermon_hw_fini(state, cleanup);
1965                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1966                     "hw_init_rsrcinit2_fail");
1967                 /* This case is not the degraded one */
1968                 return (DDI_FAILURE);
1969         }
1970         cleanup = HERMON_DRV_CLEANUP_LEVEL12;
1971 
1972         /* Query the adapter via QUERY_ADAPTER */
1973         status = hermon_cmn_query_cmd_post(state, QUERY_ADAPTER, 0, 0,
1974             &state->hs_adapter, sizeof (hermon_hw_queryadapter_t),
1975             HERMON_CMD_NOSLEEP_SPIN);
1976         if (status != HERMON_CMD_SUCCESS) {
1977                 cmn_err(CE_NOTE, "Hermon: QUERY_ADAPTER command failed: %08x\n",
1978                     status);
1979                 hermon_hw_fini(state, cleanup);
1980                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1981                     "hw_init_query_adapter_fail");
1982                 /* This case is not the degraded one */
1983                 return (DDI_FAILURE);
1984         }
1985 
1986         /* Allocate protection domain (PD) for Hermon internal use */
1987         status = hermon_pd_alloc(state, &state->hs_pdhdl_internal,
1988             HERMON_SLEEP);
1989         if (status != DDI_SUCCESS) {
1990                 cmn_err(CE_NOTE, "failed to alloc internal PD\n");
1991                 hermon_hw_fini(state, cleanup);
1992                 HERMON_ATTACH_MSG(state->hs_attach_buf,
1993                     "hw_init_internal_pd_alloc_fail");
1994                 /* This case is not the degraded one */
1995                 return (DDI_FAILURE);
1996         }
1997         cleanup = HERMON_DRV_CLEANUP_LEVEL13;
1998 
1999         /* Setup UAR page for kernel use */
2000         status = hermon_internal_uarpg_init(state);
2001         if (status != DDI_SUCCESS) {
2002                 cmn_err(CE_NOTE, "failed to setup internal UAR\n");
2003                 hermon_hw_fini(state, cleanup);
2004                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2005                     "hw_init_internal_uarpg_alloc_fail");
2006                 /* This case is not the degraded one */
2007                 return (DDI_FAILURE);
2008         }
2009         cleanup = HERMON_DRV_CLEANUP_LEVEL14;
2010 
2011         /* Query and initialize the Hermon interrupt/MSI information */
2012         status = hermon_intr_or_msi_init(state);
2013         if (status != DDI_SUCCESS) {
2014                 cmn_err(CE_NOTE, "failed to setup INTR/MSI\n");
2015                 hermon_hw_fini(state, cleanup);
2016                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2017                     "hw_init_intr_or_msi_init_fail");
2018                 /* This case is not the degraded one */
2019                 return (DDI_FAILURE);
2020         }
2021         cleanup = HERMON_DRV_CLEANUP_LEVEL15;
2022 
2023         status = hermon_isr_init(state);        /* set up the isr */
2024         if (status != DDI_SUCCESS) {
2025                 cmn_err(CE_NOTE, "failed to init isr\n");
2026                 hermon_hw_fini(state, cleanup);
2027                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2028                     "hw_init_isrinit_fail");
2029                 /* This case is not the degraded one */
2030                 return (DDI_FAILURE);
2031         }
2032         cleanup = HERMON_DRV_CLEANUP_LEVEL16;
2033 
2034         /* Setup the event queues */
2035         status = hermon_eq_init_all(state);
2036         if (status != DDI_SUCCESS) {
2037                 cmn_err(CE_NOTE, "failed to init EQs\n");
2038                 hermon_hw_fini(state, cleanup);
2039                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2040                     "hw_init_eqinitall_fail");
2041                 /* This case is not the degraded one */
2042                 return (DDI_FAILURE);
2043         }
2044         cleanup = HERMON_DRV_CLEANUP_LEVEL17;
2045 
2046 
2047 
2048         /* Reserve contexts for QP0 and QP1 */
2049         status = hermon_special_qp_contexts_reserve(state);
2050         if (status != DDI_SUCCESS) {
2051                 cmn_err(CE_NOTE, "failed to init special QPs\n");
2052                 hermon_hw_fini(state, cleanup);
2053                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2054                     "hw_init_rsrv_sqp_fail");
2055                 /* This case is not the degraded one */
2056                 return (DDI_FAILURE);
2057         }
2058         cleanup = HERMON_DRV_CLEANUP_LEVEL18;
2059 
2060         /* Initialize for multicast group handling */
2061         status = hermon_mcg_init(state);
2062         if (status != DDI_SUCCESS) {
2063                 cmn_err(CE_NOTE, "failed to init multicast\n");
2064                 hermon_hw_fini(state, cleanup);
2065                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2066                     "hw_init_mcg_init_fail");
2067                 /* This case is not the degraded one */
2068                 return (DDI_FAILURE);
2069         }
2070         cleanup = HERMON_DRV_CLEANUP_LEVEL19;
2071 
2072         /* Initialize the Hermon IB port(s) */
2073         status = hermon_hca_port_init(state);
2074         if (status != DDI_SUCCESS) {
2075                 cmn_err(CE_NOTE, "failed to init HCA Port\n");
2076                 hermon_hw_fini(state, cleanup);
2077                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2078                     "hw_init_hca_port_init_fail");
2079                 /* This case is not the degraded one */
2080                 return (DDI_FAILURE);
2081         }
2082 
2083         cleanup = HERMON_DRV_CLEANUP_ALL;
2084 
2085         /* Determine NodeGUID and SystemImageGUID */
2086         status = hermon_getnodeinfo_cmd_post(state, HERMON_CMD_NOSLEEP_SPIN,
2087             &nodeinfo);
2088         if (status != HERMON_CMD_SUCCESS) {
2089                 cmn_err(CE_NOTE, "GetNodeInfo command failed: %08x\n", status);
2090                 hermon_hw_fini(state, cleanup);
2091                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2092                     "hw_init_getnodeinfo_cmd_fail");
2093                 /* This case is not the degraded one */
2094                 return (DDI_FAILURE);
2095         }
2096 
2097         /*
2098          * If the NodeGUID value was set in OBP properties, then we use that
2099          * value.  But we still print a message if the value we queried from
2100          * firmware does not match this value.
2101          *
2102          * Otherwise if OBP value is not set then we use the value from
2103          * firmware unconditionally.
2104          */
2105         if (state->hs_cfg_profile->cp_nodeguid) {
2106                 state->hs_nodeguid   = state->hs_cfg_profile->cp_nodeguid;
2107         } else {
2108                 state->hs_nodeguid = nodeinfo.NodeGUID;
2109         }
2110 
2111         if (state->hs_nodeguid != nodeinfo.NodeGUID) {
2112                 cmn_err(CE_NOTE, "!NodeGUID value queried from firmware "
2113                     "does not match value set by device property");
2114         }
2115 
2116         /*
2117          * If the SystemImageGUID value was set in OBP properties, then we use
2118          * that value.  But we still print a message if the value we queried
2119          * from firmware does not match this value.
2120          *
2121          * Otherwise if OBP value is not set then we use the value from
2122          * firmware unconditionally.
2123          */
2124         if (state->hs_cfg_profile->cp_sysimgguid) {
2125                 state->hs_sysimgguid = state->hs_cfg_profile->cp_sysimgguid;
2126         } else {
2127                 state->hs_sysimgguid = nodeinfo.SystemImageGUID;
2128         }
2129 
2130         if (state->hs_sysimgguid != nodeinfo.SystemImageGUID) {
2131                 cmn_err(CE_NOTE, "!SystemImageGUID value queried from firmware "
2132                     "does not match value set by device property");
2133         }
2134 
2135         /* Get NodeDescription */
2136         status = hermon_getnodedesc_cmd_post(state, HERMON_CMD_NOSLEEP_SPIN,
2137             (sm_nodedesc_t *)&state->hs_nodedesc);
2138         if (status != HERMON_CMD_SUCCESS) {
2139                 cmn_err(CE_CONT, "GetNodeDesc command failed: %08x\n", status);
2140                 hermon_hw_fini(state, cleanup);
2141                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2142                     "hw_init_getnodedesc_cmd_fail");
2143                 /* This case is not the degraded one */
2144                 return (DDI_FAILURE);
2145         }
2146 
2147         return (DDI_SUCCESS);
2148 }
2149 
2150 
2151 /*
2152  * hermon_hw_fini()
2153  *    Context: Only called from attach() and/or detach() path contexts
2154  */
2155 static void
2156 hermon_hw_fini(hermon_state_t *state, hermon_drv_cleanup_level_t cleanup)
2157 {
2158         uint_t          num_ports;
2159         int             i, status;
2160 
2161 
2162         /*
2163          * JBDB - We might not want to run these returns in all cases of
2164          * Bad News. We should still attempt to free all of the DMA memory
2165          * resources...  This needs to be worked last, after all allocations
2166          * are implemented. For now, and possibly for later, this works.
2167          */
2168 
2169         switch (cleanup) {
2170         /*
2171          * If we add more driver initialization steps that should be cleaned
2172          * up here, we need to ensure that HERMON_DRV_CLEANUP_ALL is still the
2173          * first entry (i.e. corresponds to the last init step).
2174          */
2175         case HERMON_DRV_CLEANUP_ALL:
2176                 /* Shutdown the Hermon IB port(s) */
2177                 num_ports = state->hs_cfg_profile->cp_num_ports;
2178                 (void) hermon_hca_ports_shutdown(state, num_ports);
2179                 /* FALLTHROUGH */
2180 
2181         case HERMON_DRV_CLEANUP_LEVEL19:
2182                 /* Teardown resources used for multicast group handling */
2183                 hermon_mcg_fini(state);
2184                 /* FALLTHROUGH */
2185 
2186         case HERMON_DRV_CLEANUP_LEVEL18:
2187                 /* Unreserve the special QP contexts */
2188                 hermon_special_qp_contexts_unreserve(state);
2189                 /* FALLTHROUGH */
2190 
2191         case HERMON_DRV_CLEANUP_LEVEL17:
2192                 /*
2193                  * Attempt to teardown all event queues (EQ).  If we fail
2194                  * here then print a warning message and return.  Something
2195                  * (either in HW or SW) has gone seriously wrong.
2196                  */
2197                 status = hermon_eq_fini_all(state);
2198                 if (status != DDI_SUCCESS) {
2199                         HERMON_WARNING(state, "failed to teardown EQs");
2200                         return;
2201                 }
2202                 /* FALLTHROUGH */
2203         case HERMON_DRV_CLEANUP_LEVEL16:
2204                 /* Teardown Hermon interrupts */
2205                 hermon_isr_fini(state);
2206                 /* FALLTHROUGH */
2207 
2208         case HERMON_DRV_CLEANUP_LEVEL15:
2209                 status = hermon_intr_or_msi_fini(state);
2210                 if (status != DDI_SUCCESS) {
2211                         HERMON_WARNING(state, "failed to free intr/MSI");
2212                         return;
2213                 }
2214                 /* FALLTHROUGH */
2215 
2216         case HERMON_DRV_CLEANUP_LEVEL14:
2217                 /* Free the resources for the Hermon internal UAR pages */
2218                 hermon_internal_uarpg_fini(state);
2219                 /* FALLTHROUGH */
2220 
2221         case HERMON_DRV_CLEANUP_LEVEL13:
2222                 /*
2223                  * Free the PD that was used internally by Hermon software.  If
2224                  * we fail here then print a warning and return.  Something
2225                  * (probably software-related, but perhaps HW) has gone wrong.
2226                  */
2227                 status = hermon_pd_free(state, &state->hs_pdhdl_internal);
2228                 if (status != DDI_SUCCESS) {
2229                         HERMON_WARNING(state, "failed to free internal PD");
2230                         return;
2231                 }
2232                 /* FALLTHROUGH */
2233 
2234         case HERMON_DRV_CLEANUP_LEVEL12:
2235                 /* Cleanup all the phase2 resources first */
2236                 hermon_rsrc_fini(state, HERMON_RSRC_CLEANUP_ALL);
2237                 /* FALLTHROUGH */
2238 
2239         case HERMON_DRV_CLEANUP_LEVEL11:
2240                 /* LEVEL11 is after INIT_HCA */
2241                 /* FALLTHROUGH */
2242 
2243 
2244         case HERMON_DRV_CLEANUP_LEVEL10:
2245                 /*
2246                  * Unmap the ICM memory area with UNMAP_ICM command.
2247                  */
2248                 status = hermon_unmap_icm_cmd_post(state, NULL);
2249                 if (status != DDI_SUCCESS) {
2250                         cmn_err(CE_WARN,
2251                             "hermon_hw_fini: failed to unmap ICM\n");
2252                 }
2253 
2254                 /* Free the initial ICM DMA handles */
2255                 hermon_icm_dma_fini(state);
2256 
2257                 /* Free the ICM table structures */
2258                 hermon_icm_tables_fini(state);
2259 
2260                 /* Free the ICM table handles */
2261                 kmem_free(state->hs_icm, HERMON_NUM_ICM_RESOURCES *
2262                     sizeof (hermon_icm_table_t));
2263 
2264                 /* FALLTHROUGH */
2265 
2266         case HERMON_DRV_CLEANUP_LEVEL9:
2267                 /*
2268                  * Unmap the ICM Aux memory area with UNMAP_ICM_AUX command.
2269                  */
2270                 status = hermon_unmap_icm_aux_cmd_post(state);
2271                 if (status != HERMON_CMD_SUCCESS) {
2272                         cmn_err(CE_NOTE,
2273                             "hermon_hw_fini: failed to unmap ICMA\n");
2274                 }
2275                 /* FALLTHROUGH */
2276 
2277         case HERMON_DRV_CLEANUP_LEVEL8:
2278                 /*
2279                  * Deallocate ICM Aux DMA memory.
2280                  */
2281                 hermon_dma_free(&state->hs_icma_dma);
2282                 /* FALLTHROUGH */
2283 
2284         case HERMON_DRV_CLEANUP_LEVEL7:
2285                 if (state->hs_fm_uarhdl) {
2286                         hermon_regs_map_free(state, &state->hs_fm_uarhdl);
2287                         state->hs_fm_uarhdl = NULL;
2288                 }
2289 
2290                 if (state->hs_reg_uarhdl) {
2291                         ddi_regs_map_free(&state->hs_reg_uarhdl);
2292                         state->hs_reg_uarhdl = NULL;
2293                 }
2294 
2295                 if (state->hs_bf_offset != 0 && state->hs_reg_bfhdl) {
2296                         ddi_regs_map_free(&state->hs_reg_bfhdl);
2297                         state->hs_reg_bfhdl = NULL;
2298                 }
2299 
2300                 for (i = 0; i < HERMON_MAX_PORTS; i++) {
2301                         if (state->hs_pkey[i]) {
2302                                 kmem_free(state->hs_pkey[i], (1 <<
2303                                     state->hs_cfg_profile->cp_log_max_pkeytbl) *
2304                                     sizeof (ib_pkey_t));
2305                                 state->hs_pkey[i] = NULL;
2306                         }
2307                         if (state->hs_guid[i]) {
2308                                 kmem_free(state->hs_guid[i], (1 <<
2309                                     state->hs_cfg_profile->cp_log_max_gidtbl) *
2310                                     sizeof (ib_guid_t));
2311                                 state->hs_guid[i] = NULL;
2312                         }
2313                 }
2314                 /* FALLTHROUGH */
2315 
2316         case HERMON_DRV_CLEANUP_LEVEL6:
2317                 /*
2318                  * Unmap the firmware memory area with UNMAP_FA command.
2319                  */
2320                 status = hermon_unmap_fa_cmd_post(state);
2321 
2322                 if (status != HERMON_CMD_SUCCESS) {
2323                         cmn_err(CE_NOTE,
2324                             "hermon_hw_fini: failed to unmap FW\n");
2325                 }
2326 
2327                 /*
2328                  * Deallocate firmware DMA memory.
2329                  */
2330                 hermon_dma_free(&state->hs_fw_dma);
2331                 /* FALLTHROUGH */
2332 
2333         case HERMON_DRV_CLEANUP_LEVEL5:
2334                 /* stop the poll thread */
2335                 if (state->hs_fm_poll_thread) {
2336                         ddi_periodic_delete(state->hs_fm_poll_thread);
2337                         state->hs_fm_poll_thread = NULL;
2338                 }
2339                 /* FALLTHROUGH */
2340 
2341         case HERMON_DRV_CLEANUP_LEVEL4:
2342                 /* Then cleanup the phase1 resources */
2343                 hermon_rsrc_fini(state, HERMON_RSRC_CLEANUP_PHASE1_COMPLETE);
2344                 /* FALLTHROUGH */
2345 
2346         case HERMON_DRV_CLEANUP_LEVEL3:
2347                 /* Teardown any resources allocated for the config profile */
2348                 hermon_cfg_profile_fini(state);
2349                 /* FALLTHROUGH */
2350 
2351         case HERMON_DRV_CLEANUP_LEVEL2:
2352 #ifdef HERMON_SUPPORTS_MSIX_BAR
2353                 /*
2354                  * unmap 3rd BAR, MSIX BAR
2355                  */
2356                 if (state->hs_reg_msihdl) {
2357                         ddi_regs_map_free(&state->hs_reg_msihdl);
2358                         state->hs_reg_msihdl = NULL;
2359                 }
2360                 /* FALLTHROUGH */
2361 #endif
2362         case HERMON_DRV_CLEANUP_LEVEL1:
2363         case HERMON_DRV_CLEANUP_LEVEL0:
2364                 /*
2365                  * LEVEL1 and LEVEL0 resources are freed in
2366                  * hermon_drv_fini2().
2367                  */
2368                 break;
2369 
2370         default:
2371                 HERMON_WARNING(state, "unexpected driver cleanup level");
2372                 return;
2373         }
2374 }
2375 
2376 
2377 /*
2378  * hermon_soft_state_init()
2379  *    Context: Only called from attach() path context
2380  */
2381 static int
2382 hermon_soft_state_init(hermon_state_t *state)
2383 {
2384         ibt_hca_attr_t          *hca_attr;
2385         uint64_t                maxval, val;
2386         ibt_hca_flags_t         caps = IBT_HCA_NO_FLAGS;
2387         ibt_hca_flags2_t        caps2 = IBT_HCA2_NO_FLAGS;
2388         int                     status;
2389         int                     max_send_wqe_bytes;
2390         int                     max_recv_wqe_bytes;
2391 
2392         /*
2393          * The ibc_hca_info_t struct is passed to the IBTF.  This is the
2394          * routine where we initialize it.  Many of the init values come from
2395          * either configuration variables or successful queries of the Hermon
2396          * hardware abilities
2397          */
2398         state->hs_ibtfinfo.hca_ci_vers       = IBCI_V4;
2399         state->hs_ibtfinfo.hca_handle        = (ibc_hca_hdl_t)state;
2400         state->hs_ibtfinfo.hca_ops   = &hermon_ibc_ops;
2401 
2402         hca_attr = kmem_zalloc(sizeof (ibt_hca_attr_t), KM_SLEEP);
2403         state->hs_ibtfinfo.hca_attr = hca_attr;
2404 
2405         hca_attr->hca_dip = state->hs_dip;
2406         hca_attr->hca_fw_major_version = state->hs_fw.fw_rev_major;
2407         hca_attr->hca_fw_minor_version = state->hs_fw.fw_rev_minor;
2408         hca_attr->hca_fw_micro_version = state->hs_fw.fw_rev_subminor;
2409 
2410         /* CQ interrupt moderation maximums - each limited to 16 bits */
2411         hca_attr->hca_max_cq_mod_count = 0xFFFF;
2412         hca_attr->hca_max_cq_mod_usec = 0xFFFF;
2413         hca_attr->hca_max_cq_handlers = state->hs_intrmsi_allocd;
2414 
2415 
2416         /*
2417          * Determine HCA capabilities:
2418          * No default support for IBT_HCA_RD, IBT_HCA_RAW_MULTICAST,
2419          *    IBT_HCA_ATOMICS_GLOBAL, IBT_HCA_RESIZE_CHAN, IBT_HCA_INIT_TYPE,
2420          *    or IBT_HCA_SHUTDOWN_PORT
2421          * But IBT_HCA_AH_PORT_CHECK, IBT_HCA_SQD_RTS_PORT, IBT_HCA_SI_GUID,
2422          *    IBT_HCA_RNR_NAK, IBT_HCA_CURRENT_QP_STATE, IBT_HCA_PORT_UP,
2423          *    IBT_HCA_SRQ, IBT_HCA_RESIZE_SRQ and IBT_HCA_FMR are always
2424          *    supported
2425          * All other features are conditionally supported, depending on the
2426          *    status return by the Hermon HCA in QUERY_DEV_LIM.
2427          */
2428         if (state->hs_devlim.ud_multi) {
2429                 caps |= IBT_HCA_UD_MULTICAST;
2430         }
2431         if (state->hs_devlim.atomic) {
2432                 caps |= IBT_HCA_ATOMICS_HCA;
2433         }
2434         if (state->hs_devlim.apm) {
2435                 caps |= IBT_HCA_AUTO_PATH_MIG;
2436         }
2437         if (state->hs_devlim.pkey_v) {
2438                 caps |= IBT_HCA_PKEY_CNTR;
2439         }
2440         if (state->hs_devlim.qkey_v) {
2441                 caps |= IBT_HCA_QKEY_CNTR;
2442         }
2443         if (state->hs_devlim.ipoib_cksm) {
2444                 caps |= IBT_HCA_CKSUM_FULL;
2445                 caps2 |= IBT_HCA2_IP_CLASS;
2446         }
2447         if (state->hs_devlim.mod_wr_srq) {
2448                 caps |= IBT_HCA_RESIZE_SRQ;
2449         }
2450         if (state->hs_devlim.lif) {
2451                 caps |= IBT_HCA_LOCAL_INVAL_FENCE;
2452         }
2453         if (state->hs_devlim.reserved_lkey) {
2454                 caps2 |= IBT_HCA2_RES_LKEY;
2455                 hca_attr->hca_reserved_lkey = state->hs_devlim.rsv_lkey;
2456         }
2457         if (state->hs_devlim.local_inv && state->hs_devlim.remote_inv &&
2458             state->hs_devlim.fast_reg_wr) {  /* fw needs to be >= 2.7.000 */
2459                 if ((state->hs_fw.fw_rev_major > 2) ||
2460                     ((state->hs_fw.fw_rev_major == 2) &&
2461                     (state->hs_fw.fw_rev_minor >= 7)))
2462                         caps2 |= IBT_HCA2_MEM_MGT_EXT;
2463         }
2464         if (state->hs_devlim.log_max_rss_tbl_sz) {
2465                 hca_attr->hca_rss_max_log2_table =
2466                     state->hs_devlim.log_max_rss_tbl_sz;
2467                 if (state->hs_devlim.rss_xor)
2468                         caps2 |= IBT_HCA2_RSS_XOR_ALG;
2469                 if (state->hs_devlim.rss_toep)
2470                         caps2 |= IBT_HCA2_RSS_TPL_ALG;
2471         }
2472         if (state->hs_devlim.mps) {
2473                 caps |= IBT_HCA_ZERO_BASED_VA;
2474         }
2475         if (state->hs_devlim.zb) {
2476                 caps |= IBT_HCA_MULT_PAGE_SZ_MR;
2477         }
2478         caps |= (IBT_HCA_AH_PORT_CHECK | IBT_HCA_SQD_SQD_PORT |
2479             IBT_HCA_SI_GUID | IBT_HCA_RNR_NAK | IBT_HCA_CURRENT_QP_STATE |
2480             IBT_HCA_PORT_UP | IBT_HCA_RC_SRQ | IBT_HCA_UD_SRQ | IBT_HCA_FMR);
2481         caps2 |= IBT_HCA2_DMA_MR;
2482 
2483         if (state->hs_devlim.log_max_gso_sz) {
2484                 hca_attr->hca_max_lso_size =
2485                     (1 << state->hs_devlim.log_max_gso_sz);
2486                 /* 64 = ctrl & datagram seg, 4 = LSO seg, 16 = 1 SGL */
2487                 hca_attr->hca_max_lso_hdr_size =
2488                     state->hs_devlim.max_desc_sz_sq - (64 + 4 + 16);
2489         }
2490 
2491         caps |= IBT_HCA_WQE_SIZE_INFO;
2492         max_send_wqe_bytes = state->hs_devlim.max_desc_sz_sq;
2493         max_recv_wqe_bytes = state->hs_devlim.max_desc_sz_rq;
2494         hca_attr->hca_ud_send_sgl_sz = (max_send_wqe_bytes / 16) - 4;
2495         hca_attr->hca_conn_send_sgl_sz = (max_send_wqe_bytes / 16) - 1;
2496         hca_attr->hca_conn_rdma_sgl_overhead = 1;
2497         hca_attr->hca_conn_rdma_write_sgl_sz = (max_send_wqe_bytes / 16) - 2;
2498         hca_attr->hca_conn_rdma_read_sgl_sz = (512 / 16) - 2; /* see PRM */
2499         hca_attr->hca_recv_sgl_sz = max_recv_wqe_bytes / 16;
2500 
2501         /* We choose not to support "inline" unless it improves performance */
2502         hca_attr->hca_max_inline_size = 0;
2503         hca_attr->hca_ud_send_inline_sz = 0;
2504         hca_attr->hca_conn_send_inline_sz = 0;
2505         hca_attr->hca_conn_rdmaw_inline_overhead = 4;
2506 
2507 #if defined(_ELF64)
2508         /* 32-bit kernels are too small for Fibre Channel over IB */
2509         if (state->hs_devlim.fcoib && (caps2 & IBT_HCA2_MEM_MGT_EXT)) {
2510                 caps2 |= IBT_HCA2_FC;
2511                 hca_attr->hca_rfci_max_log2_qp = 7;  /* 128 per port */
2512                 hca_attr->hca_fexch_max_log2_qp = 16;        /* 64K per port */
2513                 hca_attr->hca_fexch_max_log2_mem = 20;       /* 1MB per MPT */
2514         }
2515 #endif
2516 
2517         hca_attr->hca_flags = caps;
2518         hca_attr->hca_flags2 = caps2;
2519 
2520         /*
2521          * Set hca_attr's IDs
2522          */
2523         hca_attr->hca_vendor_id       = state->hs_vendor_id;
2524         hca_attr->hca_device_id       = state->hs_device_id;
2525         hca_attr->hca_version_id = state->hs_revision_id;
2526 
2527         /*
2528          * Determine number of available QPs and max QP size.  Number of
2529          * available QPs is determined by subtracting the number of
2530          * "reserved QPs" (i.e. reserved for firmware use) from the
2531          * total number configured.
2532          */
2533         val = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_qp);
2534         hca_attr->hca_max_qp = val - ((uint64_t)1 <<
2535             state->hs_devlim.log_rsvd_qp);
2536         maxval  = ((uint64_t)1 << state->hs_devlim.log_max_qp_sz);
2537         val     = ((uint64_t)1 << state->hs_cfg_profile->cp_log_max_qp_sz);
2538         if (val > maxval) {
2539                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2540                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2541                     "soft_state_init_maxqpsz_toobig_fail");
2542                 return (DDI_FAILURE);
2543         }
2544         /* we need to reduce this by the max space needed for headroom */
2545         hca_attr->hca_max_qp_sz = (uint_t)val - (HERMON_QP_OH_SIZE >>
2546             HERMON_QP_WQE_LOG_MINIMUM) - 1;
2547 
2548         /*
2549          * Determine max scatter-gather size in WQEs. The HCA has split
2550          * the max sgl into rec'v Q and send Q values. Use the least.
2551          *
2552          * This is mainly useful for legacy clients.  Smart clients
2553          * such as IPoIB will use the IBT_HCA_WQE_SIZE_INFO sgl info.
2554          */
2555         if (state->hs_devlim.max_sg_rq <= state->hs_devlim.max_sg_sq) {
2556                 maxval = state->hs_devlim.max_sg_rq;
2557         } else {
2558                 maxval = state->hs_devlim.max_sg_sq;
2559         }
2560         val     = state->hs_cfg_profile->cp_wqe_max_sgl;
2561         if (val > maxval) {
2562                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2563                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2564                     "soft_state_init_toomanysgl_fail");
2565                 return (DDI_FAILURE);
2566         }
2567         /* If the rounded value for max SGL is too large, cap it */
2568         if (state->hs_cfg_profile->cp_wqe_real_max_sgl > maxval) {
2569                 state->hs_cfg_profile->cp_wqe_real_max_sgl = (uint32_t)maxval;
2570                 val = maxval;
2571         } else {
2572                 val = state->hs_cfg_profile->cp_wqe_real_max_sgl;
2573         }
2574 
2575         hca_attr->hca_max_sgl         = (uint_t)val;
2576         hca_attr->hca_max_rd_sgl = 0;        /* zero because RD is unsupported */
2577 
2578         /*
2579          * Determine number of available CQs and max CQ size. Number of
2580          * available CQs is determined by subtracting the number of
2581          * "reserved CQs" (i.e. reserved for firmware use) from the
2582          * total number configured.
2583          */
2584         val = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_cq);
2585         hca_attr->hca_max_cq = val - ((uint64_t)1 <<
2586             state->hs_devlim.log_rsvd_cq);
2587         maxval  = ((uint64_t)1 << state->hs_devlim.log_max_cq_sz);
2588         val     = ((uint64_t)1 << state->hs_cfg_profile->cp_log_max_cq_sz) - 1;
2589         if (val > maxval) {
2590                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2591                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2592                     "soft_state_init_maxcqsz_toobig_fail");
2593                 return (DDI_FAILURE);
2594         }
2595         hca_attr->hca_max_cq_sz = (uint_t)val;
2596 
2597         /*
2598          * Determine number of available SRQs and max SRQ size. Number of
2599          * available SRQs is determined by subtracting the number of
2600          * "reserved SRQs" (i.e. reserved for firmware use) from the
2601          * total number configured.
2602          */
2603         val = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_srq);
2604         hca_attr->hca_max_srqs = val - ((uint64_t)1 <<
2605             state->hs_devlim.log_rsvd_srq);
2606         maxval  = ((uint64_t)1 << state->hs_devlim.log_max_srq_sz);
2607         val     = ((uint64_t)1 << state->hs_cfg_profile->cp_log_max_srq_sz);
2608 
2609         if (val > maxval) {
2610                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2611                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2612                     "soft_state_init_maxsrqsz_toobig_fail");
2613                 return (DDI_FAILURE);
2614         }
2615         hca_attr->hca_max_srqs_sz = (uint_t)val;
2616 
2617         val     = hca_attr->hca_recv_sgl_sz - 1; /* SRQ has a list link */
2618         maxval  = state->hs_devlim.max_sg_rq - 1;
2619         if (val > maxval) {
2620                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2621                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2622                     "soft_state_init_toomanysrqsgl_fail");
2623                 return (DDI_FAILURE);
2624         }
2625         hca_attr->hca_max_srq_sgl = (uint_t)val;
2626 
2627         /*
2628          * Determine supported HCA page sizes
2629          * XXX
2630          * For now we simply return the system pagesize as the only supported
2631          * pagesize
2632          */
2633         hca_attr->hca_page_sz = ((PAGESIZE == (1 << 13)) ? IBT_PAGE_8K :
2634             IBT_PAGE_4K);
2635 
2636         /*
2637          * Determine number of available MemReg, MemWin, and their max size.
2638          * Number of available MRs and MWs is determined by subtracting
2639          * the number of "reserved MPTs" (i.e. reserved for firmware use)
2640          * from the total number configured for each.
2641          */
2642         val = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_dmpt);
2643         hca_attr->hca_max_memr         = val - ((uint64_t)1 <<
2644             state->hs_devlim.log_rsvd_dmpt);
2645         hca_attr->hca_max_mem_win = state->hs_devlim.mem_win ? (val -
2646             ((uint64_t)1 << state->hs_devlim.log_rsvd_dmpt)) : 0;
2647         maxval  = state->hs_devlim.log_max_mrw_sz;
2648         val     = state->hs_cfg_profile->cp_log_max_mrw_sz;
2649         if (val > maxval) {
2650                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2651                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2652                     "soft_state_init_maxmrwsz_toobig_fail");
2653                 return (DDI_FAILURE);
2654         }
2655         hca_attr->hca_max_memr_len = ((uint64_t)1 << val);
2656 
2657         /* Determine RDMA/Atomic properties */
2658         val = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_rdb);
2659         hca_attr->hca_max_rsc = (uint_t)val;
2660         val = state->hs_cfg_profile->cp_hca_max_rdma_in_qp;
2661         hca_attr->hca_max_rdma_in_qp  = (uint8_t)val;
2662         val = state->hs_cfg_profile->cp_hca_max_rdma_out_qp;
2663         hca_attr->hca_max_rdma_out_qp = (uint8_t)val;
2664         hca_attr->hca_max_rdma_in_ee  = 0;
2665         hca_attr->hca_max_rdma_out_ee = 0;
2666 
2667         /*
2668          * Determine maximum number of raw IPv6 and Ether QPs.  Set to 0
2669          * because neither type of raw QP is supported
2670          */
2671         hca_attr->hca_max_ipv6_qp  = 0;
2672         hca_attr->hca_max_ether_qp = 0;
2673 
2674         /* Determine max number of MCGs and max QP-per-MCG */
2675         val = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_qp);
2676         hca_attr->hca_max_mcg_qps   = (uint_t)val;
2677         val = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_mcg);
2678         hca_attr->hca_max_mcg            = (uint_t)val;
2679         val = state->hs_cfg_profile->cp_num_qp_per_mcg;
2680         hca_attr->hca_max_qp_per_mcg = (uint_t)val;
2681 
2682         /* Determine max number partitions (i.e. PKeys) */
2683         maxval  = ((uint64_t)state->hs_cfg_profile->cp_num_ports <<
2684             state->hs_queryport.log_max_pkey);
2685         val     = ((uint64_t)state->hs_cfg_profile->cp_num_ports <<
2686             state->hs_cfg_profile->cp_log_max_pkeytbl);
2687 
2688         if (val > maxval) {
2689                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2690                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2691                     "soft_state_init_toomanypkey_fail");
2692                 return (DDI_FAILURE);
2693         }
2694         hca_attr->hca_max_partitions = (uint16_t)val;
2695 
2696         /* Determine number of ports */
2697         maxval = state->hs_devlim.num_ports;
2698         val = state->hs_cfg_profile->cp_num_ports;
2699         if ((val > maxval) || (val == 0)) {
2700                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2701                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2702                     "soft_state_init_toomanyports_fail");
2703                 return (DDI_FAILURE);
2704         }
2705         hca_attr->hca_nports = (uint8_t)val;
2706 
2707         /* Copy NodeGUID and SystemImageGUID from softstate */
2708         hca_attr->hca_node_guid = state->hs_nodeguid;
2709         hca_attr->hca_si_guid        = state->hs_sysimgguid;
2710 
2711         /*
2712          * Determine local ACK delay.  Use the value suggested by the Hermon
2713          * hardware (from the QUERY_DEV_CAP command)
2714          */
2715         hca_attr->hca_local_ack_delay = state->hs_devlim.ca_ack_delay;
2716 
2717         /* Determine max SGID table and PKey table sizes */
2718         val     = ((uint64_t)1 << state->hs_cfg_profile->cp_log_max_gidtbl);
2719         hca_attr->hca_max_port_sgid_tbl_sz = (uint_t)val;
2720         val     = ((uint64_t)1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
2721         hca_attr->hca_max_port_pkey_tbl_sz = (uint16_t)val;
2722 
2723         /* Determine max number of PDs */
2724         maxval  = ((uint64_t)1 << state->hs_devlim.log_max_pd);
2725         val     = ((uint64_t)1 << state->hs_cfg_profile->cp_log_num_pd);
2726         if (val > maxval) {
2727                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2728                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2729                     "soft_state_init_toomanypd_fail");
2730                 return (DDI_FAILURE);
2731         }
2732         hca_attr->hca_max_pd = (uint_t)val;
2733 
2734         /* Determine max number of Address Handles (NOT IN ARBEL or HERMON) */
2735         hca_attr->hca_max_ah = 0;
2736 
2737         /* No RDDs or EECs (since Reliable Datagram is not supported) */
2738         hca_attr->hca_max_rdd = 0;
2739         hca_attr->hca_max_eec = 0;
2740 
2741         /* Initialize lock for reserved UAR page access */
2742         mutex_init(&state->hs_uar_lock, NULL, MUTEX_DRIVER,
2743             DDI_INTR_PRI(state->hs_intrmsi_pri));
2744 
2745         /* Initialize the flash fields */
2746         state->hs_fw_flashstarted = 0;
2747         mutex_init(&state->hs_fw_flashlock, NULL, MUTEX_DRIVER,
2748             DDI_INTR_PRI(state->hs_intrmsi_pri));
2749 
2750         /* Initialize the lock for the info ioctl */
2751         mutex_init(&state->hs_info_lock, NULL, MUTEX_DRIVER,
2752             DDI_INTR_PRI(state->hs_intrmsi_pri));
2753 
2754         /* Initialize the AVL tree for QP number support */
2755         hermon_qpn_avl_init(state);
2756 
2757         /* Initialize the cq_sched info structure */
2758         status = hermon_cq_sched_init(state);
2759         if (status != DDI_SUCCESS) {
2760                 hermon_qpn_avl_fini(state);
2761                 mutex_destroy(&state->hs_info_lock);
2762                 mutex_destroy(&state->hs_fw_flashlock);
2763                 mutex_destroy(&state->hs_uar_lock);
2764                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2765                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2766                     "soft_state_init_cqsched_init_fail");
2767                 return (DDI_FAILURE);
2768         }
2769 
2770         /* Initialize the fcoib info structure */
2771         status = hermon_fcoib_init(state);
2772         if (status != DDI_SUCCESS) {
2773                 hermon_cq_sched_fini(state);
2774                 hermon_qpn_avl_fini(state);
2775                 mutex_destroy(&state->hs_info_lock);
2776                 mutex_destroy(&state->hs_fw_flashlock);
2777                 mutex_destroy(&state->hs_uar_lock);
2778                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2779                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2780                     "soft_state_init_fcoibinit_fail");
2781                 return (DDI_FAILURE);
2782         }
2783 
2784         /* Initialize the kstat info structure */
2785         status = hermon_kstat_init(state);
2786         if (status != DDI_SUCCESS) {
2787                 hermon_fcoib_fini(state);
2788                 hermon_cq_sched_fini(state);
2789                 hermon_qpn_avl_fini(state);
2790                 mutex_destroy(&state->hs_info_lock);
2791                 mutex_destroy(&state->hs_fw_flashlock);
2792                 mutex_destroy(&state->hs_uar_lock);
2793                 kmem_free(hca_attr, sizeof (ibt_hca_attr_t));
2794                 HERMON_ATTACH_MSG(state->hs_attach_buf,
2795                     "soft_state_init_kstatinit_fail");
2796                 return (DDI_FAILURE);
2797         }
2798 
2799         return (DDI_SUCCESS);
2800 }
2801 
2802 
2803 /*
2804  * hermon_soft_state_fini()
2805  *    Context: Called only from detach() path context
2806  */
2807 static void
2808 hermon_soft_state_fini(hermon_state_t *state)
2809 {
2810 
2811         /* Teardown the kstat info */
2812         hermon_kstat_fini(state);
2813 
2814         /* Teardown the fcoib info */
2815         hermon_fcoib_fini(state);
2816 
2817         /* Teardown the cq_sched info */
2818         hermon_cq_sched_fini(state);
2819 
2820         /* Teardown the AVL tree for QP number support */
2821         hermon_qpn_avl_fini(state);
2822 
2823         /* Free up info ioctl mutex */
2824         mutex_destroy(&state->hs_info_lock);
2825 
2826         /* Free up flash mutex */
2827         mutex_destroy(&state->hs_fw_flashlock);
2828 
2829         /* Free up the UAR page access mutex */
2830         mutex_destroy(&state->hs_uar_lock);
2831 
2832         /* Free up the hca_attr struct */
2833         kmem_free(state->hs_ibtfinfo.hca_attr, sizeof (ibt_hca_attr_t));
2834 
2835 }
2836 
2837 /*
2838  * hermon_icm_config_setup()
2839  *    Context: Only called from attach() path context
2840  */
2841 static int
2842 hermon_icm_config_setup(hermon_state_t *state,
2843     hermon_hw_initqueryhca_t *inithca)
2844 {
2845         hermon_hw_querydevlim_t *devlim;
2846         hermon_cfg_profile_t    *cfg;
2847         hermon_icm_table_t      *icm_p[HERMON_NUM_ICM_RESOURCES];
2848         hermon_icm_table_t      *icm;
2849         hermon_icm_table_t      *tmp;
2850         uint64_t                icm_addr;
2851         uint64_t                icm_size;
2852         int                     status, i, j;
2853 
2854 
2855         /* Bring in local devlims, cfg_profile and hs_icm table list */
2856         devlim = &state->hs_devlim;
2857         cfg = state->hs_cfg_profile;
2858         icm = state->hs_icm;
2859 
2860         /*
2861          * Assign each ICM table's entry size from data in the devlims,
2862          * except for RDB and MCG sizes, which are not returned in devlims
2863          * but do have a fixed size, and the UAR context entry size, which
2864          * we determine. For this, we use the "cp_num_pgs_per_uce" value
2865          * from our hs_cfg_profile.
2866          */
2867         icm[HERMON_CMPT].object_size    = devlim->cmpt_entry_sz;
2868         icm[HERMON_CMPT_QPC].object_size        = devlim->cmpt_entry_sz;
2869         icm[HERMON_CMPT_SRQC].object_size       = devlim->cmpt_entry_sz;
2870         icm[HERMON_CMPT_CQC].object_size        = devlim->cmpt_entry_sz;
2871         icm[HERMON_CMPT_EQC].object_size        = devlim->cmpt_entry_sz;
2872         icm[HERMON_MTT].object_size     = devlim->mtt_entry_sz;
2873         icm[HERMON_DMPT].object_size    = devlim->dmpt_entry_sz;
2874         icm[HERMON_QPC].object_size     = devlim->qpc_entry_sz;
2875         icm[HERMON_CQC].object_size     = devlim->cqc_entry_sz;
2876         icm[HERMON_SRQC].object_size    = devlim->srq_entry_sz;
2877         icm[HERMON_EQC].object_size     = devlim->eqc_entry_sz;
2878         icm[HERMON_RDB].object_size     = devlim->rdmardc_entry_sz *
2879             cfg->cp_hca_max_rdma_in_qp;
2880         icm[HERMON_MCG].object_size     = HERMON_MCGMEM_SZ(state);
2881         icm[HERMON_ALTC].object_size    = devlim->altc_entry_sz;
2882         icm[HERMON_AUXC].object_size    = devlim->aux_entry_sz;
2883 
2884         /* Assign each ICM table's log2 number of entries */
2885         icm[HERMON_CMPT].log_num_entries = cfg->cp_log_num_cmpt;
2886         icm[HERMON_CMPT_QPC].log_num_entries = cfg->cp_log_num_qp;
2887         icm[HERMON_CMPT_SRQC].log_num_entries = cfg->cp_log_num_srq;
2888         icm[HERMON_CMPT_CQC].log_num_entries = cfg->cp_log_num_cq;
2889         icm[HERMON_CMPT_EQC].log_num_entries = HERMON_NUM_EQ_SHIFT;
2890         icm[HERMON_MTT].log_num_entries = cfg->cp_log_num_mtt;
2891         icm[HERMON_DMPT].log_num_entries = cfg->cp_log_num_dmpt;
2892         icm[HERMON_QPC].log_num_entries = cfg->cp_log_num_qp;
2893         icm[HERMON_SRQC].log_num_entries = cfg->cp_log_num_srq;
2894         icm[HERMON_CQC].log_num_entries = cfg->cp_log_num_cq;
2895         icm[HERMON_EQC].log_num_entries = HERMON_NUM_EQ_SHIFT;
2896         icm[HERMON_RDB].log_num_entries = cfg->cp_log_num_qp;
2897         icm[HERMON_MCG].log_num_entries = cfg->cp_log_num_mcg;
2898         icm[HERMON_ALTC].log_num_entries = cfg->cp_log_num_qp;
2899         icm[HERMON_AUXC].log_num_entries = cfg->cp_log_num_qp;
2900 
2901         /* Initialize the ICM tables */
2902         hermon_icm_tables_init(state);
2903 
2904         /*
2905          * ICM tables must be aligned on their size in the ICM address
2906          * space. So, here we order the tables from largest total table
2907          * size to the smallest. All tables are a power of 2 in size, so
2908          * this will ensure that all tables are aligned on their own size
2909          * without wasting space in the ICM.
2910          *
2911          * In order to easily set the ICM addresses without needing to
2912          * worry about the ordering of our table indices as relates to
2913          * the hermon_rsrc_type_t enum, we will use a list of pointers
2914          * representing the tables for the sort, then assign ICM addresses
2915          * below using it.
2916          */
2917         for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) {
2918                 icm_p[i] = &icm[i];
2919         }
2920         for (i = HERMON_NUM_ICM_RESOURCES; i > 0; i--) {
2921                 switch (i) {
2922                 case HERMON_CMPT_QPC:
2923                 case HERMON_CMPT_SRQC:
2924                 case HERMON_CMPT_CQC:
2925                 case HERMON_CMPT_EQC:
2926                         continue;
2927                 }
2928                 for (j = 1; j < i; j++) {
2929                         if (icm_p[j]->table_size > icm_p[j - 1]->table_size) {
2930                                 tmp             = icm_p[j];
2931                                 icm_p[j]        = icm_p[j - 1];
2932                                 icm_p[j - 1]    = tmp;
2933                         }
2934                 }
2935         }
2936 
2937         /* Initialize the ICM address and ICM size */
2938         icm_addr = icm_size = 0;
2939 
2940         /*
2941          * Set the ICM base address of each table, using our sorted
2942          * list of pointers from above.
2943          */
2944         for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) {
2945                 j = icm_p[i]->icm_type;
2946                 switch (j) {
2947                 case HERMON_CMPT_QPC:
2948                 case HERMON_CMPT_SRQC:
2949                 case HERMON_CMPT_CQC:
2950                 case HERMON_CMPT_EQC:
2951                         continue;
2952                 }
2953                 if (icm[j].table_size) {
2954                         /*
2955                          * Set the ICM base address in the table, save the
2956                          * ICM offset in the rsrc pool and increment the
2957                          * total ICM allocation.
2958                          */
2959                         icm[j].icm_baseaddr = icm_addr;
2960                         if (hermon_verbose) {
2961                                 IBTF_DPRINTF_L2("ICMADDR", "rsrc %x @ %p"
2962                                     " size %llx", j, icm[j].icm_baseaddr,
2963                                     icm[j].table_size);
2964                         }
2965                         icm_size += icm[j].table_size;
2966                 }
2967 
2968                 /* Verify that we don't exceed maximum ICM size */
2969                 if (icm_size > devlim->max_icm_size) {
2970                         /* free the ICM table memory resources */
2971                         hermon_icm_tables_fini(state);
2972                         cmn_err(CE_WARN, "ICM configuration exceeds maximum "
2973                             "configuration: max (0x%lx) requested (0x%lx)\n",
2974                             (ulong_t)devlim->max_icm_size, (ulong_t)icm_size);
2975                         HERMON_ATTACH_MSG(state->hs_attach_buf,
2976                             "icm_config_toobig_fail");
2977                         return (DDI_FAILURE);
2978                 }
2979 
2980                 /* assign address to the 4 pieces of the CMPT */
2981                 if (j == HERMON_CMPT) {
2982                         uint64_t cmpt_size = icm[j].table_size >> 2;
2983 #define init_cmpt_icm_baseaddr(rsrc, indx)                              \
2984         icm[rsrc].icm_baseaddr  = icm_addr + (indx * cmpt_size);
2985                         init_cmpt_icm_baseaddr(HERMON_CMPT_QPC, 0);
2986                         init_cmpt_icm_baseaddr(HERMON_CMPT_SRQC, 1);
2987                         init_cmpt_icm_baseaddr(HERMON_CMPT_CQC, 2);
2988                         init_cmpt_icm_baseaddr(HERMON_CMPT_EQC, 3);
2989                 }
2990 
2991                 /* Increment the ICM address for the next table */
2992                 icm_addr += icm[j].table_size;
2993         }
2994 
2995         /* Populate the structure for the INIT_HCA command */
2996         hermon_inithca_set(state, inithca);
2997 
2998         /*
2999          * Prior to invoking INIT_HCA, we must have ICM memory in place
3000          * for the reserved objects in each table. We will allocate and map
3001          * this initial ICM memory here. Note that given the assignment
3002          * of span_size above, tables that are smaller or equal in total
3003          * size to the default span_size will be mapped in full.
3004          */
3005         status = hermon_icm_dma_init(state);
3006         if (status != DDI_SUCCESS) {
3007                 /* free the ICM table memory resources */
3008                 hermon_icm_tables_fini(state);
3009                 HERMON_WARNING(state, "Failed to allocate initial ICM");
3010                 HERMON_ATTACH_MSG(state->hs_attach_buf,
3011                     "icm_config_dma_init_fail");
3012                 return (DDI_FAILURE);
3013         }
3014 
3015         return (DDI_SUCCESS);
3016 }
3017 
3018 /*
3019  * hermon_inithca_set()
3020  *    Context: Only called from attach() path context
3021  */
3022 static void
3023 hermon_inithca_set(hermon_state_t *state, hermon_hw_initqueryhca_t *inithca)
3024 {
3025         hermon_cfg_profile_t    *cfg;
3026         hermon_icm_table_t      *icm;
3027         int                     i;
3028 
3029 
3030         /* Populate the INIT_HCA structure */
3031         icm = state->hs_icm;
3032         cfg = state->hs_cfg_profile;
3033 
3034         /* set version */
3035         inithca->version = 0x02;     /* PRM 0.36 */
3036         /* set cacheline - log2 in 16-byte chunks */
3037         inithca->log2_cacheline = 0x2;       /* optimized for 64 byte cache */
3038 
3039         /* we need to update the inithca info with thie UAR info too */
3040         inithca->uar.log_max_uars = highbit(cfg->cp_log_num_uar);
3041         inithca->uar.uar_pg_sz = PAGESHIFT - HERMON_PAGESHIFT;
3042 
3043         /* Set endianess */
3044 #ifdef  _LITTLE_ENDIAN
3045         inithca->big_endian  = 0;
3046 #else
3047         inithca->big_endian  = 1;
3048 #endif
3049 
3050         /* Port Checking is on by default */
3051         inithca->udav_port_chk       = HERMON_UDAV_PORTCHK_ENABLED;
3052 
3053         /* Enable IPoIB checksum */
3054         if (state->hs_devlim.ipoib_cksm)
3055                 inithca->chsum_en = 1;
3056 
3057         /* Set each ICM table's attributes */
3058         for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) {
3059                 switch (icm[i].icm_type) {
3060                 case HERMON_CMPT:
3061                         inithca->tpt.cmpt_baseaddr = icm[i].icm_baseaddr;
3062                         break;
3063 
3064                 case HERMON_MTT:
3065                         inithca->tpt.mtt_baseaddr = icm[i].icm_baseaddr;
3066                         break;
3067 
3068                 case HERMON_DMPT:
3069                         inithca->tpt.dmpt_baseaddr = icm[i].icm_baseaddr;
3070                         inithca->tpt.log_dmpt_sz   = icm[i].log_num_entries;
3071                         inithca->tpt.pgfault_rnr_to = 0; /* just in case */
3072                         break;
3073 
3074                 case HERMON_QPC:
3075                         inithca->context.log_num_qp = icm[i].log_num_entries;
3076                         inithca->context.qpc_baseaddr_h =
3077                             icm[i].icm_baseaddr >> 32;
3078                         inithca->context.qpc_baseaddr_l =
3079                             (icm[i].icm_baseaddr & 0xFFFFFFFF) >> 5;
3080                         break;
3081 
3082                 case HERMON_CQC:
3083                         inithca->context.log_num_cq = icm[i].log_num_entries;
3084                         inithca->context.cqc_baseaddr_h =
3085                             icm[i].icm_baseaddr >> 32;
3086                         inithca->context.cqc_baseaddr_l =
3087                             (icm[i].icm_baseaddr & 0xFFFFFFFF) >> 5;
3088                         break;
3089 
3090                 case HERMON_SRQC:
3091                         inithca->context.log_num_srq = icm[i].log_num_entries;
3092                         inithca->context.srqc_baseaddr_h =
3093                             icm[i].icm_baseaddr >> 32;
3094                         inithca->context.srqc_baseaddr_l =
3095                             (icm[i].icm_baseaddr & 0xFFFFFFFF) >> 5;
3096                         break;
3097 
3098                 case HERMON_EQC:
3099                         inithca->context.log_num_eq = icm[i].log_num_entries;
3100                         inithca->context.eqc_baseaddr_h =
3101                             icm[i].icm_baseaddr >> 32;
3102                         inithca->context.eqc_baseaddr_l =
3103                             (icm[i].icm_baseaddr & 0xFFFFFFFF) >> 5;
3104                         break;
3105 
3106                 case HERMON_RDB:
3107                         inithca->context.rdmardc_baseaddr_h =
3108                             icm[i].icm_baseaddr >> 32;
3109                         inithca->context.rdmardc_baseaddr_l =
3110                             (icm[i].icm_baseaddr & 0xFFFFFFFF) >> 5;
3111                         inithca->context.log_num_rdmardc =
3112                             cfg->cp_log_num_rdb - cfg->cp_log_num_qp;
3113                         break;
3114 
3115                 case HERMON_MCG:
3116                         inithca->multi.mc_baseaddr    = icm[i].icm_baseaddr;
3117                         inithca->multi.log_mc_tbl_sz  = icm[i].log_num_entries;
3118                         inithca->multi.log_mc_tbl_ent =
3119                             highbit(HERMON_MCGMEM_SZ(state)) - 1;
3120                         inithca->multi.log_mc_tbl_hash_sz =
3121                             cfg->cp_log_num_mcg_hash;
3122                         inithca->multi.mc_hash_fn = HERMON_MCG_DEFAULT_HASH_FN;
3123                         break;
3124 
3125                 case HERMON_ALTC:
3126                         inithca->context.altc_baseaddr = icm[i].icm_baseaddr;
3127                         break;
3128 
3129                 case HERMON_AUXC:
3130                         inithca->context.auxc_baseaddr = icm[i].icm_baseaddr;
3131                         break;
3132 
3133                 default:
3134                         break;
3135 
3136                 }
3137         }
3138 
3139 }
3140 
3141 /*
3142  * hermon_icm_tables_init()
3143  *    Context: Only called from attach() path context
3144  *
3145  * Dynamic ICM breaks the various ICM tables into "span_size" chunks
3146  * to enable allocation of backing memory on demand.  Arbel used a
3147  * fixed size ARBEL_ICM_SPAN_SIZE (initially was 512KB) as the
3148  * span_size for all ICM chunks.  Hermon has other considerations,
3149  * so the span_size used differs from Arbel.
3150  *
3151  * The basic considerations for why Hermon differs are:
3152  *
3153  *      1) ICM memory is in units of HERMON pages.
3154  *
3155  *      2) The AUXC table is approximately 1 byte per QP.
3156  *
3157  *      3) ICM memory for AUXC, ALTC, and RDB is allocated when
3158  *      the ICM memory for the corresponding QPC is allocated.
3159  *
3160  *      4) ICM memory for the CMPT corresponding to the various primary
3161  *      resources (QPC, SRQC, CQC, and EQC) is allocated when the ICM
3162  *      memory for the primary resource is allocated.
3163  *
3164  * One HERMON page (4KB) would typically map 4K QPs worth of AUXC.
3165  * So, the minimum chunk for the various QPC related ICM memory should
3166  * all be allocated to support the 4K QPs.  Currently, this means the
3167  * amount of memory for the various QP chunks is:
3168  *
3169  *      QPC     256*4K bytes
3170  *      RDB     128*4K bytes
3171  *      CMPT     64*4K bytes
3172  *      ALTC     64*4K bytes
3173  *      AUXC      1*4K bytes
3174  *
3175  * The span_size chosen for the QP resource is 4KB of AUXC entries,
3176  * or 1 HERMON_PAGESIZE worth, which is the minimum ICM mapping size.
3177  *
3178  * Other ICM resources can have their span_size be more arbitrary.
3179  * This is 4K (HERMON_ICM_SPAN), except for MTTs because they are tiny.
3180  */
3181 
3182 /* macro to make the code below cleaner */
3183 #define init_dependent(rsrc, dep)                               \
3184         icm[dep].span           = icm[rsrc].span;               \
3185         icm[dep].num_spans      = icm[rsrc].num_spans;          \
3186         icm[dep].split_shift    = icm[rsrc].split_shift;        \
3187         icm[dep].span_mask      = icm[rsrc].span_mask;          \
3188         icm[dep].span_shift     = icm[rsrc].span_shift;         \
3189         icm[dep].rsrc_mask      = icm[rsrc].rsrc_mask;          \
3190         if (hermon_verbose) {                                   \
3191                 IBTF_DPRINTF_L2("hermon", "tables_init: "       \
3192                     "rsrc (0x%x) size (0x%lx) span (0x%x) "     \
3193                     "num_spans (0x%x)", dep, icm[dep].table_size, \
3194                     icm[dep].span, icm[dep].num_spans);         \
3195                 IBTF_DPRINTF_L2("hermon", "tables_init: "       \
3196                     "span_shift (0x%x) split_shift (0x%x)",     \
3197                     icm[dep].span_shift, icm[dep].split_shift); \
3198                 IBTF_DPRINTF_L2("hermon", "tables_init: "       \
3199                     "span_mask (0x%x)  rsrc_mask   (0x%x)",     \
3200                     icm[dep].span_mask, icm[dep].rsrc_mask);    \
3201         }
3202 
3203 static void
3204 hermon_icm_tables_init(hermon_state_t *state)
3205 {
3206         hermon_icm_table_t      *icm;
3207         int                     i, k;
3208         uint32_t                per_split;
3209 
3210 
3211         icm = state->hs_icm;
3212 
3213         for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) {
3214                 icm[i].icm_type         = i;
3215                 icm[i].num_entries      = 1 << icm[i].log_num_entries;
3216                 icm[i].log_object_size  = highbit(icm[i].object_size) - 1;
3217                 icm[i].table_size       = icm[i].num_entries <<
3218                     icm[i].log_object_size;
3219 
3220                 /* deal with "dependent" resource types */
3221                 switch (i) {
3222                 case HERMON_AUXC:
3223 #ifdef HERMON_FW_WORKAROUND
3224                         icm[i].table_size = 0x80000000ull;
3225                         /* FALLTHROUGH */
3226 #endif
3227                 case HERMON_CMPT_QPC:
3228                 case HERMON_RDB:
3229                 case HERMON_ALTC:
3230                         init_dependent(HERMON_QPC, i);
3231                         continue;
3232                 case HERMON_CMPT_SRQC:
3233                         init_dependent(HERMON_SRQC, i);
3234                         continue;
3235                 case HERMON_CMPT_CQC:
3236                         init_dependent(HERMON_CQC, i);
3237                         continue;
3238                 case HERMON_CMPT_EQC:
3239                         init_dependent(HERMON_EQC, i);
3240                         continue;
3241                 }
3242 
3243                 icm[i].span = HERMON_ICM_SPAN;  /* default #rsrc's in 1 span */
3244                 if (i == HERMON_MTT) /* Alloc enough MTTs to map 256MB */
3245                         icm[i].span = HERMON_ICM_SPAN * 16;
3246                 icm[i].num_spans = icm[i].num_entries / icm[i].span;
3247                 if (icm[i].num_spans == 0) {
3248                         icm[i].span = icm[i].num_entries;
3249                         per_split = 1;
3250                         icm[i].num_spans = icm[i].num_entries / icm[i].span;
3251                 } else {
3252                         per_split = icm[i].num_spans / HERMON_ICM_SPLIT;
3253                         if (per_split == 0) {
3254                                 per_split = 1;
3255                         }
3256                 }
3257                 if (hermon_verbose)
3258                         IBTF_DPRINTF_L2("ICM", "rsrc %x  span %x  num_spans %x",
3259                             i, icm[i].span, icm[i].num_spans);
3260 
3261                 /*
3262                  * Ensure a minimum table size of an ICM page, and a
3263                  * maximum span size of the ICM table size.  This ensures
3264                  * that we don't have less than an ICM page to map, which is
3265                  * impossible, and that we will map an entire table at
3266                  * once if it's total size is less than the span size.
3267                  */
3268                 icm[i].table_size = max(icm[i].table_size, HERMON_PAGESIZE);
3269 
3270                 icm[i].span_shift = 0;
3271                 for (k = icm[i].span; k != 1; k >>= 1)
3272                         icm[i].span_shift++;
3273                 icm[i].split_shift = icm[i].span_shift;
3274                 for (k = per_split; k != 1; k >>= 1)
3275                         icm[i].split_shift++;
3276                 icm[i].span_mask = (1 << icm[i].split_shift) -
3277                     (1 << icm[i].span_shift);
3278                 icm[i].rsrc_mask = (1 << icm[i].span_shift) - 1;
3279 
3280 
3281                 /* Initialize the table lock */
3282                 mutex_init(&icm[i].icm_table_lock, NULL, MUTEX_DRIVER,
3283                     DDI_INTR_PRI(state->hs_intrmsi_pri));
3284                 cv_init(&icm[i].icm_table_cv, NULL, CV_DRIVER, NULL);
3285 
3286                 if (hermon_verbose) {
3287                         IBTF_DPRINTF_L2("hermon", "tables_init: "
3288                             "rsrc (0x%x) size (0x%lx)", i, icm[i].table_size);
3289                         IBTF_DPRINTF_L2("hermon", "tables_init: "
3290                             "span (0x%x) num_spans (0x%x)",
3291                             icm[i].span, icm[i].num_spans);
3292                         IBTF_DPRINTF_L2("hermon", "tables_init: "
3293                             "span_shift (0x%x) split_shift (0x%x)",
3294                             icm[i].span_shift, icm[i].split_shift);
3295                         IBTF_DPRINTF_L2("hermon", "tables_init: "
3296                             "span_mask (0x%x)  rsrc_mask   (0x%x)",
3297                             icm[i].span_mask, icm[i].rsrc_mask);
3298                 }
3299         }
3300 
3301 }
3302 
3303 /*
3304  * hermon_icm_tables_fini()
3305  *    Context: Only called from attach() path context
3306  *
3307  * Clean up all icm_tables.  Free the bitmap and dma_info arrays.
3308  */
3309 static void
3310 hermon_icm_tables_fini(hermon_state_t *state)
3311 {
3312         hermon_icm_table_t      *icm;
3313         int                     nspans;
3314         int                     i, j;
3315 
3316 
3317         icm = state->hs_icm;
3318 
3319         for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) {
3320 
3321                 mutex_enter(&icm[i].icm_table_lock);
3322                 nspans = icm[i].num_spans;
3323 
3324                 for (j = 0; j < HERMON_ICM_SPLIT; j++) {
3325                         if (icm[i].icm_dma[j])
3326                                 /* Free the ICM DMA slots */
3327                                 kmem_free(icm[i].icm_dma[j],
3328                                     nspans * sizeof (hermon_dma_info_t));
3329 
3330                         if (icm[i].icm_bitmap[j])
3331                                 /* Free the table bitmap */
3332                                 kmem_free(icm[i].icm_bitmap[j],
3333                                     (nspans + 7) / 8);
3334                 }
3335                 /* Destroy the table lock */
3336                 cv_destroy(&icm[i].icm_table_cv);
3337                 mutex_exit(&icm[i].icm_table_lock);
3338                 mutex_destroy(&icm[i].icm_table_lock);
3339         }
3340 
3341 }
3342 
3343 /*
3344  * hermon_icm_dma_init()
3345  *    Context: Only called from attach() path context
3346  */
3347 static int
3348 hermon_icm_dma_init(hermon_state_t *state)
3349 {
3350         hermon_icm_table_t      *icm;
3351         hermon_rsrc_type_t      type;
3352         int                     status;
3353 
3354 
3355         /*
3356          * This routine will allocate initial ICM DMA resources for ICM
3357          * tables that have reserved ICM objects. This is the only routine
3358          * where we should have to allocate ICM outside of hermon_rsrc_alloc().
3359          * We need to allocate ICM here explicitly, rather than in
3360          * hermon_rsrc_alloc(), because we've not yet completed the resource
3361          * pool initialization. When the resource pools are initialized
3362          * (in hermon_rsrc_init_phase2(), see hermon_rsrc.c for more
3363          * information), resource preallocations will be invoked to match
3364          * the ICM allocations seen here. We will then be able to use the
3365          * normal allocation path.  Note we don't need to set a refcnt on
3366          * these initial allocations because that will be done in the calls
3367          * to hermon_rsrc_alloc() from hermon_hw_entries_init() for the
3368          * "prealloc" objects (see hermon_rsrc.c for more information).
3369          */
3370         for (type = 0; type < HERMON_NUM_ICM_RESOURCES; type++) {
3371 
3372                 /* ICM for these is allocated within hermon_icm_alloc() */
3373                 switch (type) {
3374                 case HERMON_CMPT:
3375                 case HERMON_CMPT_QPC:
3376                 case HERMON_CMPT_SRQC:
3377                 case HERMON_CMPT_CQC:
3378                 case HERMON_CMPT_EQC:
3379                 case HERMON_AUXC:
3380                 case HERMON_ALTC:
3381                 case HERMON_RDB:
3382                         continue;
3383                 }
3384 
3385                 icm = &state->hs_icm[type];
3386 
3387                 mutex_enter(&icm->icm_table_lock);
3388                 status = hermon_icm_alloc(state, type, 0, 0);
3389                 mutex_exit(&icm->icm_table_lock);
3390                 if (status != DDI_SUCCESS) {
3391                         while (type--) {
3392                                 icm = &state->hs_icm[type];
3393                                 mutex_enter(&icm->icm_table_lock);
3394                                 hermon_icm_free(state, type, 0, 0);
3395                                 mutex_exit(&icm->icm_table_lock);
3396                         }
3397                         return (DDI_FAILURE);
3398                 }
3399 
3400                 if (hermon_verbose) {
3401                         IBTF_DPRINTF_L2("hermon", "hermon_icm_dma_init: "
3402                             "table (0x%x) index (0x%x) allocated", type, 0);
3403                 }
3404         }
3405 
3406         return (DDI_SUCCESS);
3407 }
3408 
3409 /*
3410  * hermon_icm_dma_fini()
3411  *    Context: Only called from attach() path context
3412  *
3413  * ICM has been completely unmapped.  We just free the memory here.
3414  */
3415 static void
3416 hermon_icm_dma_fini(hermon_state_t *state)
3417 {
3418         hermon_icm_table_t      *icm;
3419         hermon_dma_info_t       *dma_info;
3420         hermon_rsrc_type_t      type;
3421         int                     index1, index2;
3422 
3423 
3424         for (type = 0; type < HERMON_NUM_ICM_RESOURCES; type++) {
3425                 icm = &state->hs_icm[type];
3426                 for (index1 = 0; index1 < HERMON_ICM_SPLIT; index1++) {
3427                         dma_info = icm->icm_dma[index1];
3428                         if (dma_info == NULL)
3429                                 continue;
3430                         for (index2 = 0; index2 < icm->num_spans; index2++) {
3431                                 if (dma_info[index2].dma_hdl)
3432                                         hermon_dma_free(&dma_info[index2]);
3433                                 dma_info[index2].dma_hdl = NULL;
3434                         }
3435                 }
3436         }
3437 
3438 }
3439 
3440 /*
3441  * hermon_hca_port_init()
3442  *    Context: Only called from attach() path context
3443  */
3444 static int
3445 hermon_hca_port_init(hermon_state_t *state)
3446 {
3447         hermon_hw_set_port_t    *portinits, *initport;
3448         hermon_cfg_profile_t    *cfgprof;
3449         uint_t                  num_ports;
3450         int                     i = 0, status;
3451         uint64_t                maxval, val;
3452         uint64_t                sysimgguid, nodeguid, portguid;
3453 
3454 
3455         cfgprof = state->hs_cfg_profile;
3456 
3457         /* Get number of HCA ports */
3458         num_ports = cfgprof->cp_num_ports;
3459 
3460         /* Allocate space for Hermon set port  struct(s) */
3461         portinits = (hermon_hw_set_port_t *)kmem_zalloc(num_ports *
3462             sizeof (hermon_hw_set_port_t), KM_SLEEP);
3463 
3464 
3465 
3466         /* Post commands to initialize each Hermon HCA port */
3467         /*
3468          * In Hermon, the process is different than in previous HCAs.
3469          * Here, you have to:
3470          *      QUERY_PORT - to get basic information from the HCA
3471          *      set the fields accordingly
3472          *      SET_PORT - to change/set everything as desired
3473          *      INIT_PORT - to bring the port up
3474          *
3475          * Needs to be done for each port in turn
3476          */
3477 
3478         for (i = 0; i < num_ports; i++) {
3479                 bzero(&state->hs_queryport, sizeof (hermon_hw_query_port_t));
3480                 status = hermon_cmn_query_cmd_post(state, QUERY_PORT, 0,
3481                     (i + 1), &state->hs_queryport,
3482                     sizeof (hermon_hw_query_port_t), HERMON_CMD_NOSLEEP_SPIN);
3483                 if (status != HERMON_CMD_SUCCESS) {
3484                         cmn_err(CE_CONT, "Hermon: QUERY_PORT (port %02d) "
3485                             "command failed: %08x\n", i + 1, status);
3486                         goto init_ports_fail;
3487                 }
3488                 initport = &portinits[i];
3489                 state->hs_initport = &portinits[i];
3490 
3491                 bzero(initport, sizeof (hermon_hw_query_port_t));
3492 
3493                 /*
3494                  * Determine whether we need to override the firmware's
3495                  * default SystemImageGUID setting.
3496                  */
3497                 sysimgguid = cfgprof->cp_sysimgguid;
3498                 if (sysimgguid != 0) {
3499                         initport->sig                = 1;
3500                         initport->sys_img_guid       = sysimgguid;
3501                 }
3502 
3503                 /*
3504                  * Determine whether we need to override the firmware's
3505                  * default NodeGUID setting.
3506                  */
3507                 nodeguid = cfgprof->cp_nodeguid;
3508                 if (nodeguid != 0) {
3509                         initport->ng         = 1;
3510                         initport->node_guid  = nodeguid;
3511                 }
3512 
3513                 /*
3514                  * Determine whether we need to override the firmware's
3515                  * default PortGUID setting.
3516                  */
3517                 portguid = cfgprof->cp_portguid[i];
3518                 if (portguid != 0) {
3519                         initport->g0         = 1;
3520                         initport->guid0              = portguid;
3521                 }
3522 
3523                 /* Validate max MTU size */
3524                 maxval  = state->hs_queryport.ib_mtu;
3525                 val     = cfgprof->cp_max_mtu;
3526                 if (val > maxval) {
3527                         goto init_ports_fail;
3528                 }
3529 
3530                 /* Set mtu_cap to 4096 bytes */
3531                 initport->mmc = 1;   /* set the change bit */
3532                 initport->mtu_cap = 5;       /* for 4096 bytes */
3533 
3534                 /* Validate the max port width */
3535                 maxval  = state->hs_queryport.ib_port_wid;
3536                 val     = cfgprof->cp_max_port_width;
3537                 if (val > maxval) {
3538                         goto init_ports_fail;
3539                 }
3540 
3541                 /* Validate max VL cap size */
3542                 maxval  = state->hs_queryport.max_vl;
3543                 val     = cfgprof->cp_max_vlcap;
3544                 if (val > maxval) {
3545                         goto init_ports_fail;
3546                 }
3547 
3548                 /* Since we're doing mtu_cap, cut vl_cap down */
3549                 initport->mvc = 1;   /* set this change bit */
3550                 initport->vl_cap = 3;        /* 3 means vl0-vl3, 4 total */
3551 
3552                 /* Validate max GID table size */
3553                 maxval  = ((uint64_t)1 << state->hs_queryport.log_max_gid);
3554                 val     = ((uint64_t)1 << cfgprof->cp_log_max_gidtbl);
3555                 if (val > maxval) {
3556                         goto init_ports_fail;
3557                 }
3558                 initport->max_gid = (uint16_t)val;
3559                 initport->mg = 1;
3560 
3561                 /* Validate max PKey table size */
3562                 maxval  = ((uint64_t)1 << state->hs_queryport.log_max_pkey);
3563                 val     = ((uint64_t)1 << cfgprof->cp_log_max_pkeytbl);
3564                 if (val > maxval) {
3565                         goto init_ports_fail;
3566                 }
3567                 initport->max_pkey = (uint16_t)val;
3568                 initport->mp = 1;
3569                 /*
3570                  * Post the SET_PORT cmd to Hermon firmware. This sets
3571                  * the parameters of the port.
3572                  */
3573                 status = hermon_set_port_cmd_post(state, initport, i + 1,
3574                     HERMON_CMD_NOSLEEP_SPIN);
3575                 if (status != HERMON_CMD_SUCCESS) {
3576                         cmn_err(CE_CONT, "Hermon: SET_PORT (port %02d) command "
3577                             "failed: %08x\n", i + 1, status);
3578                         goto init_ports_fail;
3579                 }
3580                 /* issue another SET_PORT cmd - performance fix/workaround */
3581                 /* XXX - need to discuss with Mellanox */
3582                 bzero(initport, sizeof (hermon_hw_query_port_t));
3583                 initport->cap_mask = 0x02500868;
3584                 status = hermon_set_port_cmd_post(state, initport, i + 1,
3585                     HERMON_CMD_NOSLEEP_SPIN);
3586                 if (status != HERMON_CMD_SUCCESS) {
3587                         cmn_err(CE_CONT, "Hermon: SET_PORT (port %02d) command "
3588                             "failed: %08x\n", i + 1, status);
3589                         goto init_ports_fail;
3590                 }
3591         }
3592 
3593         /*
3594          * Finally, do the INIT_PORT for each port in turn
3595          * When this command completes, the corresponding Hermon port
3596          * will be physically "Up" and initialized.
3597          */
3598         for (i = 0; i < num_ports; i++) {
3599                 status = hermon_init_port_cmd_post(state, i + 1,
3600                     HERMON_CMD_NOSLEEP_SPIN);
3601                 if (status != HERMON_CMD_SUCCESS) {
3602                         cmn_err(CE_CONT, "Hermon: INIT_PORT (port %02d) "
3603                             "comman failed: %08x\n", i + 1, status);
3604                         goto init_ports_fail;
3605                 }
3606         }
3607 
3608         /* Free up the memory for Hermon port init struct(s), return success */
3609         kmem_free(portinits, num_ports * sizeof (hermon_hw_set_port_t));
3610         return (DDI_SUCCESS);
3611 
3612 init_ports_fail:
3613         /*
3614          * Free up the memory for Hermon port init struct(s), shutdown any
3615          * successfully initialized ports, and return failure
3616          */
3617         kmem_free(portinits, num_ports * sizeof (hermon_hw_set_port_t));
3618         (void) hermon_hca_ports_shutdown(state, i);
3619 
3620         return (DDI_FAILURE);
3621 }
3622 
3623 
3624 /*
3625  * hermon_hca_ports_shutdown()
3626  *    Context: Only called from attach() and/or detach() path contexts
3627  */
3628 static int
3629 hermon_hca_ports_shutdown(hermon_state_t *state, uint_t num_init)
3630 {
3631         int     i, status;
3632 
3633         /*
3634          * Post commands to shutdown all init'd Hermon HCA ports.  Note: if
3635          * any of these commands fail for any reason, it would be entirely
3636          * unexpected and probably indicative a serious problem (HW or SW).
3637          * Although we do return void from this function, this type of failure
3638          * should not go unreported.  That is why we have the warning message.
3639          */
3640         for (i = 0; i < num_init; i++) {
3641                 status = hermon_close_port_cmd_post(state, i + 1,
3642                     HERMON_CMD_NOSLEEP_SPIN);
3643                 if (status != HERMON_CMD_SUCCESS) {
3644                         HERMON_WARNING(state, "failed to shutdown HCA port");
3645                         return (status);
3646                 }
3647         }
3648         return (HERMON_CMD_SUCCESS);
3649 }
3650 
3651 
3652 /*
3653  * hermon_internal_uarpg_init
3654  *    Context: Only called from attach() path context
3655  */
3656 static int
3657 hermon_internal_uarpg_init(hermon_state_t *state)
3658 {
3659         int     status;
3660         hermon_dbr_info_t       *info;
3661 
3662         /*
3663          * Allocate the UAR page for kernel use. This UAR page is
3664          * the privileged UAR page through which all kernel generated
3665          * doorbells will be rung. There are a number of UAR pages
3666          * reserved by hardware at the front of the UAR BAR, indicated
3667          * by DEVCAP.num_rsvd_uar, which we have already allocated. So,
3668          * the kernel page, or UAR page index num_rsvd_uar, will be
3669          * allocated here for kernel use.
3670          */
3671 
3672         status = hermon_rsrc_alloc(state, HERMON_UARPG, 1, HERMON_SLEEP,
3673             &state->hs_uarkpg_rsrc);
3674         if (status != DDI_SUCCESS) {
3675                 return (DDI_FAILURE);
3676         }
3677 
3678         /* Setup pointer to kernel UAR page */
3679         state->hs_uar = (hermon_hw_uar_t *)state->hs_uarkpg_rsrc->hr_addr;
3680 
3681         /* need to set up DBr tracking as well */
3682         status = hermon_dbr_page_alloc(state, &info);
3683         if (status != DDI_SUCCESS) {
3684                 return (DDI_FAILURE);
3685         }
3686         state->hs_kern_dbr = info;
3687         return (DDI_SUCCESS);
3688 }
3689 
3690 
3691 /*
3692  * hermon_internal_uarpg_fini
3693  *    Context: Only called from attach() and/or detach() path contexts
3694  */
3695 static void
3696 hermon_internal_uarpg_fini(hermon_state_t *state)
3697 {
3698         /* Free up Hermon UAR page #1 (kernel driver doorbells) */
3699         hermon_rsrc_free(state, &state->hs_uarkpg_rsrc);
3700 }
3701 
3702 
3703 /*
3704  * hermon_special_qp_contexts_reserve()
3705  *    Context: Only called from attach() path context
3706  */
3707 static int
3708 hermon_special_qp_contexts_reserve(hermon_state_t *state)
3709 {
3710         hermon_rsrc_t   *qp0_rsrc, *qp1_rsrc, *qp_resvd;
3711         int             status;
3712 
3713         /* Initialize the lock used for special QP rsrc management */
3714         mutex_init(&state->hs_spec_qplock, NULL, MUTEX_DRIVER,
3715             DDI_INTR_PRI(state->hs_intrmsi_pri));
3716 
3717         /*
3718          * Reserve contexts for QP0.  These QP contexts will be setup to
3719          * act as aliases for the real QP0.  Note: We are required to grab
3720          * two QPs (one per port) even if we are operating in single-port
3721          * mode.
3722          */
3723         status = hermon_rsrc_alloc(state, HERMON_QPC, 2,
3724             HERMON_SLEEP, &qp0_rsrc);
3725         if (status != DDI_SUCCESS) {
3726                 mutex_destroy(&state->hs_spec_qplock);
3727                 return (DDI_FAILURE);
3728         }
3729         state->hs_spec_qp0 = qp0_rsrc;
3730 
3731         /*
3732          * Reserve contexts for QP1.  These QP contexts will be setup to
3733          * act as aliases for the real QP1.  Note: We are required to grab
3734          * two QPs (one per port) even if we are operating in single-port
3735          * mode.
3736          */
3737         status = hermon_rsrc_alloc(state, HERMON_QPC, 2,
3738             HERMON_SLEEP, &qp1_rsrc);
3739         if (status != DDI_SUCCESS) {
3740                 hermon_rsrc_free(state, &qp0_rsrc);
3741                 mutex_destroy(&state->hs_spec_qplock);
3742                 return (DDI_FAILURE);
3743         }
3744         state->hs_spec_qp1 = qp1_rsrc;
3745 
3746         status = hermon_rsrc_alloc(state, HERMON_QPC, 4,
3747             HERMON_SLEEP, &qp_resvd);
3748         if (status != DDI_SUCCESS) {
3749                 hermon_rsrc_free(state, &qp1_rsrc);
3750                 hermon_rsrc_free(state, &qp0_rsrc);
3751                 mutex_destroy(&state->hs_spec_qplock);
3752                 return (DDI_FAILURE);
3753         }
3754         state->hs_spec_qp_unused = qp_resvd;
3755 
3756         return (DDI_SUCCESS);
3757 }
3758 
3759 
3760 /*
3761  * hermon_special_qp_contexts_unreserve()
3762  *    Context: Only called from attach() and/or detach() path contexts
3763  */
3764 static void
3765 hermon_special_qp_contexts_unreserve(hermon_state_t *state)
3766 {
3767 
3768         /* Unreserve contexts for spec_qp_unused */
3769         hermon_rsrc_free(state, &state->hs_spec_qp_unused);
3770 
3771         /* Unreserve contexts for QP1 */
3772         hermon_rsrc_free(state, &state->hs_spec_qp1);
3773 
3774         /* Unreserve contexts for QP0 */
3775         hermon_rsrc_free(state, &state->hs_spec_qp0);
3776 
3777         /* Destroy the lock used for special QP rsrc management */
3778         mutex_destroy(&state->hs_spec_qplock);
3779 
3780 }
3781 
3782 
3783 /*
3784  * hermon_sw_reset()
3785  *    Context: Currently called only from attach() path context
3786  */
3787 static int
3788 hermon_sw_reset(hermon_state_t *state)
3789 {
3790         ddi_acc_handle_t        hdl = hermon_get_pcihdl(state);
3791         ddi_acc_handle_t        cmdhdl = hermon_get_cmdhdl(state);
3792         uint32_t                reset_delay;
3793         int                     status, i;
3794         uint32_t                sem;
3795         uint_t                  offset;
3796         uint32_t                data32;         /* for devctl & linkctl */
3797         int                     loopcnt;
3798 
3799         /* initialize the FMA retry loop */
3800         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
3801         hermon_pio_init(fm_loop_cnt2, fm_status2, fm_test2);
3802 
3803         /*
3804          * If the configured software reset delay is set to zero, then we
3805          * will not attempt a software reset of the Hermon device.
3806          */
3807         reset_delay = state->hs_cfg_profile->cp_sw_reset_delay;
3808         if (reset_delay == 0) {
3809                 return (DDI_SUCCESS);
3810         }
3811 
3812         /* the FMA retry loop starts. */
3813         hermon_pio_start(state, cmdhdl, pio_error, fm_loop_cnt, fm_status,
3814             fm_test);
3815         hermon_pio_start(state, hdl, pio_error2, fm_loop_cnt2, fm_status2,
3816             fm_test2);
3817 
3818         /* Query the PCI capabilities of the HCA device */
3819         /* but don't process the VPD until after reset */
3820         status = hermon_pci_capability_list(state, hdl);
3821         if (status != DDI_SUCCESS) {
3822                 cmn_err(CE_NOTE, "failed to get pci capabilities list(0x%x)\n",
3823                     status);
3824                 return (DDI_FAILURE);
3825         }
3826 
3827         /*
3828          * Read all PCI config info (reg0...reg63).  Note: According to the
3829          * Hermon software reset application note, we should not read or
3830          * restore the values in reg22 and reg23.
3831          * NOTE:  For Hermon (and Arbel too) it says to restore the command
3832          * register LAST, and technically, you need to restore the
3833          * PCIE Capability "device control" and "link control" (word-sized,
3834          * at offsets 0x08 and 0x10 from the capbility ID respectively).
3835          * We hold off restoring the command register - offset 0x4 - till last
3836          */
3837 
3838         /* 1st, wait for the semaphore assure accessibility - per PRM */
3839         status = -1;
3840         for (i = 0; i < NANOSEC/MICROSEC /* 1sec timeout */; i++) {
3841                 sem = ddi_get32(cmdhdl, state->hs_cmd_regs.sw_semaphore);
3842                 if (sem == 0) {
3843                         status = 0;
3844                         break;
3845                 }
3846                 drv_usecwait(1);
3847         }
3848 
3849         /* Check if timeout happens */
3850         if (status == -1) {
3851                 /*
3852                  * Remove this acc handle from Hermon, then log
3853                  * the error.
3854                  */
3855                 hermon_pci_config_teardown(state, &hdl);
3856 
3857                 cmn_err(CE_WARN, "hermon_sw_reset timeout: "
3858                     "failed to get the semaphore(0x%p)\n",
3859                     (void *)state->hs_cmd_regs.sw_semaphore);
3860 
3861                 hermon_fm_ereport(state, HCA_IBA_ERR, HCA_ERR_NON_FATAL);
3862                 return (DDI_FAILURE);
3863         }
3864 
3865         for (i = 0; i < HERMON_SW_RESET_NUMREGS; i++) {
3866                 if ((i != HERMON_SW_RESET_REG22_RSVD) &&
3867                     (i != HERMON_SW_RESET_REG23_RSVD)) {
3868                         state->hs_cfg_data[i]  = pci_config_get32(hdl, i << 2);
3869                 }
3870         }
3871 
3872         /*
3873          * Perform the software reset (by writing 1 at offset 0xF0010)
3874          */
3875         ddi_put32(cmdhdl, state->hs_cmd_regs.sw_reset, HERMON_SW_RESET_START);
3876 
3877         /*
3878          * This delay is required so as not to cause a panic here. If the
3879          * device is accessed too soon after reset it will not respond to
3880          * config cycles, causing a Master Abort and panic.
3881          */
3882         drv_usecwait(reset_delay);
3883 
3884         /*
3885          * Poll waiting for the device to finish resetting.
3886          */
3887         loopcnt = 100;  /* 100 times @ 100 usec - total delay 10 msec */
3888         while ((pci_config_get32(hdl, 0) & 0x0000FFFF) != PCI_VENID_MLX) {
3889                 drv_usecwait(HERMON_SW_RESET_POLL_DELAY);
3890                 if (--loopcnt == 0)
3891                         break;  /* just in case, break and go on */
3892         }
3893         if (loopcnt == 0)
3894                 cmn_err(CE_CONT, "!Never see VEND_ID - read == %X",
3895                     pci_config_get32(hdl, 0));
3896 
3897         /*
3898          * Restore the config info
3899          */
3900         for (i = 0; i < HERMON_SW_RESET_NUMREGS; i++) {
3901                 if (i == 1) continue;   /* skip the status/ctrl reg */
3902                 if ((i != HERMON_SW_RESET_REG22_RSVD) &&
3903                     (i != HERMON_SW_RESET_REG23_RSVD)) {
3904                         pci_config_put32(hdl, i << 2, state->hs_cfg_data[i]);
3905                 }
3906         }
3907 
3908         /*
3909          * PCI Express Capability - we saved during capability list, and
3910          * we'll restore them here.
3911          */
3912         offset = state->hs_pci_cap_offset;
3913         data32 = state->hs_pci_cap_devctl;
3914         pci_config_put32(hdl, offset + HERMON_PCI_CAP_DEV_OFFS, data32);
3915         data32 = state->hs_pci_cap_lnkctl;
3916         pci_config_put32(hdl, offset + HERMON_PCI_CAP_LNK_OFFS, data32);
3917 
3918         pci_config_put32(hdl, 0x04, (state->hs_cfg_data[1] | 0x0006));
3919 
3920         /* the FMA retry loop ends. */
3921         hermon_pio_end(state, hdl, pio_error2, fm_loop_cnt2, fm_status2,
3922             fm_test2);
3923         hermon_pio_end(state, cmdhdl, pio_error, fm_loop_cnt, fm_status,
3924             fm_test);
3925 
3926         return (DDI_SUCCESS);
3927 
3928 pio_error2:
3929         /* fall through */
3930 pio_error:
3931         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_NON_FATAL);
3932         return (DDI_FAILURE);
3933 }
3934 
3935 
3936 /*
3937  * hermon_mcg_init()
3938  *    Context: Only called from attach() path context
3939  */
3940 static int
3941 hermon_mcg_init(hermon_state_t *state)
3942 {
3943         uint_t          mcg_tmp_sz;
3944 
3945 
3946         /*
3947          * Allocate space for the MCG temporary copy buffer.  This is
3948          * used by the Attach/Detach Multicast Group code
3949          */
3950         mcg_tmp_sz = HERMON_MCGMEM_SZ(state);
3951         state->hs_mcgtmp = kmem_zalloc(mcg_tmp_sz, KM_SLEEP);
3952 
3953         /*
3954          * Initialize the multicast group mutex.  This ensures atomic
3955          * access to add, modify, and remove entries in the multicast
3956          * group hash lists.
3957          */
3958         mutex_init(&state->hs_mcglock, NULL, MUTEX_DRIVER,
3959             DDI_INTR_PRI(state->hs_intrmsi_pri));
3960 
3961         return (DDI_SUCCESS);
3962 }
3963 
3964 
3965 /*
3966  * hermon_mcg_fini()
3967  *    Context: Only called from attach() and/or detach() path contexts
3968  */
3969 static void
3970 hermon_mcg_fini(hermon_state_t *state)
3971 {
3972         uint_t          mcg_tmp_sz;
3973 
3974 
3975         /* Free up the space used for the MCG temporary copy buffer */
3976         mcg_tmp_sz = HERMON_MCGMEM_SZ(state);
3977         kmem_free(state->hs_mcgtmp, mcg_tmp_sz);
3978 
3979         /* Destroy the multicast group mutex */
3980         mutex_destroy(&state->hs_mcglock);
3981 
3982 }
3983 
3984 
3985 /*
3986  * hermon_fw_version_check()
3987  *    Context: Only called from attach() path context
3988  */
3989 static int
3990 hermon_fw_version_check(hermon_state_t *state)
3991 {
3992 
3993         uint_t  hermon_fw_ver_major;
3994         uint_t  hermon_fw_ver_minor;
3995         uint_t  hermon_fw_ver_subminor;
3996 
3997 #ifdef FMA_TEST
3998         if (hermon_test_num == -1) {
3999                 return (DDI_FAILURE);
4000         }
4001 #endif
4002 
4003         /*
4004          * Depending on which version of driver we have attached, and which
4005          * HCA we've attached, the firmware version checks will be different.
4006          * We set up the comparison values for both Arbel and Sinai HCAs.
4007          */
4008         switch (state->hs_operational_mode) {
4009         case HERMON_HCA_MODE:
4010                 hermon_fw_ver_major = HERMON_FW_VER_MAJOR;
4011                 hermon_fw_ver_minor = HERMON_FW_VER_MINOR;
4012                 hermon_fw_ver_subminor = HERMON_FW_VER_SUBMINOR;
4013                 break;
4014 
4015         default:
4016                 return (DDI_FAILURE);
4017         }
4018 
4019         /*
4020          * If FW revision major number is less than acceptable,
4021          * return failure, else if greater return success.  If
4022          * the major numbers are equal than check the minor number
4023          */
4024         if (state->hs_fw.fw_rev_major < hermon_fw_ver_major) {
4025                 return (DDI_FAILURE);
4026         } else if (state->hs_fw.fw_rev_major > hermon_fw_ver_major) {
4027                 return (DDI_SUCCESS);
4028         }
4029 
4030         /*
4031          * Do the same check as above, except for minor revision numbers
4032          * If the minor numbers are equal than check the subminor number
4033          */
4034         if (state->hs_fw.fw_rev_minor < hermon_fw_ver_minor) {
4035                 return (DDI_FAILURE);
4036         } else if (state->hs_fw.fw_rev_minor > hermon_fw_ver_minor) {
4037                 return (DDI_SUCCESS);
4038         }
4039 
4040         /*
4041          * Once again we do the same check as above, except for the subminor
4042          * revision number.  If the subminor numbers are equal here, then
4043          * these are the same firmware version, return success
4044          */
4045         if (state->hs_fw.fw_rev_subminor < hermon_fw_ver_subminor) {
4046                 return (DDI_FAILURE);
4047         } else if (state->hs_fw.fw_rev_subminor > hermon_fw_ver_subminor) {
4048                 return (DDI_SUCCESS);
4049         }
4050 
4051         return (DDI_SUCCESS);
4052 }
4053 
4054 
4055 /*
4056  * hermon_device_info_report()
4057  *    Context: Only called from attach() path context
4058  */
4059 static void
4060 hermon_device_info_report(hermon_state_t *state)
4061 {
4062 
4063         cmn_err(CE_CONT, "?hermon%d: FW ver: %04d.%04d.%04d, "
4064             "HW rev: %02d\n", state->hs_instance, state->hs_fw.fw_rev_major,
4065             state->hs_fw.fw_rev_minor, state->hs_fw.fw_rev_subminor,
4066             state->hs_revision_id);
4067         cmn_err(CE_CONT, "?hermon%d: %64s (0x%016" PRIx64 ")\n",
4068             state->hs_instance, state->hs_nodedesc, state->hs_nodeguid);
4069 
4070 }
4071 
4072 
4073 /*
4074  * hermon_pci_capability_list()
4075  *    Context: Only called from attach() path context
4076  */
4077 static int
4078 hermon_pci_capability_list(hermon_state_t *state, ddi_acc_handle_t hdl)
4079 {
4080         uint_t          offset, data;
4081         uint32_t        data32;
4082 
4083         state->hs_pci_cap_offset = 0;                /* make sure it's cleared */
4084 
4085         /*
4086          * Check for the "PCI Capabilities" bit in the "Status Register".
4087          * Bit 4 in this register indicates the presence of a "PCI
4088          * Capabilities" list.
4089          *
4090          * PCI-Express requires this bit to be set to 1.
4091          */
4092         data = pci_config_get16(hdl, 0x06);
4093         if ((data & 0x10) == 0) {
4094                 return (DDI_FAILURE);
4095         }
4096 
4097         /*
4098          * Starting from offset 0x34 in PCI config space, find the
4099          * head of "PCI capabilities" list, and walk the list.  If
4100          * capabilities of a known type are encountered (e.g.
4101          * "PCI-X Capability"), then call the appropriate handler
4102          * function.
4103          */
4104         offset = pci_config_get8(hdl, 0x34);
4105         while (offset != 0x0) {
4106                 data = pci_config_get8(hdl, offset);
4107                 /*
4108                  * Check for known capability types.  Hermon has the
4109                  * following:
4110                  *    o Power Mgmt       (0x02)
4111                  *    o VPD Capability   (0x03)
4112                  *    o PCI-E Capability (0x10)
4113                  *    o MSIX Capability  (0x11)
4114                  */
4115                 switch (data) {
4116                 case 0x01:
4117                         /* power mgmt handling */
4118                         break;
4119                 case 0x03:
4120 
4121 /*
4122  * Reading the PCIe VPD is inconsistent - that is, sometimes causes
4123  * problems on (mostly) X64, though we've also seen problems w/ Sparc
4124  * and Tavor --- so, for now until it's root caused, don't try and
4125  * read it
4126  */
4127 #ifdef HERMON_VPD_WORKS
4128                         hermon_pci_capability_vpd(state, hdl, offset);
4129 #else
4130                         delay(100);
4131                         hermon_pci_capability_vpd(state, hdl, offset);
4132 #endif
4133                         break;
4134                 case 0x10:
4135                         /*
4136                          * PCI Express Capability - save offset & contents
4137                          * for later in reset
4138                          */
4139                         state->hs_pci_cap_offset = offset;
4140                         data32 = pci_config_get32(hdl,
4141                             offset + HERMON_PCI_CAP_DEV_OFFS);
4142                         state->hs_pci_cap_devctl = data32;
4143                         data32 = pci_config_get32(hdl,
4144                             offset + HERMON_PCI_CAP_LNK_OFFS);
4145                         state->hs_pci_cap_lnkctl = data32;
4146                         break;
4147                 case 0x11:
4148                         /*
4149                          * MSIX support - nothing to do, taken care of in the
4150                          * MSI/MSIX interrupt frameworkd
4151                          */
4152                         break;
4153                 default:
4154                         /* just go on to the next */
4155                         break;
4156                 }
4157 
4158                 /* Get offset of next entry in list */
4159                 offset = pci_config_get8(hdl, offset + 1);
4160         }
4161 
4162         return (DDI_SUCCESS);
4163 }
4164 
4165 /*
4166  * hermon_pci_read_vpd()
4167  *    Context: Only called from attach() path context
4168  *    utility routine for hermon_pci_capability_vpd()
4169  */
4170 static int
4171 hermon_pci_read_vpd(ddi_acc_handle_t hdl, uint_t offset, uint32_t addr,
4172     uint32_t *data)
4173 {
4174         int             retry = 40;  /* retry counter for EEPROM poll */
4175         uint32_t        val;
4176         int             vpd_addr = offset + 2;
4177         int             vpd_data = offset + 4;
4178 
4179         /*
4180          * In order to read a 32-bit value from VPD, we are to write down
4181          * the address (offset in the VPD itself) to the address register.
4182          * To signal the read, we also clear bit 31.  We then poll on bit 31
4183          * and when it is set, we can then read our 4 bytes from the data
4184          * register.
4185          */
4186         (void) pci_config_put32(hdl, offset, addr << 16);
4187         do {
4188                 drv_usecwait(1000);
4189                 val = pci_config_get16(hdl, vpd_addr);
4190                 if (val & 0x8000) {         /* flag bit set */
4191                         *data = pci_config_get32(hdl, vpd_data);
4192                         return (DDI_SUCCESS);
4193                 }
4194         } while (--retry);
4195         /* read of flag failed write one message but count the failures */
4196         if (debug_vpd == 0)
4197                 cmn_err(CE_NOTE,
4198                     "!Failed to see flag bit after VPD addr write\n");
4199         debug_vpd++;
4200 
4201 
4202 vpd_read_fail:
4203         return (DDI_FAILURE);
4204 }
4205 
4206 
4207 
4208 /*
4209  *   hermon_pci_capability_vpd()
4210  *    Context: Only called from attach() path context
4211  */
4212 static void
4213 hermon_pci_capability_vpd(hermon_state_t *state, ddi_acc_handle_t hdl,
4214     uint_t offset)
4215 {
4216         uint8_t                 name_length;
4217         uint8_t                 pn_length;
4218         int                     i, err = 0;
4219         int                     vpd_str_id = 0;
4220         int                     vpd_ro_desc;
4221         int                     vpd_ro_pn_desc;
4222 #ifdef _BIG_ENDIAN
4223         uint32_t                data32;
4224 #endif /* _BIG_ENDIAN */
4225         union {
4226                 uint32_t        vpd_int[HERMON_VPD_HDR_DWSIZE];
4227                 uchar_t         vpd_char[HERMON_VPD_HDR_BSIZE];
4228         } vpd;
4229 
4230 
4231         /*
4232          * Read in the Vital Product Data (VPD) to the extend needed
4233          * by the fwflash utility
4234          */
4235         for (i = 0; i < HERMON_VPD_HDR_DWSIZE; i++) {
4236                 err = hermon_pci_read_vpd(hdl, offset, i << 2, &vpd.vpd_int[i]);
4237                 if (err != DDI_SUCCESS) {
4238                         cmn_err(CE_NOTE, "!VPD read failed\n");
4239                         goto out;
4240                 }
4241         }
4242 
4243 #ifdef _BIG_ENDIAN
4244         /* Need to swap bytes for big endian. */
4245         for (i = 0; i < HERMON_VPD_HDR_DWSIZE; i++) {
4246                 data32 = vpd.vpd_int[i];
4247                 vpd.vpd_char[(i << 2) + 3] =
4248                     (uchar_t)((data32 & 0xFF000000) >> 24);
4249                 vpd.vpd_char[(i << 2) + 2] =
4250                     (uchar_t)((data32 & 0x00FF0000) >> 16);
4251                 vpd.vpd_char[(i << 2) + 1] =
4252                     (uchar_t)((data32 & 0x0000FF00) >> 8);
4253                 vpd.vpd_char[i << 2] = (uchar_t)(data32 & 0x000000FF);
4254         }
4255 #endif  /* _BIG_ENDIAN */
4256 
4257         /* Check for VPD String ID Tag */
4258         if (vpd.vpd_char[vpd_str_id] == 0x82) {
4259                 /* get the product name */
4260                 name_length = (uint8_t)vpd.vpd_char[vpd_str_id + 1];
4261                 if (name_length > sizeof (state->hs_hca_name)) {
4262                         cmn_err(CE_NOTE, "!VPD name too large (0x%x)\n",
4263                             name_length);
4264                         goto out;
4265                 }
4266                 (void) memcpy(state->hs_hca_name, &vpd.vpd_char[vpd_str_id + 3],
4267                     name_length);
4268                 state->hs_hca_name[name_length] = 0;
4269 
4270                 /* get the part number */
4271                 vpd_ro_desc = name_length + 3; /* read-only tag location */
4272                 vpd_ro_pn_desc = vpd_ro_desc + 3; /* P/N keyword location */
4273 
4274                 /* Verify read-only tag and Part Number keyword. */
4275                 if (vpd.vpd_char[vpd_ro_desc] != 0x90 ||
4276                     (vpd.vpd_char[vpd_ro_pn_desc] != 'P' &&
4277                     vpd.vpd_char[vpd_ro_pn_desc + 1] != 'N')) {
4278                         cmn_err(CE_NOTE, "!VPD Part Number not found\n");
4279                         goto out;
4280                 }
4281 
4282                 pn_length = (uint8_t)vpd.vpd_char[vpd_ro_pn_desc + 2];
4283                 if (pn_length > sizeof (state->hs_hca_pn)) {
4284                         cmn_err(CE_NOTE, "!VPD part number too large (0x%x)\n",
4285                             name_length);
4286                         goto out;
4287                 }
4288                 (void) memcpy(state->hs_hca_pn,
4289                     &vpd.vpd_char[vpd_ro_pn_desc + 3],
4290                     pn_length);
4291                 state->hs_hca_pn[pn_length] = 0;
4292                 state->hs_hca_pn_len = pn_length;
4293                 cmn_err(CE_CONT, "!vpd %s\n", state->hs_hca_pn);
4294         } else {
4295                 /* Wrong VPD String ID Tag */
4296                 cmn_err(CE_NOTE, "!VPD String ID Tag not found, tag: %02x\n",
4297                     vpd.vpd_char[0]);
4298                 goto out;
4299         }
4300         return;
4301 out:
4302         state->hs_hca_pn_len = 0;
4303 }
4304 
4305 
4306 
4307 /*
4308  * hermon_intr_or_msi_init()
4309  *    Context: Only called from attach() path context
4310  */
4311 static int
4312 hermon_intr_or_msi_init(hermon_state_t *state)
4313 {
4314         int     status;
4315 
4316         /* Query for the list of supported interrupt event types */
4317         status = ddi_intr_get_supported_types(state->hs_dip,
4318             &state->hs_intr_types_avail);
4319         if (status != DDI_SUCCESS) {
4320                 return (DDI_FAILURE);
4321         }
4322 
4323         /*
4324          * If Hermon supports MSI-X in this system (and, if it
4325          * hasn't been overridden by a configuration variable), then
4326          * the default behavior is to use a single MSI-X.  Otherwise,
4327          * fallback to using legacy interrupts.  Also, if MSI-X is chosen,
4328          * but fails for whatever reasons, then next try MSI
4329          */
4330         if ((state->hs_cfg_profile->cp_use_msi_if_avail != 0) &&
4331             (state->hs_intr_types_avail & DDI_INTR_TYPE_MSIX)) {
4332                 status = hermon_add_intrs(state, DDI_INTR_TYPE_MSIX);
4333                 if (status == DDI_SUCCESS) {
4334                         state->hs_intr_type_chosen = DDI_INTR_TYPE_MSIX;
4335                         return (DDI_SUCCESS);
4336                 }
4337         }
4338 
4339         /*
4340          * If Hermon supports MSI in this system (and, if it
4341          * hasn't been overridden by a configuration variable), then
4342          * the default behavior is to use a single MSIX.  Otherwise,
4343          * fallback to using legacy interrupts.  Also, if MSI is chosen,
4344          * but fails for whatever reasons, then fallback to using legacy
4345          * interrupts.
4346          */
4347         if ((state->hs_cfg_profile->cp_use_msi_if_avail != 0) &&
4348             (state->hs_intr_types_avail & DDI_INTR_TYPE_MSI)) {
4349                 status = hermon_add_intrs(state, DDI_INTR_TYPE_MSI);
4350                 if (status == DDI_SUCCESS) {
4351                         state->hs_intr_type_chosen = DDI_INTR_TYPE_MSI;
4352                         return (DDI_SUCCESS);
4353                 }
4354         }
4355 
4356         /*
4357          * MSI interrupt allocation failed, or was not available.  Fallback to
4358          * legacy interrupt support.
4359          */
4360         if (state->hs_intr_types_avail & DDI_INTR_TYPE_FIXED) {
4361                 status = hermon_add_intrs(state, DDI_INTR_TYPE_FIXED);
4362                 if (status == DDI_SUCCESS) {
4363                         state->hs_intr_type_chosen = DDI_INTR_TYPE_FIXED;
4364                         return (DDI_SUCCESS);
4365                 }
4366         }
4367 
4368         /*
4369          * None of MSI, MSI-X, nor legacy interrupts were successful.
4370          * Return failure.
4371          */
4372         return (DDI_FAILURE);
4373 }
4374 
4375 /* ARGSUSED */
4376 static int
4377 hermon_intr_cb_handler(dev_info_t *dip, ddi_cb_action_t action, void *cbarg,
4378     void *arg1, void *arg2)
4379 {
4380         hermon_state_t *state = (hermon_state_t *)arg1;
4381 
4382         IBTF_DPRINTF_L2("hermon", "interrupt callback: instance %d, "
4383             "action %d, cbarg %d\n", state->hs_instance, action,
4384             (uint32_t)(uintptr_t)cbarg);
4385         return (DDI_SUCCESS);
4386 }
4387 
4388 /*
4389  * hermon_add_intrs()
4390  *    Context: Only called from attach() patch context
4391  */
4392 static int
4393 hermon_add_intrs(hermon_state_t *state, int intr_type)
4394 {
4395         int     status;
4396 
4397         if (state->hs_intr_cb_hdl == NULL) {
4398                 status = ddi_cb_register(state->hs_dip, DDI_CB_FLAG_INTR,
4399                     hermon_intr_cb_handler, state, NULL,
4400                     &state->hs_intr_cb_hdl);
4401                 if (status != DDI_SUCCESS) {
4402                         cmn_err(CE_CONT, "ddi_cb_register failed: 0x%x\n",
4403                             status);
4404                         state->hs_intr_cb_hdl = NULL;
4405                         return (DDI_FAILURE);
4406                 }
4407         }
4408 
4409         /* Get number of interrupts/MSI supported */
4410         status = ddi_intr_get_nintrs(state->hs_dip, intr_type,
4411             &state->hs_intrmsi_count);
4412         if (status != DDI_SUCCESS) {
4413                 (void) ddi_cb_unregister(state->hs_intr_cb_hdl);
4414                 state->hs_intr_cb_hdl = NULL;
4415                 return (DDI_FAILURE);
4416         }
4417 
4418         /* Get number of available interrupts/MSI */
4419         status = ddi_intr_get_navail(state->hs_dip, intr_type,
4420             &state->hs_intrmsi_avail);
4421         if (status != DDI_SUCCESS) {
4422                 (void) ddi_cb_unregister(state->hs_intr_cb_hdl);
4423                 state->hs_intr_cb_hdl = NULL;
4424                 return (DDI_FAILURE);
4425         }
4426 
4427         /* Ensure that we have at least one (1) usable MSI or interrupt */
4428         if ((state->hs_intrmsi_avail < 1) || (state->hs_intrmsi_count < 1)) {
4429                 (void) ddi_cb_unregister(state->hs_intr_cb_hdl);
4430                 state->hs_intr_cb_hdl = NULL;
4431                 return (DDI_FAILURE);
4432         }
4433 
4434         /*
4435          * Allocate the #interrupt/MSI handles.
4436          * The number we request is the minimum of these three values:
4437          *      HERMON_MSIX_MAX                 driver maximum (array size)
4438          *      hermon_msix_max                 /etc/system override to...
4439          *                                              HERMON_MSIX_MAX
4440          *      state->hs_intrmsi_avail              Maximum the ddi provides.
4441          */
4442         status = ddi_intr_alloc(state->hs_dip, &state->hs_intrmsi_hdl[0],
4443             intr_type, 0, min(min(HERMON_MSIX_MAX, state->hs_intrmsi_avail),
4444             hermon_msix_max), &state->hs_intrmsi_allocd, DDI_INTR_ALLOC_NORMAL);
4445         if (status != DDI_SUCCESS) {
4446                 (void) ddi_cb_unregister(state->hs_intr_cb_hdl);
4447                 state->hs_intr_cb_hdl = NULL;
4448                 return (DDI_FAILURE);
4449         }
4450 
4451         /* Ensure that we have allocated at least one (1) MSI or interrupt */
4452         if (state->hs_intrmsi_allocd < 1) {
4453                 (void) ddi_cb_unregister(state->hs_intr_cb_hdl);
4454                 state->hs_intr_cb_hdl = NULL;
4455                 return (DDI_FAILURE);
4456         }
4457 
4458         /*
4459          * Extract the priority for the allocated interrupt/MSI.  This
4460          * will be used later when initializing certain mutexes.
4461          */
4462         status = ddi_intr_get_pri(state->hs_intrmsi_hdl[0],
4463             &state->hs_intrmsi_pri);
4464         if (status != DDI_SUCCESS) {
4465                 /* Free the allocated interrupt/MSI handle */
4466                 (void) ddi_intr_free(state->hs_intrmsi_hdl[0]);
4467 
4468                 (void) ddi_cb_unregister(state->hs_intr_cb_hdl);
4469                 state->hs_intr_cb_hdl = NULL;
4470                 return (DDI_FAILURE);
4471         }
4472 
4473         /* Make sure the interrupt/MSI priority is below 'high level' */
4474         if (state->hs_intrmsi_pri >= ddi_intr_get_hilevel_pri()) {
4475                 /* Free the allocated interrupt/MSI handle */
4476                 (void) ddi_intr_free(state->hs_intrmsi_hdl[0]);
4477 
4478                 return (DDI_FAILURE);
4479         }
4480 
4481         /* Get add'l capability information regarding interrupt/MSI */
4482         status = ddi_intr_get_cap(state->hs_intrmsi_hdl[0],
4483             &state->hs_intrmsi_cap);
4484         if (status != DDI_SUCCESS) {
4485                 /* Free the allocated interrupt/MSI handle */
4486                 (void) ddi_intr_free(state->hs_intrmsi_hdl[0]);
4487 
4488                 return (DDI_FAILURE);
4489         }
4490 
4491         return (DDI_SUCCESS);
4492 }
4493 
4494 
4495 /*
4496  * hermon_intr_or_msi_fini()
4497  *    Context: Only called from attach() and/or detach() path contexts
4498  */
4499 static int
4500 hermon_intr_or_msi_fini(hermon_state_t *state)
4501 {
4502         int     status;
4503         int     intr;
4504 
4505         for (intr = 0; intr < state->hs_intrmsi_allocd; intr++) {
4506 
4507                 /* Free the allocated interrupt/MSI handle */
4508                 status = ddi_intr_free(state->hs_intrmsi_hdl[intr]);
4509                 if (status != DDI_SUCCESS) {
4510                         return (DDI_FAILURE);
4511                 }
4512         }
4513         if (state->hs_intr_cb_hdl) {
4514                 (void) ddi_cb_unregister(state->hs_intr_cb_hdl);
4515                 state->hs_intr_cb_hdl = NULL;
4516         }
4517         return (DDI_SUCCESS);
4518 }
4519 
4520 
4521 /*ARGSUSED*/
4522 void
4523 hermon_pci_capability_msix(hermon_state_t *state, ddi_acc_handle_t hdl,
4524     uint_t offset)
4525 {
4526         uint32_t        msix_data;
4527         uint16_t        msg_cntr;
4528         uint32_t        t_offset;       /* table offset */
4529         uint32_t        t_bir;
4530         uint32_t        p_offset;       /* pba */
4531         uint32_t        p_bir;
4532         int             t_size;         /* size in entries - each is 4 dwords */
4533 
4534         /* come in with offset pointing at the capability structure */
4535 
4536         msix_data = pci_config_get32(hdl, offset);
4537         cmn_err(CE_CONT, "Full cap structure dword = %X\n", msix_data);
4538         msg_cntr =  pci_config_get16(hdl, offset+2);
4539         cmn_err(CE_CONT, "MSIX msg_control = %X\n", msg_cntr);
4540         offset += 4;
4541         msix_data = pci_config_get32(hdl, offset);      /* table info */
4542         t_offset = (msix_data & 0xFFF8) >> 3;
4543         t_bir = msix_data & 0x07;
4544         offset += 4;
4545         cmn_err(CE_CONT, "  table %X --offset = %X, bir(bar) = %X\n",
4546             msix_data, t_offset, t_bir);
4547         msix_data = pci_config_get32(hdl, offset);      /* PBA info */
4548         p_offset = (msix_data & 0xFFF8) >> 3;
4549         p_bir = msix_data & 0x07;
4550 
4551         cmn_err(CE_CONT, "  PBA   %X --offset = %X, bir(bar) = %X\n",
4552             msix_data, p_offset, p_bir);
4553         t_size = msg_cntr & 0x7FF;          /* low eleven bits */
4554         cmn_err(CE_CONT, "    table size = %X entries\n", t_size);
4555 
4556         offset = t_offset;              /* reuse this for offset from BAR */
4557 #ifdef HERMON_SUPPORTS_MSIX_BAR
4558         cmn_err(CE_CONT, "First 2 table entries behind BAR2 \n");
4559         for (i = 0; i < 2; i++) {
4560                 for (j = 0; j < 4; j++, offset += 4) {
4561                         msix_data = ddi_get32(state->hs_reg_msihdl,
4562                             (uint32_t *)((uintptr_t)state->hs_reg_msi_baseaddr
4563                             + offset));
4564                         cmn_err(CE_CONT, "MSI table entry %d, dword %d == %X\n",
4565                             i, j, msix_data);
4566                 }
4567         }
4568 #endif
4569 
4570 }
4571 
4572 /*
4573  * X86 fastreboot support functions.
4574  * These functions are used to save/restore MSI-X table/PBA and also
4575  * to disable MSI-X interrupts in hermon_quiesce().
4576  */
4577 
4578 /* Return the message control for MSI-X */
4579 static ushort_t
4580 get_msix_ctrl(dev_info_t *dip)
4581 {
4582         ushort_t msix_ctrl = 0, caps_ctrl = 0;
4583         hermon_state_t *state = ddi_get_soft_state(hermon_statep,
4584             DEVI(dip)->devi_instance);
4585         ddi_acc_handle_t pci_cfg_hdl = hermon_get_pcihdl(state);
4586         ASSERT(pci_cfg_hdl != NULL);
4587 
4588         if ((PCI_CAP_LOCATE(pci_cfg_hdl,
4589             PCI_CAP_ID_MSI_X, &caps_ctrl) == DDI_SUCCESS)) {
4590                 if ((msix_ctrl = PCI_CAP_GET16(pci_cfg_hdl, NULL, caps_ctrl,
4591                     PCI_MSIX_CTRL)) == PCI_CAP_EINVAL16)
4592                         return (0);
4593         }
4594         ASSERT(msix_ctrl != 0);
4595 
4596         return (msix_ctrl);
4597 }
4598 
4599 /* Return the MSI-X table size */
4600 static size_t
4601 get_msix_tbl_size(dev_info_t *dip)
4602 {
4603         ushort_t msix_ctrl = get_msix_ctrl(dip);
4604         ASSERT(msix_ctrl != 0);
4605 
4606         return (((msix_ctrl & PCI_MSIX_TBL_SIZE_MASK) + 1) *
4607             PCI_MSIX_VECTOR_SIZE);
4608 }
4609 
4610 /* Return the MSI-X PBA size */
4611 static size_t
4612 get_msix_pba_size(dev_info_t *dip)
4613 {
4614         ushort_t msix_ctrl = get_msix_ctrl(dip);
4615         ASSERT(msix_ctrl != 0);
4616 
4617         return (((msix_ctrl & PCI_MSIX_TBL_SIZE_MASK) + 64) / 64 * 8);
4618 }
4619 
4620 /* Set up the MSI-X table/PBA save area */
4621 static void
4622 hermon_set_msix_info(hermon_state_t *state)
4623 {
4624         uint_t                  rnumber, breg, nregs;
4625         ushort_t                caps_ctrl, msix_ctrl;
4626         pci_regspec_t           *rp;
4627         int                     reg_size, addr_space, offset, *regs_list, i;
4628 
4629         /*
4630          * MSI-X BIR Index Table:
4631          * BAR indicator register (BIR) to Base Address register.
4632          */
4633         uchar_t pci_msix_bir_index[8] = {0x10, 0x14, 0x18, 0x1c,
4634             0x20, 0x24, 0xff, 0xff};
4635 
4636         /* Fastreboot data access  attribute */
4637         ddi_device_acc_attr_t   dev_attr = {
4638                 0,                              /* version */
4639                 DDI_STRUCTURE_LE_ACC,
4640                 DDI_STRICTORDER_ACC,            /* attr access */
4641                 0
4642         };
4643 
4644         ddi_acc_handle_t pci_cfg_hdl = hermon_get_pcihdl(state);
4645         ASSERT(pci_cfg_hdl != NULL);
4646 
4647         if ((PCI_CAP_LOCATE(pci_cfg_hdl,
4648             PCI_CAP_ID_MSI_X, &caps_ctrl) == DDI_SUCCESS)) {
4649                 if ((msix_ctrl = PCI_CAP_GET16(pci_cfg_hdl, NULL, caps_ctrl,
4650                     PCI_MSIX_CTRL)) == PCI_CAP_EINVAL16)
4651                         return;
4652         }
4653         ASSERT(msix_ctrl != 0);
4654 
4655         state->hs_msix_tbl_offset = PCI_CAP_GET32(pci_cfg_hdl, NULL, caps_ctrl,
4656             PCI_MSIX_TBL_OFFSET);
4657 
4658         /* Get the BIR for MSI-X table */
4659         breg = pci_msix_bir_index[state->hs_msix_tbl_offset &
4660             PCI_MSIX_TBL_BIR_MASK];
4661         ASSERT(breg != 0xFF);
4662 
4663         /* Set the MSI-X table offset */
4664         state->hs_msix_tbl_offset = state->hs_msix_tbl_offset &
4665             ~PCI_MSIX_TBL_BIR_MASK;
4666 
4667         /* Set the MSI-X table size */
4668         state->hs_msix_tbl_size = ((msix_ctrl & PCI_MSIX_TBL_SIZE_MASK) + 1) *
4669             PCI_MSIX_VECTOR_SIZE;
4670 
4671         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, state->hs_dip,
4672             DDI_PROP_DONTPASS, "reg", (int **)&regs_list, &nregs) !=
4673             DDI_PROP_SUCCESS) {
4674                 return;
4675         }
4676         reg_size = sizeof (pci_regspec_t) / sizeof (int);
4677 
4678         /* Check the register number for MSI-X table */
4679         for (i = 1, rnumber = 0; i < nregs/reg_size; i++) {
4680                 rp = (pci_regspec_t *)&regs_list[i * reg_size];
4681                 addr_space = rp->pci_phys_hi & PCI_ADDR_MASK;
4682                 offset = PCI_REG_REG_G(rp->pci_phys_hi);
4683 
4684                 if ((offset == breg) && ((addr_space == PCI_ADDR_MEM32) ||
4685                     (addr_space == PCI_ADDR_MEM64))) {
4686                         rnumber = i;
4687                         break;
4688                 }
4689         }
4690         ASSERT(rnumber != 0);
4691         state->hs_msix_tbl_rnumber = rnumber;
4692 
4693         /* Set device attribute version and access according to Hermon FM */
4694         dev_attr.devacc_attr_version = hermon_devacc_attr_version(state);
4695         dev_attr.devacc_attr_access = hermon_devacc_attr_access(state);
4696 
4697         /* Map the entire MSI-X vector table */
4698         if (hermon_regs_map_setup(state, state->hs_msix_tbl_rnumber,
4699             (caddr_t *)&state->hs_msix_tbl_addr, state->hs_msix_tbl_offset,
4700             state->hs_msix_tbl_size, &dev_attr,
4701             &state->hs_fm_msix_tblhdl) != DDI_SUCCESS) {
4702                 return;
4703         }
4704 
4705         state->hs_msix_pba_offset = PCI_CAP_GET32(pci_cfg_hdl, NULL, caps_ctrl,
4706             PCI_MSIX_PBA_OFFSET);
4707 
4708         /* Get the BIR for MSI-X PBA */
4709         breg = pci_msix_bir_index[state->hs_msix_pba_offset &
4710             PCI_MSIX_PBA_BIR_MASK];
4711         ASSERT(breg != 0xFF);
4712 
4713         /* Set the MSI-X PBA offset */
4714         state->hs_msix_pba_offset = state->hs_msix_pba_offset &
4715             ~PCI_MSIX_PBA_BIR_MASK;
4716 
4717         /* Set the MSI-X PBA size */
4718         state->hs_msix_pba_size =
4719             ((msix_ctrl & PCI_MSIX_TBL_SIZE_MASK) + 64) / 64 * 8;
4720 
4721         /* Check the register number for MSI-X PBA */
4722         for (i = 1, rnumber = 0; i < nregs/reg_size; i++) {
4723                 rp = (pci_regspec_t *)&regs_list[i * reg_size];
4724                 addr_space = rp->pci_phys_hi & PCI_ADDR_MASK;
4725                 offset = PCI_REG_REG_G(rp->pci_phys_hi);
4726 
4727                 if ((offset == breg) && ((addr_space == PCI_ADDR_MEM32) ||
4728                     (addr_space == PCI_ADDR_MEM64))) {
4729                         rnumber = i;
4730                         break;
4731                 }
4732         }
4733         ASSERT(rnumber != 0);
4734         state->hs_msix_pba_rnumber = rnumber;
4735         ddi_prop_free(regs_list);
4736 
4737         /* Map in the MSI-X Pending Bit Array */
4738         if (hermon_regs_map_setup(state, state->hs_msix_pba_rnumber,
4739             (caddr_t *)&state->hs_msix_pba_addr, state->hs_msix_pba_offset,
4740             state->hs_msix_pba_size, &dev_attr,
4741             &state->hs_fm_msix_pbahdl) != DDI_SUCCESS) {
4742                 hermon_regs_map_free(state, &state->hs_fm_msix_tblhdl);
4743                 state->hs_fm_msix_tblhdl = NULL;
4744                 return;
4745         }
4746 
4747         /* Set the MSI-X table save area */
4748         state->hs_msix_tbl_entries = kmem_alloc(state->hs_msix_tbl_size,
4749             KM_SLEEP);
4750 
4751         /* Set the MSI-X PBA save area */
4752         state->hs_msix_pba_entries = kmem_alloc(state->hs_msix_pba_size,
4753             KM_SLEEP);
4754 }
4755 
4756 /* Disable Hermon interrupts */
4757 static int
4758 hermon_intr_disable(hermon_state_t *state)
4759 {
4760         ushort_t msix_ctrl = 0, caps_ctrl = 0;
4761         ddi_acc_handle_t pci_cfg_hdl = hermon_get_pcihdl(state);
4762         ddi_acc_handle_t msix_tblhdl = hermon_get_msix_tblhdl(state);
4763         int i, j;
4764         ASSERT(pci_cfg_hdl != NULL && msix_tblhdl != NULL);
4765         ASSERT(state->hs_intr_types_avail &
4766             (DDI_INTR_TYPE_FIXED | DDI_INTR_TYPE_MSI | DDI_INTR_TYPE_MSIX));
4767 
4768         /*
4769          * Check if MSI-X interrupts are used. If so, disable MSI-X interupts.
4770          * If not, since Hermon doesn't support MSI interrupts, assuming the
4771          * legacy interrupt is used instead, disable the legacy interrupt.
4772          */
4773         if ((state->hs_cfg_profile->cp_use_msi_if_avail != 0) &&
4774             (state->hs_intr_types_avail & DDI_INTR_TYPE_MSIX)) {
4775 
4776                 if ((PCI_CAP_LOCATE(pci_cfg_hdl,
4777                     PCI_CAP_ID_MSI_X, &caps_ctrl) == DDI_SUCCESS)) {
4778                         if ((msix_ctrl = PCI_CAP_GET16(pci_cfg_hdl, NULL,
4779                             caps_ctrl, PCI_MSIX_CTRL)) == PCI_CAP_EINVAL16)
4780                                 return (DDI_FAILURE);
4781                 }
4782                 ASSERT(msix_ctrl != 0);
4783 
4784                 if (!(msix_ctrl & PCI_MSIX_ENABLE_BIT))
4785                         return (DDI_SUCCESS);
4786 
4787                 /* Clear all inums in MSI-X table */
4788                 for (i = 0; i < get_msix_tbl_size(state->hs_dip);
4789                     i += PCI_MSIX_VECTOR_SIZE) {
4790                         for (j = 0; j < PCI_MSIX_VECTOR_SIZE; j += 4) {
4791                                 char *addr = state->hs_msix_tbl_addr + i + j;
4792                                 ddi_put32(msix_tblhdl,
4793                                     (uint32_t *)(uintptr_t)addr, 0x0);
4794                         }
4795                 }
4796 
4797                 /* Disable MSI-X interrupts */
4798                 msix_ctrl &= ~PCI_MSIX_ENABLE_BIT;
4799                 PCI_CAP_PUT16(pci_cfg_hdl, NULL, caps_ctrl, PCI_MSIX_CTRL,
4800                     msix_ctrl);
4801 
4802         } else {
4803                 uint16_t cmdreg = pci_config_get16(pci_cfg_hdl, PCI_CONF_COMM);
4804                 ASSERT(state->hs_intr_types_avail & DDI_INTR_TYPE_FIXED);
4805 
4806                 /* Disable the legacy interrupts */
4807                 cmdreg |= PCI_COMM_INTX_DISABLE;
4808                 pci_config_put16(pci_cfg_hdl, PCI_CONF_COMM, cmdreg);
4809         }
4810 
4811         return (DDI_SUCCESS);
4812 }
4813 
4814 /* Hermon quiesce(9F) entry */
4815 static int
4816 hermon_quiesce(dev_info_t *dip)
4817 {
4818         hermon_state_t *state = ddi_get_soft_state(hermon_statep,
4819             DEVI(dip)->devi_instance);
4820         ddi_acc_handle_t pcihdl = hermon_get_pcihdl(state);
4821         ddi_acc_handle_t cmdhdl = hermon_get_cmdhdl(state);
4822         ddi_acc_handle_t msix_tbl_hdl = hermon_get_msix_tblhdl(state);
4823         ddi_acc_handle_t msix_pba_hdl = hermon_get_msix_pbahdl(state);
4824         uint32_t sem, reset_delay = state->hs_cfg_profile->cp_sw_reset_delay;
4825         uint64_t data64;
4826         uint32_t data32;
4827         int status, i, j, loopcnt;
4828         uint_t offset;
4829 
4830         ASSERT(state != NULL);
4831 
4832         /* start fastreboot */
4833         state->hs_quiescing = B_TRUE;
4834 
4835         /* If it's in maintenance mode, do nothing but return with SUCCESS */
4836         if (!HERMON_IS_OPERATIONAL(state->hs_operational_mode)) {
4837                 return (DDI_SUCCESS);
4838         }
4839 
4840         /* suppress Hermon FM ereports */
4841         if (hermon_get_state(state) & HCA_EREPORT_FM) {
4842                 hermon_clr_state_nolock(state, HCA_EREPORT_FM);
4843         }
4844 
4845         /* Shutdown HCA ports */
4846         if (hermon_hca_ports_shutdown(state,
4847             state->hs_cfg_profile->cp_num_ports) != HERMON_CMD_SUCCESS) {
4848                 state->hs_quiescing = B_FALSE;
4849                 return (DDI_FAILURE);
4850         }
4851 
4852         /* Close HCA */
4853         if (hermon_close_hca_cmd_post(state, HERMON_CMD_NOSLEEP_SPIN) !=
4854             HERMON_CMD_SUCCESS) {
4855                 state->hs_quiescing = B_FALSE;
4856                 return (DDI_FAILURE);
4857         }
4858 
4859         /* Disable interrupts */
4860         if (hermon_intr_disable(state) != DDI_SUCCESS) {
4861                 state->hs_quiescing = B_FALSE;
4862                 return (DDI_FAILURE);
4863         }
4864 
4865         /*
4866          * Query the PCI capabilities of the HCA device, but don't process
4867          * the VPD until after reset.
4868          */
4869         if (hermon_pci_capability_list(state, pcihdl) != DDI_SUCCESS) {
4870                 state->hs_quiescing = B_FALSE;
4871                 return (DDI_FAILURE);
4872         }
4873 
4874         /*
4875          * Read all PCI config info (reg0...reg63).  Note: According to the
4876          * Hermon software reset application note, we should not read or
4877          * restore the values in reg22 and reg23.
4878          * NOTE:  For Hermon (and Arbel too) it says to restore the command
4879          * register LAST, and technically, you need to restore the
4880          * PCIE Capability "device control" and "link control" (word-sized,
4881          * at offsets 0x08 and 0x10 from the capbility ID respectively).
4882          * We hold off restoring the command register - offset 0x4 - till last
4883          */
4884 
4885         /* 1st, wait for the semaphore assure accessibility - per PRM */
4886         status = -1;
4887         for (i = 0; i < NANOSEC/MICROSEC /* 1sec timeout */; i++) {
4888                 sem = ddi_get32(cmdhdl, state->hs_cmd_regs.sw_semaphore);
4889                 if (sem == 0) {
4890                         status = 0;
4891                         break;
4892                 }
4893                 drv_usecwait(1);
4894         }
4895 
4896         /* Check if timeout happens */
4897         if (status == -1) {
4898                 state->hs_quiescing = B_FALSE;
4899                 return (DDI_FAILURE);
4900         }
4901 
4902         /* MSI-X interrupts are used, save the MSI-X table */
4903         if (msix_tbl_hdl && msix_pba_hdl) {
4904                 /* save MSI-X table */
4905                 for (i = 0; i < get_msix_tbl_size(state->hs_dip);
4906                     i += PCI_MSIX_VECTOR_SIZE) {
4907                         for (j = 0; j < PCI_MSIX_VECTOR_SIZE; j += 4) {
4908                                 char *addr = state->hs_msix_tbl_addr + i + j;
4909                                 data32 = ddi_get32(msix_tbl_hdl,
4910                                     (uint32_t *)(uintptr_t)addr);
4911                                 *(uint32_t *)(uintptr_t)(state->
4912                                     hs_msix_tbl_entries + i + j) = data32;
4913                         }
4914                 }
4915                 /* save MSI-X PBA */
4916                 for (i = 0; i < get_msix_pba_size(state->hs_dip); i += 8) {
4917                         char *addr = state->hs_msix_pba_addr + i;
4918                         data64 = ddi_get64(msix_pba_hdl,
4919                             (uint64_t *)(uintptr_t)addr);
4920                         *(uint64_t *)(uintptr_t)(state->
4921                             hs_msix_pba_entries + i) = data64;
4922                 }
4923         }
4924 
4925         /* save PCI config space */
4926         for (i = 0; i < HERMON_SW_RESET_NUMREGS; i++) {
4927                 if ((i != HERMON_SW_RESET_REG22_RSVD) &&
4928                     (i != HERMON_SW_RESET_REG23_RSVD)) {
4929                         state->hs_cfg_data[i]  =
4930                             pci_config_get32(pcihdl, i << 2);
4931                 }
4932         }
4933 
4934         /* SW-reset HCA */
4935         ddi_put32(cmdhdl, state->hs_cmd_regs.sw_reset, HERMON_SW_RESET_START);
4936 
4937         /*
4938          * This delay is required so as not to cause a panic here. If the
4939          * device is accessed too soon after reset it will not respond to
4940          * config cycles, causing a Master Abort and panic.
4941          */
4942         drv_usecwait(reset_delay);
4943 
4944         /* Poll waiting for the device to finish resetting */
4945         loopcnt = 100;  /* 100 times @ 100 usec - total delay 10 msec */
4946         while ((pci_config_get32(pcihdl, 0) & 0x0000FFFF) != PCI_VENID_MLX) {
4947                 drv_usecwait(HERMON_SW_RESET_POLL_DELAY);
4948                 if (--loopcnt == 0)
4949                         break;  /* just in case, break and go on */
4950         }
4951         if (loopcnt == 0) {
4952                 state->hs_quiescing = B_FALSE;
4953                 return (DDI_FAILURE);
4954         }
4955 
4956         /* Restore the config info */
4957         for (i = 0; i < HERMON_SW_RESET_NUMREGS; i++) {
4958                 if (i == 1) continue;   /* skip the status/ctrl reg */
4959                 if ((i != HERMON_SW_RESET_REG22_RSVD) &&
4960                     (i != HERMON_SW_RESET_REG23_RSVD)) {
4961                         pci_config_put32(pcihdl, i << 2, state->hs_cfg_data[i]);
4962                 }
4963         }
4964 
4965         /* If MSI-X interrupts are used, restore the MSI-X table */
4966         if (msix_tbl_hdl && msix_pba_hdl) {
4967                 /* restore MSI-X PBA */
4968                 for (i = 0; i < get_msix_pba_size(state->hs_dip); i += 8) {
4969                         char *addr = state->hs_msix_pba_addr + i;
4970                         data64 = *(uint64_t *)(uintptr_t)
4971                             (state->hs_msix_pba_entries + i);
4972                         ddi_put64(msix_pba_hdl,
4973                             (uint64_t *)(uintptr_t)addr, data64);
4974                 }
4975                 /* restore MSI-X table */
4976                 for (i = 0; i < get_msix_tbl_size(state->hs_dip);
4977                     i += PCI_MSIX_VECTOR_SIZE) {
4978                         for (j = 0; j < PCI_MSIX_VECTOR_SIZE; j += 4) {
4979                                 char *addr = state->hs_msix_tbl_addr + i + j;
4980                                 data32 = *(uint32_t *)(uintptr_t)
4981                                     (state->hs_msix_tbl_entries + i + j);
4982                                 ddi_put32(msix_tbl_hdl,
4983                                     (uint32_t *)(uintptr_t)addr, data32);
4984                         }
4985                 }
4986         }
4987 
4988         /*
4989          * PCI Express Capability - we saved during capability list, and
4990          * we'll restore them here.
4991          */
4992         offset = state->hs_pci_cap_offset;
4993         data32 = state->hs_pci_cap_devctl;
4994         pci_config_put32(pcihdl, offset + HERMON_PCI_CAP_DEV_OFFS, data32);
4995         data32 = state->hs_pci_cap_lnkctl;
4996         pci_config_put32(pcihdl, offset + HERMON_PCI_CAP_LNK_OFFS, data32);
4997 
4998         /* restore the command register */
4999         pci_config_put32(pcihdl, 0x04, (state->hs_cfg_data[1] | 0x0006));
5000 
5001         return (DDI_SUCCESS);
5002 }