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) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * tavor.c 28 * Tavor (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 * Tavor 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/tavor/tavor.h> 49 #include <sys/pci.h> 50 51 /* Tavor HCA State Pointer */ 52 void *tavor_statep; 53 54 /* 55 * The Tavor "userland resource database" is common to instances of the 56 * Tavor HCA driver. This structure "tavor_userland_rsrc_db" contains all 57 * the necessary information to maintain it. 58 */ 59 tavor_umap_db_t tavor_userland_rsrc_db; 60 61 static int tavor_attach(dev_info_t *, ddi_attach_cmd_t); 62 static int tavor_detach(dev_info_t *, ddi_detach_cmd_t); 63 static int tavor_open(dev_t *, int, int, cred_t *); 64 static int tavor_close(dev_t, int, int, cred_t *); 65 static int tavor_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 66 static int tavor_drv_init(tavor_state_t *state, dev_info_t *dip, int instance); 67 static void tavor_drv_fini(tavor_state_t *state); 68 static void tavor_drv_fini2(tavor_state_t *state); 69 static int tavor_isr_init(tavor_state_t *state); 70 static void tavor_isr_fini(tavor_state_t *state); 71 static int tavor_hw_init(tavor_state_t *state); 72 static void tavor_hw_fini(tavor_state_t *state, 73 tavor_drv_cleanup_level_t cleanup); 74 static int tavor_soft_state_init(tavor_state_t *state); 75 static void tavor_soft_state_fini(tavor_state_t *state); 76 static int tavor_hca_port_init(tavor_state_t *state); 77 static int tavor_hca_ports_shutdown(tavor_state_t *state, uint_t num_init); 78 static void tavor_hca_config_setup(tavor_state_t *state, 79 tavor_hw_initqueryhca_t *inithca); 80 static int tavor_internal_uarpgs_init(tavor_state_t *state); 81 static void tavor_internal_uarpgs_fini(tavor_state_t *state); 82 static int tavor_special_qp_contexts_reserve(tavor_state_t *state); 83 static void tavor_special_qp_contexts_unreserve(tavor_state_t *state); 84 static int tavor_sw_reset(tavor_state_t *state); 85 static int tavor_mcg_init(tavor_state_t *state); 86 static void tavor_mcg_fini(tavor_state_t *state); 87 static int tavor_fw_version_check(tavor_state_t *state); 88 static void tavor_device_info_report(tavor_state_t *state); 89 static void tavor_pci_capability_list(tavor_state_t *state, 90 ddi_acc_handle_t hdl); 91 static void tavor_pci_capability_vpd(tavor_state_t *state, 92 ddi_acc_handle_t hdl, uint_t offset); 93 static int tavor_pci_read_vpd(ddi_acc_handle_t hdl, uint_t offset, 94 uint32_t addr, uint32_t *data); 95 static void tavor_pci_capability_pcix(tavor_state_t *state, 96 ddi_acc_handle_t hdl, uint_t offset); 97 static int tavor_intr_or_msi_init(tavor_state_t *state); 98 static int tavor_add_intrs(tavor_state_t *state, int intr_type); 99 static int tavor_intr_or_msi_fini(tavor_state_t *state); 100 101 /* X86 fastreboot support */ 102 static int tavor_intr_disable(tavor_state_t *); 103 static int tavor_quiesce(dev_info_t *); 104 105 /* Character/Block Operations */ 106 static struct cb_ops tavor_cb_ops = { 107 tavor_open, /* open */ 108 tavor_close, /* close */ 109 nodev, /* strategy (block) */ 110 nodev, /* print (block) */ 111 nodev, /* dump (block) */ 112 nodev, /* read */ 113 nodev, /* write */ 114 tavor_ioctl, /* ioctl */ 115 tavor_devmap, /* devmap */ 116 NULL, /* mmap */ 117 nodev, /* segmap */ 118 nochpoll, /* chpoll */ 119 ddi_prop_op, /* prop_op */ 120 NULL, /* streams */ 121 D_NEW | D_MP | 122 D_64BIT | D_HOTPLUG | 123 D_DEVMAP, /* flags */ 124 CB_REV /* rev */ 125 }; 126 127 /* Driver Operations */ 128 static struct dev_ops tavor_ops = { 129 DEVO_REV, /* struct rev */ 130 0, /* refcnt */ 131 tavor_getinfo, /* getinfo */ 132 nulldev, /* identify */ 133 nulldev, /* probe */ 134 tavor_attach, /* attach */ 135 tavor_detach, /* detach */ 136 nodev, /* reset */ 137 &tavor_cb_ops, /* cb_ops */ 138 NULL, /* bus_ops */ 139 nodev, /* power */ 140 tavor_quiesce, /* devo_quiesce */ 141 }; 142 143 /* Module Driver Info */ 144 static struct modldrv tavor_modldrv = { 145 &mod_driverops, 146 "Tavor InfiniBand HCA Driver", 147 &tavor_ops 148 }; 149 150 /* Module Linkage */ 151 static struct modlinkage tavor_modlinkage = { 152 MODREV_1, 153 &tavor_modldrv, 154 NULL 155 }; 156 157 /* 158 * This extern refers to the ibc_operations_t function vector that is defined 159 * in the tavor_ci.c file. 160 */ 161 extern ibc_operations_t tavor_ibc_ops; 162 163 #ifndef NPROBE 164 extern int tnf_mod_load(void); 165 extern int tnf_mod_unload(struct modlinkage *mlp); 166 #endif 167 168 169 /* 170 * _init() 171 */ 172 int 173 _init() 174 { 175 int status; 176 177 #ifndef NPROBE 178 (void) tnf_mod_load(); 179 #endif 180 TAVOR_TNF_ENTER(tavor_init); 181 182 status = ddi_soft_state_init(&tavor_statep, sizeof (tavor_state_t), 183 (size_t)TAVOR_INITIAL_STATES); 184 if (status != 0) { 185 TNF_PROBE_0(tavor_init_ssi_fail, TAVOR_TNF_ERROR, ""); 186 TAVOR_TNF_EXIT(tavor_init); 187 #ifndef NPROBE 188 (void) tnf_mod_unload(&tavor_modlinkage); 189 #endif 190 return (status); 191 } 192 193 status = ibc_init(&tavor_modlinkage); 194 if (status != 0) { 195 TNF_PROBE_0(tavor_init_ibc_init_fail, TAVOR_TNF_ERROR, ""); 196 ddi_soft_state_fini(&tavor_statep); 197 TAVOR_TNF_EXIT(tavor_init); 198 #ifndef NPROBE 199 (void) tnf_mod_unload(&tavor_modlinkage); 200 #endif 201 return (status); 202 } 203 status = mod_install(&tavor_modlinkage); 204 if (status != 0) { 205 TNF_PROBE_0(tavor_init_modi_fail, TAVOR_TNF_ERROR, ""); 206 ibc_fini(&tavor_modlinkage); 207 ddi_soft_state_fini(&tavor_statep); 208 TAVOR_TNF_EXIT(tavor_init); 209 #ifndef NPROBE 210 (void) tnf_mod_unload(&tavor_modlinkage); 211 #endif 212 return (status); 213 } 214 215 /* Initialize the Tavor "userland resources database" */ 216 tavor_umap_db_init(); 217 218 TAVOR_TNF_EXIT(tavor_init); 219 return (status); 220 } 221 222 223 /* 224 * _info() 225 */ 226 int 227 _info(struct modinfo *modinfop) 228 { 229 int status; 230 231 TAVOR_TNF_ENTER(tavor_info); 232 status = mod_info(&tavor_modlinkage, modinfop); 233 TAVOR_TNF_EXIT(tavor_info); 234 return (status); 235 } 236 237 238 /* 239 * _fini() 240 */ 241 int 242 _fini() 243 { 244 int status; 245 246 TAVOR_TNF_ENTER(tavor_fini); 247 248 status = mod_remove(&tavor_modlinkage); 249 if (status != 0) { 250 TNF_PROBE_0(tavor_fini_modr_fail, TAVOR_TNF_ERROR, ""); 251 TAVOR_TNF_EXIT(tavor_fini); 252 return (status); 253 } 254 255 /* Destroy the Tavor "userland resources database" */ 256 tavor_umap_db_fini(); 257 258 ibc_fini(&tavor_modlinkage); 259 ddi_soft_state_fini(&tavor_statep); 260 #ifndef NPROBE 261 (void) tnf_mod_unload(&tavor_modlinkage); 262 #endif 263 TAVOR_TNF_EXIT(tavor_fini); 264 return (status); 265 } 266 267 268 /* 269 * tavor_getinfo() 270 */ 271 /* ARGSUSED */ 272 static int 273 tavor_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 274 { 275 dev_t dev; 276 tavor_state_t *state; 277 minor_t instance; 278 279 TAVOR_TNF_ENTER(tavor_getinfo); 280 281 switch (cmd) { 282 case DDI_INFO_DEVT2DEVINFO: 283 dev = (dev_t)arg; 284 instance = TAVOR_DEV_INSTANCE(dev); 285 state = ddi_get_soft_state(tavor_statep, instance); 286 if (state == NULL) { 287 TNF_PROBE_0(tavor_getinfo_gss_fail, 288 TAVOR_TNF_ERROR, ""); 289 TAVOR_TNF_EXIT(tavor_getinfo); 290 return (DDI_FAILURE); 291 } 292 *result = (void *)state->ts_dip; 293 return (DDI_SUCCESS); 294 295 case DDI_INFO_DEVT2INSTANCE: 296 dev = (dev_t)arg; 297 instance = TAVOR_DEV_INSTANCE(dev); 298 *result = (void *)(uintptr_t)instance; 299 return (DDI_SUCCESS); 300 301 default: 302 TNF_PROBE_0(tavor_getinfo_default_fail, TAVOR_TNF_ERROR, ""); 303 break; 304 } 305 306 TAVOR_TNF_EXIT(tavor_getinfo); 307 return (DDI_FAILURE); 308 } 309 310 311 /* 312 * tavor_open() 313 */ 314 /* ARGSUSED */ 315 static int 316 tavor_open(dev_t *devp, int flag, int otyp, cred_t *credp) 317 { 318 tavor_state_t *state; 319 tavor_rsrc_t *rsrcp; 320 tavor_umap_db_entry_t *umapdb, *umapdb2; 321 minor_t instance; 322 uint64_t key, value; 323 uint_t tr_indx; 324 dev_t dev; 325 int status; 326 327 TAVOR_TNF_ENTER(tavor_open); 328 329 instance = TAVOR_DEV_INSTANCE(*devp); 330 state = ddi_get_soft_state(tavor_statep, instance); 331 if (state == NULL) { 332 TNF_PROBE_0(tavor_open_gss_fail, TAVOR_TNF_ERROR, ""); 333 TAVOR_TNF_EXIT(tavor_open); 334 return (ENXIO); 335 } 336 337 /* 338 * Only allow driver to be opened for character access, and verify 339 * whether exclusive access is allowed. 340 */ 341 if ((otyp != OTYP_CHR) || ((flag & FEXCL) && 342 secpolicy_excl_open(credp) != 0)) { 343 TNF_PROBE_0(tavor_open_invflags_fail, TAVOR_TNF_ERROR, ""); 344 TAVOR_TNF_EXIT(tavor_open); 345 return (EINVAL); 346 } 347 348 /* 349 * Search for the current process PID in the "userland resources 350 * database". If it is not found, then attempt to allocate a UAR 351 * page and add the ("key", "value") pair to the database. 352 * Note: As a last step we always return a devp appropriate for 353 * the open. Either we return a new minor number (based on the 354 * instance and the UAR page index) or we return the current minor 355 * number for the given client process. 356 * 357 * We also add an entry to the database to allow for lookup from 358 * "dev_t" to the current process PID. This is necessary because, 359 * under certain circumstance, the process PID that calls the Tavor 360 * close() entry point may not be the same as the one who called 361 * open(). Specifically, this can happen if a child process calls 362 * the Tavor's open() entry point, gets a UAR page, maps it out (using 363 * mmap()), and then exits without calling munmap(). Because mmap() 364 * adds a reference to the file descriptor, at the exit of the child 365 * process the file descriptor is "inherited" by the parent (and will 366 * be close()'d by the parent's PID only when it exits). 367 * 368 * Note: We use the tavor_umap_db_find_nolock() and 369 * tavor_umap_db_add_nolock() database access routines below (with 370 * an explicit mutex_enter of the database lock - "tdl_umapdb_lock") 371 * to ensure that the multiple accesses (in this case searching for, 372 * and then adding _two_ database entries) can be done atomically. 373 */ 374 key = ddi_get_pid(); 375 mutex_enter(&tavor_userland_rsrc_db.tdl_umapdb_lock); 376 status = tavor_umap_db_find_nolock(instance, key, 377 MLNX_UMAP_UARPG_RSRC, &value, 0, NULL); 378 if (status != DDI_SUCCESS) { 379 /* 380 * If we are in 'maintenance mode', we cannot alloc a UAR page. 381 * But we still need some rsrcp value, and a mostly unique 382 * tr_indx value. So we set rsrcp to NULL for maintenance 383 * mode, and use a rolling count for tr_indx. The field 384 * 'ts_open_tr_indx' is used only in this maintenance mode 385 * condition. 386 * 387 * Otherwise, if we are in operational mode then we allocate 388 * the UAR page as normal, and use the rsrcp value and tr_indx 389 * value from that allocation. 390 */ 391 if (!TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 392 rsrcp = NULL; 393 tr_indx = state->ts_open_tr_indx++; 394 } else { 395 /* Allocate a new UAR page for this process */ 396 status = tavor_rsrc_alloc(state, TAVOR_UARPG, 1, 397 TAVOR_NOSLEEP, &rsrcp); 398 if (status != DDI_SUCCESS) { 399 mutex_exit( 400 &tavor_userland_rsrc_db.tdl_umapdb_lock); 401 TNF_PROBE_0(tavor_open_rsrcalloc_uarpg_fail, 402 TAVOR_TNF_ERROR, ""); 403 TAVOR_TNF_EXIT(tavor_open); 404 return (EAGAIN); 405 } 406 407 tr_indx = rsrcp->tr_indx; 408 } 409 410 /* 411 * Allocate an entry to track the UAR page resource in the 412 * "userland resources database". 413 */ 414 umapdb = tavor_umap_db_alloc(instance, key, 415 MLNX_UMAP_UARPG_RSRC, (uint64_t)(uintptr_t)rsrcp); 416 if (umapdb == NULL) { 417 mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock); 418 /* If in "maintenance mode", don't free the rsrc */ 419 if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 420 tavor_rsrc_free(state, &rsrcp); 421 } 422 TNF_PROBE_0(tavor_open_umap_db_alloc_fail, 423 TAVOR_TNF_ERROR, ""); 424 TAVOR_TNF_EXIT(tavor_open); 425 return (EAGAIN); 426 } 427 428 /* 429 * Create a new device number. Minor number is a function of 430 * the UAR page index (15 bits) and the device instance number 431 * (3 bits). 432 */ 433 dev = makedevice(getmajor(*devp), (tr_indx << 434 TAVOR_MINORNUM_SHIFT) | instance); 435 436 /* 437 * Allocate another entry in the "userland resources database" 438 * to track the association of the device number (above) to 439 * the current process ID (in "key"). 440 */ 441 umapdb2 = tavor_umap_db_alloc(instance, dev, 442 MLNX_UMAP_PID_RSRC, (uint64_t)key); 443 if (umapdb2 == NULL) { 444 mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock); 445 tavor_umap_db_free(umapdb); 446 /* If in "maintenance mode", don't free the rsrc */ 447 if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 448 tavor_rsrc_free(state, &rsrcp); 449 } 450 TNF_PROBE_0(tavor_open_umap_db_alloc_fail, 451 TAVOR_TNF_ERROR, ""); 452 TAVOR_TNF_EXIT(tavor_open); 453 return (EAGAIN); 454 } 455 456 /* Add the entries to the database */ 457 tavor_umap_db_add_nolock(umapdb); 458 tavor_umap_db_add_nolock(umapdb2); 459 460 } else { 461 /* 462 * Return the same device number as on the original open() 463 * call. This was calculated as a function of the UAR page 464 * index (top 16 bits) and the device instance number 465 */ 466 rsrcp = (tavor_rsrc_t *)(uintptr_t)value; 467 dev = makedevice(getmajor(*devp), (rsrcp->tr_indx << 468 TAVOR_MINORNUM_SHIFT) | instance); 469 } 470 mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock); 471 472 *devp = dev; 473 474 TAVOR_TNF_EXIT(tavor_open); 475 return (0); 476 } 477 478 479 /* 480 * tavor_close() 481 */ 482 /* ARGSUSED */ 483 static int 484 tavor_close(dev_t dev, int flag, int otyp, cred_t *credp) 485 { 486 tavor_state_t *state; 487 tavor_rsrc_t *rsrcp; 488 tavor_umap_db_entry_t *umapdb; 489 tavor_umap_db_priv_t *priv; 490 minor_t instance; 491 uint64_t key, value; 492 int status; 493 494 TAVOR_TNF_ENTER(tavor_close); 495 496 instance = TAVOR_DEV_INSTANCE(dev); 497 state = ddi_get_soft_state(tavor_statep, instance); 498 if (state == NULL) { 499 TNF_PROBE_0(tavor_close_gss_fail, TAVOR_TNF_ERROR, ""); 500 TAVOR_TNF_EXIT(tavor_close); 501 return (ENXIO); 502 } 503 504 /* 505 * Search for "dev_t" in the "userland resources database". As 506 * explained above in tavor_open(), we can't depend on using the 507 * current process ID here to do the lookup because the process 508 * that ultimately closes may not be the same one who opened 509 * (because of inheritance). 510 * So we lookup the "dev_t" (which points to the PID of the process 511 * that opened), and we remove the entry from the database (and free 512 * it up). Then we do another query based on the PID value. And when 513 * we find that database entry, we free it up too and then free the 514 * Tavor UAR page resource. 515 * 516 * Note: We use the tavor_umap_db_find_nolock() database access 517 * routine below (with an explicit mutex_enter of the database lock) 518 * to ensure that the multiple accesses (which attempt to remove the 519 * two database entries) can be done atomically. 520 * 521 * This works the same in both maintenance mode and HCA mode, except 522 * for the call to tavor_rsrc_free(). In the case of maintenance mode, 523 * this call is not needed, as it was not allocated in tavor_open() 524 * above. 525 */ 526 key = dev; 527 mutex_enter(&tavor_userland_rsrc_db.tdl_umapdb_lock); 528 status = tavor_umap_db_find_nolock(instance, key, MLNX_UMAP_PID_RSRC, 529 &value, TAVOR_UMAP_DB_REMOVE, &umapdb); 530 if (status == DDI_SUCCESS) { 531 /* 532 * If the "tdb_priv" field is non-NULL, it indicates that 533 * some "on close" handling is still necessary. Call 534 * tavor_umap_db_handle_onclose_cb() to do the handling (i.e. 535 * to invoke all the registered callbacks). Then free up 536 * the resources associated with "tdb_priv" and continue 537 * closing. 538 */ 539 priv = (tavor_umap_db_priv_t *)umapdb->tdbe_common.tdb_priv; 540 if (priv != NULL) { 541 tavor_umap_db_handle_onclose_cb(priv); 542 kmem_free(priv, sizeof (tavor_umap_db_priv_t)); 543 umapdb->tdbe_common.tdb_priv = (void *)NULL; 544 } 545 546 tavor_umap_db_free(umapdb); 547 548 /* 549 * Now do another lookup using PID as the key (copy it from 550 * "value"). When this lookup is complete, the "value" field 551 * will contain the tavor_rsrc_t pointer for the UAR page 552 * resource. 553 */ 554 key = value; 555 status = tavor_umap_db_find_nolock(instance, key, 556 MLNX_UMAP_UARPG_RSRC, &value, TAVOR_UMAP_DB_REMOVE, 557 &umapdb); 558 if (status == DDI_SUCCESS) { 559 tavor_umap_db_free(umapdb); 560 /* If in "maintenance mode", don't free the rsrc */ 561 if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 562 rsrcp = (tavor_rsrc_t *)(uintptr_t)value; 563 tavor_rsrc_free(state, &rsrcp); 564 } 565 } 566 } 567 mutex_exit(&tavor_userland_rsrc_db.tdl_umapdb_lock); 568 569 TAVOR_TNF_EXIT(tavor_close); 570 return (0); 571 } 572 573 574 /* 575 * tavor_attach() 576 * Context: Only called from attach() path context 577 */ 578 static int 579 tavor_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 580 { 581 tavor_state_t *state; 582 ibc_clnt_hdl_t tmp_ibtfpriv; 583 ibc_status_t ibc_status; 584 int instance; 585 int status; 586 587 TAVOR_TNF_ENTER(tavor_attach); 588 589 switch (cmd) { 590 case DDI_ATTACH: 591 instance = ddi_get_instance(dip); 592 status = ddi_soft_state_zalloc(tavor_statep, instance); 593 if (status != DDI_SUCCESS) { 594 TNF_PROBE_0(tavor_attach_ssz_fail, TAVOR_TNF_ERROR, ""); 595 cmn_err(CE_NOTE, "tavor%d: driver failed to attach: " 596 "attach_ssz_fail", instance); 597 goto fail_attach_nomsg; 598 599 } 600 state = ddi_get_soft_state(tavor_statep, instance); 601 if (state == NULL) { 602 ddi_soft_state_free(tavor_statep, instance); 603 TNF_PROBE_0(tavor_attach_gss_fail, TAVOR_TNF_ERROR, ""); 604 cmn_err(CE_NOTE, "tavor%d: driver failed to attach: " 605 "attach_gss_fail", instance); 606 goto fail_attach_nomsg; 607 } 608 609 /* clear the attach error buffer */ 610 TAVOR_ATTACH_MSG_INIT(state->ts_attach_buf); 611 612 /* 613 * Initialize Tavor driver and hardware. 614 * 615 * Note: If this initialization fails we may still wish to 616 * create a device node and remain operational so that Tavor 617 * firmware can be updated/flashed (i.e. "maintenance mode"). 618 * If this is the case, then "ts_operational_mode" will be 619 * equal to TAVOR_MAINTENANCE_MODE. We will not attempt to 620 * attach to the IBTF or register with the IBMF (i.e. no 621 * InfiniBand interfaces will be enabled). 622 */ 623 status = tavor_drv_init(state, dip, instance); 624 if ((status != DDI_SUCCESS) && 625 (TAVOR_IS_OPERATIONAL(state->ts_operational_mode))) { 626 TNF_PROBE_0(tavor_attach_drvinit_fail, 627 TAVOR_TNF_ERROR, ""); 628 goto fail_attach; 629 } 630 631 /* Create the minor node for device */ 632 status = ddi_create_minor_node(dip, "devctl", S_IFCHR, instance, 633 DDI_PSEUDO, 0); 634 if (status != DDI_SUCCESS) { 635 tavor_drv_fini(state); 636 TAVOR_ATTACH_MSG(state->ts_attach_buf, 637 "attach_create_mn_fail"); 638 TNF_PROBE_0(tavor_attach_create_mn_fail, 639 TAVOR_TNF_ERROR, ""); 640 goto fail_attach; 641 } 642 643 /* 644 * If we are in "maintenance mode", then we don't want to 645 * register with the IBTF. All InfiniBand interfaces are 646 * uninitialized, and the device is only capable of handling 647 * requests to update/flash firmware (or test/debug requests). 648 */ 649 if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 650 651 /* Attach to InfiniBand Transport Framework (IBTF) */ 652 ibc_status = ibc_attach(&tmp_ibtfpriv, 653 &state->ts_ibtfinfo); 654 if (ibc_status != IBC_SUCCESS) { 655 ddi_remove_minor_node(dip, "devctl"); 656 tavor_drv_fini(state); 657 TNF_PROBE_0(tavor_attach_ibcattach_fail, 658 TAVOR_TNF_ERROR, ""); 659 TAVOR_ATTACH_MSG(state->ts_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 TAVOR_ENABLE_IBTF_CALLB(state, tmp_ibtfpriv); 670 671 ibc_post_attach(state->ts_ibtfpriv); 672 673 /* Register agents with IB Mgmt Framework (IBMF) */ 674 status = tavor_agent_handlers_init(state); 675 if (status != DDI_SUCCESS) { 676 (void) ibc_pre_detach(tmp_ibtfpriv, DDI_DETACH); 677 TAVOR_QUIESCE_IBTF_CALLB(state); 678 if (state->ts_in_evcallb != 0) { 679 TAVOR_WARNING(state, "unable to " 680 "quiesce Tavor IBTF callbacks"); 681 } 682 ibc_detach(tmp_ibtfpriv); 683 ddi_remove_minor_node(dip, "devctl"); 684 tavor_drv_fini(state); 685 TNF_PROBE_0(tavor_attach_agentinit_fail, 686 TAVOR_TNF_ERROR, ""); 687 TAVOR_ATTACH_MSG(state->ts_attach_buf, 688 "attach_agentinit_fail"); 689 goto fail_attach; 690 } 691 } 692 693 /* Report that driver was loaded */ 694 ddi_report_dev(dip); 695 696 /* Send device information to log file */ 697 tavor_device_info_report(state); 698 699 /* Report attach in maintenance mode, if appropriate */ 700 if (!(TAVOR_IS_OPERATIONAL(state->ts_operational_mode))) { 701 cmn_err(CE_NOTE, "tavor%d: driver attached " 702 "(for maintenance mode only)", state->ts_instance); 703 } 704 705 TAVOR_TNF_EXIT(tavor_attach); 706 return (DDI_SUCCESS); 707 708 case DDI_RESUME: 709 /* Add code here for DDI_RESUME XXX */ 710 TAVOR_TNF_EXIT(tavor_attach); 711 return (DDI_FAILURE); 712 713 default: 714 TNF_PROBE_0(tavor_attach_default_fail, TAVOR_TNF_ERROR, ""); 715 break; 716 } 717 718 fail_attach: 719 cmn_err(CE_NOTE, "tavor%d: driver failed to attach: %s", instance, 720 state->ts_attach_buf); 721 tavor_drv_fini2(state); 722 ddi_soft_state_free(tavor_statep, instance); 723 fail_attach_nomsg: 724 TAVOR_TNF_EXIT(tavor_attach); 725 return (DDI_FAILURE); 726 } 727 728 729 /* 730 * tavor_detach() 731 * Context: Only called from detach() path context 732 */ 733 static int 734 tavor_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 735 { 736 tavor_state_t *state; 737 ibc_clnt_hdl_t tmp_ibtfpriv; 738 ibc_status_t ibc_status; 739 int instance, status; 740 741 TAVOR_TNF_ENTER(tavor_detach); 742 743 instance = ddi_get_instance(dip); 744 state = ddi_get_soft_state(tavor_statep, instance); 745 if (state == NULL) { 746 TNF_PROBE_0(tavor_detach_gss_fail, TAVOR_TNF_ERROR, ""); 747 TAVOR_TNF_EXIT(tavor_detach); 748 return (DDI_FAILURE); 749 } 750 751 switch (cmd) { 752 case DDI_DETACH: 753 /* 754 * If we are in "maintenance mode", then we do not want to 755 * do teardown for any of the InfiniBand interfaces. 756 * Specifically, this means not detaching from IBTF (we never 757 * attached to begin with) and not deregistering from IBMF. 758 */ 759 if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 760 /* Unregister agents from IB Mgmt Framework (IBMF) */ 761 status = tavor_agent_handlers_fini(state); 762 if (status != DDI_SUCCESS) { 763 TNF_PROBE_0(tavor_detach_agentfini_fail, 764 TAVOR_TNF_ERROR, ""); 765 TAVOR_TNF_EXIT(tavor_detach); 766 return (DDI_FAILURE); 767 } 768 769 /* 770 * Attempt the "pre-detach" from InfiniBand Transport 771 * Framework (IBTF). At this point the IBTF is still 772 * capable of handling incoming asynch and completion 773 * events. This "pre-detach" is primarily a mechanism 774 * to notify the appropriate IBTF clients that the 775 * HCA is being removed/offlined. 776 */ 777 ibc_status = ibc_pre_detach(state->ts_ibtfpriv, cmd); 778 if (ibc_status != IBC_SUCCESS) { 779 status = tavor_agent_handlers_init(state); 780 if (status != DDI_SUCCESS) { 781 TAVOR_WARNING(state, "failed to " 782 "restart Tavor agents"); 783 } 784 TNF_PROBE_0(tavor_detach_ibcpredetach_fail, 785 TAVOR_TNF_ERROR, ""); 786 TAVOR_TNF_EXIT(tavor_detach); 787 return (DDI_FAILURE); 788 } 789 790 /* 791 * Before we can fully detach from the IBTF we need to 792 * ensure that we have handled all outstanding event 793 * callbacks. This is accomplished by quiescing the 794 * event callback mechanism. Note: if we are unable 795 * to successfully quiesce the callbacks, then this is 796 * an indication that something has probably gone 797 * seriously wrong. We print out a warning, but 798 * continue. 799 */ 800 tmp_ibtfpriv = state->ts_ibtfpriv; 801 TAVOR_QUIESCE_IBTF_CALLB(state); 802 if (state->ts_in_evcallb != 0) { 803 TAVOR_WARNING(state, "unable to quiesce Tavor " 804 "IBTF callbacks"); 805 } 806 807 /* Complete the detach from the IBTF */ 808 ibc_detach(tmp_ibtfpriv); 809 } 810 811 /* Remove the minor node for device */ 812 ddi_remove_minor_node(dip, "devctl"); 813 814 /* 815 * Only call tavor_drv_fini() if we are in Tavor HCA mode. 816 * (Because if we are in "maintenance mode", then we never 817 * successfully finished init.) Only report successful 818 * detach for normal HCA mode. 819 */ 820 if (TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 821 /* Cleanup driver resources and shutdown hardware */ 822 tavor_drv_fini(state); 823 cmn_err(CE_CONT, "Tavor driver successfully " 824 "detached\n"); 825 } 826 827 tavor_drv_fini2(state); 828 ddi_soft_state_free(tavor_statep, instance); 829 830 TAVOR_TNF_EXIT(tavor_detach); 831 return (DDI_SUCCESS); 832 833 case DDI_SUSPEND: 834 /* Add code here for DDI_SUSPEND XXX */ 835 TAVOR_TNF_EXIT(tavor_detach); 836 return (DDI_FAILURE); 837 838 default: 839 TNF_PROBE_0(tavor_detach_default_fail, TAVOR_TNF_ERROR, ""); 840 break; 841 } 842 843 TAVOR_TNF_EXIT(tavor_detach); 844 return (DDI_FAILURE); 845 } 846 847 848 /* 849 * tavor_drv_init() 850 * Context: Only called from attach() path context 851 */ 852 static int 853 tavor_drv_init(tavor_state_t *state, dev_info_t *dip, int instance) 854 { 855 int status; 856 857 TAVOR_TNF_ENTER(tavor_drv_init); 858 859 /* Save away devinfo and instance */ 860 state->ts_dip = dip; 861 state->ts_instance = instance; 862 863 /* 864 * Check and set the operational mode of the device. If the driver is 865 * bound to the Tavor device in "maintenance mode", then this generally 866 * means that either the device has been specifically jumpered to 867 * start in this mode or the firmware boot process has failed to 868 * successfully load either the primary or the secondary firmware 869 * image. 870 */ 871 if (TAVOR_IS_HCA_MODE(state->ts_dip)) { 872 state->ts_operational_mode = TAVOR_HCA_MODE; 873 874 } else if (TAVOR_IS_COMPAT_MODE(state->ts_dip)) { 875 state->ts_operational_mode = TAVOR_COMPAT_MODE; 876 877 } else if (TAVOR_IS_MAINTENANCE_MODE(state->ts_dip)) { 878 state->ts_operational_mode = TAVOR_MAINTENANCE_MODE; 879 return (DDI_FAILURE); 880 881 } else { 882 state->ts_operational_mode = 0; /* invalid operational mode */ 883 TAVOR_WARNING(state, "unexpected device type detected"); 884 TNF_PROBE_0(tavor_hw_init_unexpected_dev_fail, 885 TAVOR_TNF_ERROR, ""); 886 TAVOR_TNF_EXIT(tavor_hw_init); 887 return (DDI_FAILURE); 888 } 889 890 /* 891 * Initialize the Tavor hardware. 892 * Note: If this routine returns an error, it is often an reasonably 893 * good indication that something Tavor firmware-related has caused 894 * the failure. In order to give the user an opportunity (if desired) 895 * to update or reflash the Tavor firmware image, we set 896 * "ts_operational_mode" flag (described above) to indicate that we 897 * wish to enter maintenance mode. 898 */ 899 status = tavor_hw_init(state); 900 if (status != DDI_SUCCESS) { 901 state->ts_operational_mode = TAVOR_MAINTENANCE_MODE; 902 cmn_err(CE_NOTE, "tavor%d: error during attach: %s", instance, 903 state->ts_attach_buf); 904 TNF_PROBE_0(tavor_drv_init_hwinit_fail, TAVOR_TNF_ERROR, ""); 905 TAVOR_TNF_EXIT(tavor_drv_init); 906 return (DDI_FAILURE); 907 } 908 909 /* Setup Tavor interrupt handler */ 910 status = tavor_isr_init(state); 911 if (status != DDI_SUCCESS) { 912 tavor_hw_fini(state, TAVOR_DRV_CLEANUP_ALL); 913 TNF_PROBE_0(tavor_drv_init_isrinit_fail, TAVOR_TNF_ERROR, ""); 914 TAVOR_TNF_EXIT(tavor_drv_init); 915 return (DDI_FAILURE); 916 } 917 918 /* Initialize Tavor softstate */ 919 status = tavor_soft_state_init(state); 920 if (status != DDI_SUCCESS) { 921 tavor_isr_fini(state); 922 tavor_hw_fini(state, TAVOR_DRV_CLEANUP_ALL); 923 TNF_PROBE_0(tavor_drv_init_ssiinit_fail, TAVOR_TNF_ERROR, ""); 924 TAVOR_TNF_EXIT(tavor_drv_init); 925 return (DDI_FAILURE); 926 } 927 928 TAVOR_TNF_EXIT(tavor_drv_init); 929 return (DDI_SUCCESS); 930 } 931 932 933 /* 934 * tavor_drv_fini() 935 * Context: Only called from attach() and/or detach() path contexts 936 */ 937 static void 938 tavor_drv_fini(tavor_state_t *state) 939 { 940 TAVOR_TNF_ENTER(tavor_drv_fini); 941 942 /* Cleanup Tavor softstate */ 943 tavor_soft_state_fini(state); 944 945 /* Teardown Tavor interrupts */ 946 tavor_isr_fini(state); 947 948 /* Cleanup Tavor resources and shutdown hardware */ 949 tavor_hw_fini(state, TAVOR_DRV_CLEANUP_ALL); 950 951 TAVOR_TNF_EXIT(tavor_drv_fini); 952 } 953 954 /* 955 * tavor_drv_fini2() 956 * Context: Only called from attach() and/or detach() path contexts 957 */ 958 static void 959 tavor_drv_fini2(tavor_state_t *state) 960 { 961 TAVOR_TNF_ENTER(tavor_drv_fini2); 962 963 /* TAVOR_DRV_CLEANUP_LEVEL1 */ 964 if (state->ts_reg_cmdhdl) { 965 ddi_regs_map_free(&state->ts_reg_cmdhdl); 966 state->ts_reg_cmdhdl = NULL; 967 } 968 969 /* TAVOR_DRV_CLEANUP_LEVEL0 */ 970 if (state->ts_pci_cfghdl) { 971 pci_config_teardown(&state->ts_pci_cfghdl); 972 state->ts_pci_cfghdl = NULL; 973 } 974 975 TAVOR_TNF_EXIT(tavor_drv_fini2); 976 } 977 978 /* 979 * tavor_isr_init() 980 * Context: Only called from attach() path context 981 */ 982 static int 983 tavor_isr_init(tavor_state_t *state) 984 { 985 int status; 986 987 TAVOR_TNF_ENTER(tavor_isr_init); 988 989 /* 990 * Add a handler for the interrupt or MSI 991 */ 992 status = ddi_intr_add_handler(state->ts_intrmsi_hdl, tavor_isr, 993 (caddr_t)state, NULL); 994 if (status != DDI_SUCCESS) { 995 TNF_PROBE_0(tavor_isr_init_addhndlr_fail, TAVOR_TNF_ERROR, ""); 996 TAVOR_TNF_EXIT(tavor_isr_init); 997 return (DDI_FAILURE); 998 } 999 1000 /* 1001 * Enable the software interrupt. Note: Even though we are only 1002 * using one (1) interrupt/MSI, depending on the value returned in 1003 * the capability flag, we have to call either ddi_intr_block_enable() 1004 * or ddi_intr_enable(). 1005 */ 1006 if (state->ts_intrmsi_cap & DDI_INTR_FLAG_BLOCK) { 1007 status = ddi_intr_block_enable(&state->ts_intrmsi_hdl, 1); 1008 if (status != DDI_SUCCESS) { 1009 TNF_PROBE_0(tavor_isr_init_blockenable_fail, 1010 TAVOR_TNF_ERROR, ""); 1011 TAVOR_TNF_EXIT(tavor_isr_init); 1012 return (DDI_FAILURE); 1013 } 1014 } else { 1015 status = ddi_intr_enable(state->ts_intrmsi_hdl); 1016 if (status != DDI_SUCCESS) { 1017 TNF_PROBE_0(tavor_isr_init_intrenable_fail, 1018 TAVOR_TNF_ERROR, ""); 1019 TAVOR_TNF_EXIT(tavor_isr_init); 1020 return (DDI_FAILURE); 1021 } 1022 } 1023 1024 /* 1025 * Now that the ISR has been setup, arm all the EQs for event 1026 * generation. 1027 */ 1028 tavor_eq_arm_all(state); 1029 1030 TAVOR_TNF_EXIT(tavor_isr_init); 1031 return (DDI_SUCCESS); 1032 } 1033 1034 1035 /* 1036 * tavor_isr_fini() 1037 * Context: Only called from attach() and/or detach() path contexts 1038 */ 1039 static void 1040 tavor_isr_fini(tavor_state_t *state) 1041 { 1042 TAVOR_TNF_ENTER(tavor_isr_fini); 1043 1044 /* Disable the software interrupt */ 1045 if (state->ts_intrmsi_cap & DDI_INTR_FLAG_BLOCK) { 1046 (void) ddi_intr_block_disable(&state->ts_intrmsi_hdl, 1); 1047 } else { 1048 (void) ddi_intr_disable(state->ts_intrmsi_hdl); 1049 } 1050 1051 /* 1052 * Remove the software handler for the interrupt or MSI 1053 */ 1054 (void) ddi_intr_remove_handler(state->ts_intrmsi_hdl); 1055 1056 TAVOR_TNF_EXIT(tavor_isr_fini); 1057 } 1058 1059 1060 /* 1061 * tavor_fix_error_buf() 1062 * Context: Only called from attach(). 1063 * 1064 * The error_buf_addr returned from QUERY_FW is a PCI address. 1065 * We need to convert it to an offset from the base address, 1066 * which is stored in the assigned-addresses property. 1067 */ 1068 static int 1069 tavor_fix_error_buf(tavor_state_t *state) 1070 { 1071 int assigned_addr_len; 1072 pci_regspec_t *assigned_addr; 1073 1074 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, state->ts_dip, 1075 DDI_PROP_DONTPASS, "assigned-addresses", (int **)&assigned_addr, 1076 (uint_t *)&assigned_addr_len) != DDI_PROP_SUCCESS) 1077 return (DDI_FAILURE); 1078 1079 state->ts_fw.error_buf_addr -= assigned_addr[0].pci_phys_low + 1080 ((uint64_t)(assigned_addr[0].pci_phys_mid) << 32); 1081 ddi_prop_free(assigned_addr); 1082 return (DDI_SUCCESS); 1083 } 1084 1085 /* 1086 * tavor_hw_init() 1087 * Context: Only called from attach() path context 1088 */ 1089 static int 1090 tavor_hw_init(tavor_state_t *state) 1091 { 1092 tavor_drv_cleanup_level_t cleanup; 1093 sm_nodeinfo_t nodeinfo; 1094 uint64_t errorcode; 1095 off_t ddr_size; 1096 int status; 1097 int retries; 1098 1099 TAVOR_TNF_ENTER(tavor_hw_init); 1100 1101 /* This is where driver initialization begins */ 1102 cleanup = TAVOR_DRV_CLEANUP_LEVEL0; 1103 1104 /* Setup device access attributes */ 1105 state->ts_reg_accattr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1106 state->ts_reg_accattr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC; 1107 state->ts_reg_accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1108 1109 /* Setup for PCI config read/write of HCA device */ 1110 status = pci_config_setup(state->ts_dip, &state->ts_pci_cfghdl); 1111 if (status != DDI_SUCCESS) { 1112 tavor_hw_fini(state, cleanup); 1113 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1114 "hw_init_PCI_config_space_regmap_fail"); 1115 /* This case is not the degraded one */ 1116 return (DDI_FAILURE); 1117 } 1118 1119 /* Map in Tavor registers (CMD, UAR, DDR) and setup offsets */ 1120 status = ddi_regs_map_setup(state->ts_dip, TAVOR_CMD_BAR, 1121 &state->ts_reg_cmd_baseaddr, 0, 0, &state->ts_reg_accattr, 1122 &state->ts_reg_cmdhdl); 1123 if (status != DDI_SUCCESS) { 1124 tavor_hw_fini(state, cleanup); 1125 TNF_PROBE_0(tavor_hw_init_CMD_ddirms_fail, TAVOR_TNF_ERROR, ""); 1126 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1127 "hw_init_CMD_ddirms_fail"); 1128 TAVOR_TNF_EXIT(tavor_hw_init); 1129 return (DDI_FAILURE); 1130 } 1131 cleanup = TAVOR_DRV_CLEANUP_LEVEL1; 1132 1133 status = ddi_regs_map_setup(state->ts_dip, TAVOR_UAR_BAR, 1134 &state->ts_reg_uar_baseaddr, 0, 0, &state->ts_reg_accattr, 1135 &state->ts_reg_uarhdl); 1136 if (status != DDI_SUCCESS) { 1137 tavor_hw_fini(state, cleanup); 1138 TNF_PROBE_0(tavor_hw_init_UAR_ddirms_fail, TAVOR_TNF_ERROR, ""); 1139 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1140 "hw_init_UAR_ddirms_fail"); 1141 TAVOR_TNF_EXIT(tavor_hw_init); 1142 return (DDI_FAILURE); 1143 } 1144 cleanup = TAVOR_DRV_CLEANUP_LEVEL2; 1145 1146 status = ddi_dev_regsize(state->ts_dip, TAVOR_DDR_BAR, &ddr_size); 1147 if (status != DDI_SUCCESS) { 1148 cmn_err(CE_CONT, "Tavor: ddi_dev_regsize() failed " 1149 "(check HCA-attached DIMM memory?)\n"); 1150 tavor_hw_fini(state, cleanup); 1151 TNF_PROBE_0(tavor_hw_init_DDR_ddi_regsize_fail, 1152 TAVOR_TNF_ERROR, ""); 1153 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1154 "hw_init_DDR_ddi_regsize_fail"); 1155 TAVOR_TNF_EXIT(tavor_hw_init); 1156 return (DDI_FAILURE); 1157 } 1158 1159 #if !defined(_ELF64) && !defined(__sparc) 1160 /* 1161 * For 32 bit x86/x64 kernels, where there is limited kernel virtual 1162 * memory available, define a minimal memory footprint. This is 1163 * specified in order to not take up too much resources, thus starving 1164 * out others. Only specified if the HCA DIMM is equal to or greater 1165 * than 256MB. 1166 * 1167 * Note: x86/x64 install and safemode boot are both 32bit. 1168 */ 1169 ddr_size = TAVOR_DDR_SIZE_MIN; 1170 #endif /* !(_ELF64) && !(__sparc) */ 1171 1172 state->ts_cfg_profile_setting = ddr_size; 1173 1174 status = ddi_regs_map_setup(state->ts_dip, TAVOR_DDR_BAR, 1175 &state->ts_reg_ddr_baseaddr, 0, ddr_size, &state->ts_reg_accattr, 1176 &state->ts_reg_ddrhdl); 1177 1178 /* 1179 * On 32-bit platform testing (primarily x86), it was seen that the 1180 * ddi_regs_map_setup() call would fail because there wasn't enough 1181 * kernel virtual address space available to map in the entire 256MB 1182 * DDR. So we add this check in here, so that if the 256 (or other 1183 * larger value of DDR) map in fails, that we fallback to try the lower 1184 * size of 128MB. 1185 * 1186 * Note: If we only have 128MB of DDR in the system in the first place, 1187 * we don't try another ddi_regs_map_setup(), and just skip over this 1188 * check and return failures. 1189 */ 1190 if (status == DDI_ME_NORESOURCES && ddr_size > TAVOR_DDR_SIZE_128) { 1191 /* Try falling back to 128MB DDR mapping */ 1192 status = ddi_regs_map_setup(state->ts_dip, TAVOR_DDR_BAR, 1193 &state->ts_reg_ddr_baseaddr, 0, TAVOR_DDR_SIZE_128, 1194 &state->ts_reg_accattr, &state->ts_reg_ddrhdl); 1195 1196 /* 1197 * 128MB DDR mapping worked. 1198 * Set the updated config profile setting here. 1199 */ 1200 if (status == DDI_SUCCESS) { 1201 TNF_PROBE_0(tavor_hw_init_DDR_128mb_fallback_success, 1202 TAVOR_TNF_TRACE, ""); 1203 state->ts_cfg_profile_setting = TAVOR_DDR_SIZE_128; 1204 } 1205 } 1206 1207 if (status != DDI_SUCCESS) { 1208 if (status == DDI_ME_RNUMBER_RANGE) { 1209 cmn_err(CE_CONT, "Tavor: ddi_regs_map_setup() failed " 1210 "(check HCA-attached DIMM memory?)\n"); 1211 } 1212 tavor_hw_fini(state, cleanup); 1213 TNF_PROBE_0(tavor_hw_init_DDR_ddirms_fail, TAVOR_TNF_ERROR, ""); 1214 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1215 "hw_init_DDR_ddirms_fail"); 1216 TAVOR_TNF_EXIT(tavor_hw_init); 1217 return (DDI_FAILURE); 1218 } 1219 cleanup = TAVOR_DRV_CLEANUP_LEVEL3; 1220 1221 /* Setup Tavor Host Command Register (HCR) */ 1222 state->ts_cmd_regs.hcr = (tavor_hw_hcr_t *) 1223 ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_HCR_OFFSET); 1224 1225 /* Setup Tavor Event Cause Register (ecr and clr_ecr) */ 1226 state->ts_cmd_regs.ecr = (uint64_t *) 1227 ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_ECR_OFFSET); 1228 state->ts_cmd_regs.clr_ecr = (uint64_t *) 1229 ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_CLR_ECR_OFFSET); 1230 1231 /* Setup Tavor Software Reset register (sw_reset) */ 1232 state->ts_cmd_regs.sw_reset = (uint32_t *) 1233 ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_SW_RESET_OFFSET); 1234 1235 /* Setup Tavor Clear Interrupt register (clr_int) */ 1236 state->ts_cmd_regs.clr_int = (uint64_t *) 1237 ((uintptr_t)state->ts_reg_cmd_baseaddr + TAVOR_CMD_CLR_INT_OFFSET); 1238 1239 /* Initialize the Phase1 Tavor configuration profile */ 1240 status = tavor_cfg_profile_init_phase1(state); 1241 if (status != DDI_SUCCESS) { 1242 tavor_hw_fini(state, cleanup); 1243 TNF_PROBE_0(tavor_hw_init_cfginit_fail, TAVOR_TNF_ERROR, ""); 1244 TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_cfginit_fail"); 1245 TAVOR_TNF_EXIT(tavor_hw_init); 1246 return (DDI_FAILURE); 1247 } 1248 cleanup = TAVOR_DRV_CLEANUP_LEVEL4; 1249 1250 /* Do a software reset of the Tavor HW to ensure proper state */ 1251 status = tavor_sw_reset(state); 1252 if (status != TAVOR_CMD_SUCCESS) { 1253 tavor_hw_fini(state, cleanup); 1254 TNF_PROBE_0(tavor_hw_init_sw_reset_fail, TAVOR_TNF_ERROR, ""); 1255 TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_sw_reset_fail"); 1256 TAVOR_TNF_EXIT(tavor_hw_init); 1257 return (DDI_FAILURE); 1258 } 1259 1260 /* Post the SYS_EN command to start the hardware */ 1261 status = tavor_sys_en_cmd_post(state, TAVOR_CMD_SYS_EN_NORMAL, 1262 &errorcode, TAVOR_CMD_NOSLEEP_SPIN); 1263 if (status != TAVOR_CMD_SUCCESS) { 1264 if ((status == TAVOR_CMD_BAD_NVMEM) || 1265 (status == TAVOR_CMD_DDR_MEM_ERR)) { 1266 cmn_err(CE_CONT, "Tavor: SYS_EN command failed: 0x%x " 1267 "0x%" PRIx64 " (invalid firmware image?)\n", 1268 status, errorcode); 1269 } else { 1270 cmn_err(CE_CONT, "Tavor: SYS_EN command failed: 0x%x " 1271 "0x%" PRIx64 "\n", status, errorcode); 1272 } 1273 tavor_hw_fini(state, cleanup); 1274 TNF_PROBE_0(tavor_hw_init_sys_en_cmd_fail, 1275 TAVOR_TNF_ERROR, ""); 1276 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1277 "hw_init_sys_en_cmd_fail"); 1278 TAVOR_TNF_EXIT(tavor_hw_init); 1279 return (DDI_FAILURE); 1280 } 1281 cleanup = TAVOR_DRV_CLEANUP_LEVEL5; 1282 1283 /* First phase of init for Tavor configuration/resources */ 1284 status = tavor_rsrc_init_phase1(state); 1285 if (status != DDI_SUCCESS) { 1286 tavor_hw_fini(state, cleanup); 1287 TNF_PROBE_0(tavor_hw_init_rsrcinit1_fail, TAVOR_TNF_ERROR, ""); 1288 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1289 "hw_init_rsrcinit1_fail"); 1290 TAVOR_TNF_EXIT(tavor_hw_init); 1291 return (DDI_FAILURE); 1292 } 1293 cleanup = TAVOR_DRV_CLEANUP_LEVEL6; 1294 1295 /* Query the DDR properties (e.g. total DDR size) */ 1296 status = tavor_cmn_query_cmd_post(state, QUERY_DDR, 0, 1297 &state->ts_ddr, sizeof (tavor_hw_queryddr_t), 1298 TAVOR_CMD_NOSLEEP_SPIN); 1299 if (status != TAVOR_CMD_SUCCESS) { 1300 cmn_err(CE_CONT, "Tavor: QUERY_DDR command failed: %08x\n", 1301 status); 1302 tavor_hw_fini(state, cleanup); 1303 TNF_PROBE_0(tavor_hw_init_query_ddr_cmd_fail, 1304 TAVOR_TNF_ERROR, ""); 1305 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1306 "hw_init_query_ddr_cmd_fail"); 1307 TAVOR_TNF_EXIT(tavor_hw_init); 1308 return (DDI_FAILURE); 1309 } 1310 1311 /* Figure out how big the firmware image (in DDR) is */ 1312 status = tavor_cmn_query_cmd_post(state, QUERY_FW, 0, &state->ts_fw, 1313 sizeof (tavor_hw_queryfw_t), TAVOR_CMD_NOSLEEP_SPIN); 1314 if (status != TAVOR_CMD_SUCCESS) { 1315 cmn_err(CE_CONT, "Tavor: QUERY_FW command failed: %08x\n", 1316 status); 1317 tavor_hw_fini(state, cleanup); 1318 TNF_PROBE_0(tavor_hw_init_query_fw_cmd_fail, 1319 TAVOR_TNF_ERROR, ""); 1320 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1321 "hw_init_query_fw_cmd_fail"); 1322 TAVOR_TNF_EXIT(tavor_hw_init); 1323 return (DDI_FAILURE); 1324 } 1325 1326 if (tavor_fix_error_buf(state) != DDI_SUCCESS) { 1327 tavor_hw_fini(state, cleanup); 1328 TNF_PROBE_0(tavor_hw_init_fixerrorbuf_fail, 1329 TAVOR_TNF_ERROR, ""); 1330 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1331 "hw_init_fixerrorbuf_fail"); 1332 TAVOR_TNF_EXIT(tavor_hw_init); 1333 return (DDI_FAILURE); 1334 } 1335 1336 /* Validate that the FW version is appropriate */ 1337 status = tavor_fw_version_check(state); 1338 if (status != DDI_SUCCESS) { 1339 if (state->ts_operational_mode == TAVOR_HCA_MODE) { 1340 cmn_err(CE_CONT, "Unsupported Tavor FW version: " 1341 "expected: %04d.%04d.%04d, " 1342 "actual: %04d.%04d.%04d\n", 1343 TAVOR_FW_VER_MAJOR, 1344 TAVOR_FW_VER_MINOR, 1345 TAVOR_FW_VER_SUBMINOR, 1346 state->ts_fw.fw_rev_major, 1347 state->ts_fw.fw_rev_minor, 1348 state->ts_fw.fw_rev_subminor); 1349 } else if (state->ts_operational_mode == TAVOR_COMPAT_MODE) { 1350 cmn_err(CE_CONT, "Unsupported Tavor Compat FW version: " 1351 "expected: %04d.%04d.%04d, " 1352 "actual: %04d.%04d.%04d\n", 1353 TAVOR_COMPAT_FW_VER_MAJOR, 1354 TAVOR_COMPAT_FW_VER_MINOR, 1355 TAVOR_COMPAT_FW_VER_SUBMINOR, 1356 state->ts_fw.fw_rev_major, 1357 state->ts_fw.fw_rev_minor, 1358 state->ts_fw.fw_rev_subminor); 1359 } else { 1360 cmn_err(CE_CONT, "Unsupported FW version: " 1361 "%04d.%04d.%04d\n", 1362 state->ts_fw.fw_rev_major, 1363 state->ts_fw.fw_rev_minor, 1364 state->ts_fw.fw_rev_subminor); 1365 } 1366 tavor_hw_fini(state, cleanup); 1367 TNF_PROBE_0(tavor_hw_init_checkfwver_fail, 1368 TAVOR_TNF_ERROR, ""); 1369 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1370 "hw_init_checkfwver_fail"); 1371 TAVOR_TNF_EXIT(tavor_hw_init); 1372 return (DDI_FAILURE); 1373 } 1374 1375 drv_usecwait(10); 1376 retries = 1000; /* retry up to 1 second before giving up */ 1377 retry: 1378 /* Call MOD_STAT_CFG to setup SRQ support (or disable) */ 1379 status = tavor_mod_stat_cfg_cmd_post(state); 1380 if (status != DDI_SUCCESS) { 1381 if (retries > 0) { 1382 drv_usecwait(1000); 1383 retries--; 1384 goto retry; 1385 } 1386 cmn_err(CE_CONT, "Tavor: MOD_STAT_CFG command failed: %08x\n", 1387 status); 1388 tavor_hw_fini(state, cleanup); 1389 TNF_PROBE_0(tavor_hw_init_mod_stat_cfg_cmd_fail, 1390 TAVOR_TNF_ERROR, ""); 1391 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1392 "hw_init_mod_stat_cfg_cmd_fail"); 1393 TAVOR_TNF_EXIT(tavor_hw_init); 1394 return (DDI_FAILURE); 1395 } 1396 1397 /* Figure out Tavor device limits */ 1398 status = tavor_cmn_query_cmd_post(state, QUERY_DEV_LIM, 0, 1399 &state->ts_devlim, sizeof (tavor_hw_querydevlim_t), 1400 TAVOR_CMD_NOSLEEP_SPIN); 1401 if (status != TAVOR_CMD_SUCCESS) { 1402 cmn_err(CE_CONT, "Tavor: QUERY_DEV_LIM command failed: %08x\n", 1403 status); 1404 tavor_hw_fini(state, cleanup); 1405 TNF_PROBE_0(tavor_hw_init_query_devlim_cmd_fail, 1406 TAVOR_TNF_ERROR, ""); 1407 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1408 "hw_init_query_devlim_cmd_fail"); 1409 TAVOR_TNF_EXIT(tavor_hw_init); 1410 return (DDI_FAILURE); 1411 } 1412 1413 /* Initialize the Phase2 Tavor configuration profile */ 1414 status = tavor_cfg_profile_init_phase2(state); 1415 if (status != DDI_SUCCESS) { 1416 tavor_hw_fini(state, cleanup); 1417 TNF_PROBE_0(tavor_hw_init_cfginit2_fail, TAVOR_TNF_ERROR, ""); 1418 TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_cfginit2_fail"); 1419 TAVOR_TNF_EXIT(tavor_hw_init); 1420 return (DDI_FAILURE); 1421 } 1422 1423 /* Second phase of init for Tavor configuration/resources */ 1424 status = tavor_rsrc_init_phase2(state); 1425 if (status != DDI_SUCCESS) { 1426 tavor_hw_fini(state, cleanup); 1427 TNF_PROBE_0(tavor_hw_init_rsrcinit2_fail, TAVOR_TNF_ERROR, ""); 1428 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1429 "hw_init_rsrcinit2_fail"); 1430 TAVOR_TNF_EXIT(tavor_hw_init); 1431 return (DDI_FAILURE); 1432 } 1433 cleanup = TAVOR_DRV_CLEANUP_LEVEL7; 1434 1435 /* Miscellaneous query information */ 1436 status = tavor_cmn_query_cmd_post(state, QUERY_ADAPTER, 0, 1437 &state->ts_adapter, sizeof (tavor_hw_queryadapter_t), 1438 TAVOR_CMD_NOSLEEP_SPIN); 1439 if (status != TAVOR_CMD_SUCCESS) { 1440 cmn_err(CE_CONT, "Tavor: QUERY_ADAPTER command failed: %08x\n", 1441 status); 1442 tavor_hw_fini(state, cleanup); 1443 TNF_PROBE_0(tavor_hw_init_query_adapter_cmd_fail, 1444 TAVOR_TNF_ERROR, ""); 1445 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1446 "hw_init_query_adapter_cmd_fail"); 1447 TAVOR_TNF_EXIT(tavor_hw_init); 1448 return (DDI_FAILURE); 1449 } 1450 1451 /* Prepare configuration for Tavor INIT_HCA command */ 1452 tavor_hca_config_setup(state, &state->ts_hcaparams); 1453 1454 /* Post command to init Tavor HCA */ 1455 status = tavor_init_hca_cmd_post(state, &state->ts_hcaparams, 1456 TAVOR_CMD_NOSLEEP_SPIN); 1457 if (status != TAVOR_CMD_SUCCESS) { 1458 cmn_err(CE_CONT, "Tavor: INIT_HCA command failed: %08x\n", 1459 status); 1460 tavor_hw_fini(state, cleanup); 1461 TNF_PROBE_0(tavor_hw_init_init_hca_cmd_fail, 1462 TAVOR_TNF_ERROR, ""); 1463 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1464 "hw_init_init_hca_cmd_fail"); 1465 TAVOR_TNF_EXIT(tavor_hw_init); 1466 return (DDI_FAILURE); 1467 } 1468 cleanup = TAVOR_DRV_CLEANUP_LEVEL8; 1469 1470 /* Allocate protection domain (PD) for Tavor internal use */ 1471 status = tavor_pd_alloc(state, &state->ts_pdhdl_internal, TAVOR_SLEEP); 1472 if (status != DDI_SUCCESS) { 1473 tavor_hw_fini(state, cleanup); 1474 TNF_PROBE_0(tavor_hw_init_internal_pd_alloc_fail, 1475 TAVOR_TNF_ERROR, ""); 1476 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1477 "hw_init_internal_pd_alloc_fail"); 1478 TAVOR_TNF_EXIT(tavor_hw_init); 1479 return (DDI_FAILURE); 1480 } 1481 cleanup = TAVOR_DRV_CLEANUP_LEVEL9; 1482 1483 /* Setup Tavor internal UAR pages (0 and 1) */ 1484 status = tavor_internal_uarpgs_init(state); 1485 if (status != DDI_SUCCESS) { 1486 tavor_hw_fini(state, cleanup); 1487 TNF_PROBE_0(tavor_hw_init_internal_uarpgs_alloc_fail, 1488 TAVOR_TNF_ERROR, ""); 1489 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1490 "hw_init_internal_uarpgs_alloc_fail"); 1491 TAVOR_TNF_EXIT(tavor_hw_init); 1492 return (DDI_FAILURE); 1493 } 1494 cleanup = TAVOR_DRV_CLEANUP_LEVEL10; 1495 1496 /* Query and initialize the Tavor interrupt/MSI information */ 1497 status = tavor_intr_or_msi_init(state); 1498 if (status != DDI_SUCCESS) { 1499 tavor_hw_fini(state, cleanup); 1500 TNF_PROBE_0(tavor_intr_or_msi_init_fail, 1501 TAVOR_TNF_ERROR, ""); 1502 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1503 "intr_or_msi_init_fail"); 1504 TAVOR_TNF_EXIT(tavor_hw_init); 1505 return (DDI_FAILURE); 1506 } 1507 cleanup = TAVOR_DRV_CLEANUP_LEVEL11; 1508 1509 /* Setup all of the Tavor EQs */ 1510 status = tavor_eq_init_all(state); 1511 if (status != DDI_SUCCESS) { 1512 tavor_hw_fini(state, cleanup); 1513 TNF_PROBE_0(tavor_hw_init_eqinitall_fail, TAVOR_TNF_ERROR, ""); 1514 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1515 "hw_init_eqinitall_fail"); 1516 TAVOR_TNF_EXIT(tavor_hw_init); 1517 return (DDI_FAILURE); 1518 } 1519 cleanup = TAVOR_DRV_CLEANUP_LEVEL12; 1520 1521 /* Set aside contexts for QP0 and QP1 */ 1522 status = tavor_special_qp_contexts_reserve(state); 1523 if (status != DDI_SUCCESS) { 1524 tavor_hw_fini(state, cleanup); 1525 TNF_PROBE_0(tavor_hw_init_reserve_special_qp_fail, 1526 TAVOR_TNF_ERROR, ""); 1527 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1528 "hw_init_reserve_special_qp_fail"); 1529 TAVOR_TNF_EXIT(tavor_hw_init); 1530 return (DDI_FAILURE); 1531 } 1532 cleanup = TAVOR_DRV_CLEANUP_LEVEL13; 1533 1534 /* Initialize for multicast group handling */ 1535 status = tavor_mcg_init(state); 1536 if (status != DDI_SUCCESS) { 1537 tavor_hw_fini(state, cleanup); 1538 TNF_PROBE_0(tavor_hw_init_mcg_init_fail, TAVOR_TNF_ERROR, ""); 1539 TAVOR_ATTACH_MSG(state->ts_attach_buf, "hw_init_mcg_init_fail"); 1540 TAVOR_TNF_EXIT(tavor_hw_init); 1541 return (DDI_FAILURE); 1542 } 1543 cleanup = TAVOR_DRV_CLEANUP_LEVEL14; 1544 1545 /* Initialize the Tavor IB port(s) */ 1546 status = tavor_hca_port_init(state); 1547 if (status != DDI_SUCCESS) { 1548 tavor_hw_fini(state, cleanup); 1549 TNF_PROBE_0(tavor_hw_init_hca_port_init_fail, 1550 TAVOR_TNF_ERROR, ""); 1551 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1552 "hw_init_hca_port_init_fail"); 1553 TAVOR_TNF_EXIT(tavor_hw_init); 1554 return (DDI_FAILURE); 1555 } 1556 cleanup = TAVOR_DRV_CLEANUP_ALL; 1557 1558 /* Determine NodeGUID and SystemImageGUID */ 1559 status = tavor_getnodeinfo_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN, 1560 &nodeinfo); 1561 if (status != TAVOR_CMD_SUCCESS) { 1562 cmn_err(CE_CONT, "Tavor: GetNodeInfo command failed: %08x\n", 1563 status); 1564 tavor_hw_fini(state, cleanup); 1565 TNF_PROBE_0(tavor_hw_init_getnodeinfo_cmd_fail, 1566 TAVOR_TNF_ERROR, ""); 1567 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1568 "hw_init_getnodeinfo_cmd_fail"); 1569 TAVOR_TNF_EXIT(tavor_hw_init); 1570 return (DDI_FAILURE); 1571 } 1572 1573 /* 1574 * If the NodeGUID value was set in OBP properties, then we use that 1575 * value. But we still print a message if the value we queried from 1576 * firmware does not match this value. 1577 * 1578 * Otherwise if OBP value is not set then we use the value from 1579 * firmware unconditionally. 1580 */ 1581 if (state->ts_cfg_profile->cp_nodeguid) { 1582 state->ts_nodeguid = state->ts_cfg_profile->cp_nodeguid; 1583 } else { 1584 state->ts_nodeguid = nodeinfo.NodeGUID; 1585 } 1586 1587 if (state->ts_nodeguid != nodeinfo.NodeGUID) { 1588 cmn_err(CE_NOTE, "!NodeGUID value queried from firmware " 1589 "does not match value set by device property"); 1590 } 1591 1592 /* 1593 * If the SystemImageGUID value was set in OBP properties, then we use 1594 * that value. But we still print a message if the value we queried 1595 * from firmware does not match this value. 1596 * 1597 * Otherwise if OBP value is not set then we use the value from 1598 * firmware unconditionally. 1599 */ 1600 if (state->ts_cfg_profile->cp_sysimgguid) { 1601 state->ts_sysimgguid = state->ts_cfg_profile->cp_sysimgguid; 1602 } else { 1603 state->ts_sysimgguid = nodeinfo.SystemImageGUID; 1604 } 1605 1606 if (state->ts_sysimgguid != nodeinfo.SystemImageGUID) { 1607 cmn_err(CE_NOTE, "!SystemImageGUID value queried from firmware " 1608 "does not match value set by device property"); 1609 } 1610 1611 /* Get NodeDescription */ 1612 status = tavor_getnodedesc_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN, 1613 (sm_nodedesc_t *)&state->ts_nodedesc); 1614 if (status != TAVOR_CMD_SUCCESS) { 1615 cmn_err(CE_CONT, "Tavor: GetNodeDesc command failed: %08x\n", 1616 status); 1617 tavor_hw_fini(state, cleanup); 1618 TNF_PROBE_0(tavor_hw_init_getnodedesc_cmd_fail, 1619 TAVOR_TNF_ERROR, ""); 1620 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1621 "hw_init_getnodedesc_cmd_fail"); 1622 TAVOR_TNF_EXIT(tavor_hw_init); 1623 return (DDI_FAILURE); 1624 } 1625 1626 TAVOR_TNF_EXIT(tavor_hw_init); 1627 return (DDI_SUCCESS); 1628 } 1629 1630 1631 /* 1632 * tavor_hw_fini() 1633 * Context: Only called from attach() and/or detach() path contexts 1634 */ 1635 static void 1636 tavor_hw_fini(tavor_state_t *state, tavor_drv_cleanup_level_t cleanup) 1637 { 1638 uint_t num_ports; 1639 int status; 1640 1641 TAVOR_TNF_ENTER(tavor_hw_fini); 1642 1643 switch (cleanup) { 1644 /* 1645 * If we add more driver initialization steps that should be cleaned 1646 * up here, we need to ensure that TAVOR_DRV_CLEANUP_ALL is still the 1647 * first entry (i.e. corresponds to the last init step). 1648 */ 1649 case TAVOR_DRV_CLEANUP_ALL: 1650 /* Shutdown the Tavor IB port(s) */ 1651 num_ports = state->ts_cfg_profile->cp_num_ports; 1652 (void) tavor_hca_ports_shutdown(state, num_ports); 1653 /* FALLTHROUGH */ 1654 1655 case TAVOR_DRV_CLEANUP_LEVEL14: 1656 /* Teardown resources used for multicast group handling */ 1657 tavor_mcg_fini(state); 1658 /* FALLTHROUGH */ 1659 1660 case TAVOR_DRV_CLEANUP_LEVEL13: 1661 /* Unreserve the special QP contexts */ 1662 tavor_special_qp_contexts_unreserve(state); 1663 /* FALLTHROUGH */ 1664 1665 case TAVOR_DRV_CLEANUP_LEVEL12: 1666 /* 1667 * Attempt to teardown all event queues (EQ). If we fail 1668 * here then print a warning message and return. Something 1669 * (either in HW or SW) has gone seriously wrong. 1670 */ 1671 status = tavor_eq_fini_all(state); 1672 if (status != DDI_SUCCESS) { 1673 TAVOR_WARNING(state, "failed to teardown EQs"); 1674 TNF_PROBE_0(tavor_hw_fini_eqfiniall_fail, 1675 TAVOR_TNF_ERROR, ""); 1676 TAVOR_TNF_EXIT(tavor_hw_fini); 1677 return; 1678 } 1679 /* FALLTHROUGH */ 1680 1681 case TAVOR_DRV_CLEANUP_LEVEL11: 1682 status = tavor_intr_or_msi_fini(state); 1683 if (status != DDI_SUCCESS) { 1684 TAVOR_WARNING(state, "failed to free intr/MSI"); 1685 TNF_PROBE_0(tavor_hw_fini_intrmsifini_fail, 1686 TAVOR_TNF_ERROR, ""); 1687 TAVOR_TNF_EXIT(tavor_hw_fini); 1688 return; 1689 } 1690 /* FALLTHROUGH */ 1691 1692 case TAVOR_DRV_CLEANUP_LEVEL10: 1693 /* Free the resources for the Tavor internal UAR pages */ 1694 tavor_internal_uarpgs_fini(state); 1695 /* FALLTHROUGH */ 1696 1697 case TAVOR_DRV_CLEANUP_LEVEL9: 1698 /* 1699 * Free the PD that was used internally by Tavor software. If 1700 * we fail here then print a warning and return. Something 1701 * (probably software-related, but perhaps HW) has gone wrong. 1702 */ 1703 status = tavor_pd_free(state, &state->ts_pdhdl_internal); 1704 if (status != DDI_SUCCESS) { 1705 TAVOR_WARNING(state, "failed to free internal PD"); 1706 TNF_PROBE_0(tavor_hw_fini_internal_pd_free_fail, 1707 TAVOR_TNF_ERROR, ""); 1708 TAVOR_TNF_EXIT(tavor_hw_fini); 1709 return; 1710 } 1711 /* FALLTHROUGH */ 1712 1713 case TAVOR_DRV_CLEANUP_LEVEL8: 1714 /* 1715 * Post the CLOSE_HCA command to Tavor firmware. If we fail 1716 * here then print a warning and return. Something (either in 1717 * HW or SW) has gone seriously wrong. 1718 */ 1719 status = tavor_close_hca_cmd_post(state, 1720 TAVOR_CMD_NOSLEEP_SPIN); 1721 if (status != TAVOR_CMD_SUCCESS) { 1722 TAVOR_WARNING(state, "failed to shutdown HCA"); 1723 TNF_PROBE_0(tavor_hw_fini_closehcacmd_fail, 1724 TAVOR_TNF_ERROR, ""); 1725 TAVOR_TNF_EXIT(tavor_hw_fini); 1726 return; 1727 } 1728 /* FALLTHROUGH */ 1729 1730 case TAVOR_DRV_CLEANUP_LEVEL7: 1731 /* Cleanup all the phase2 resources first */ 1732 tavor_rsrc_fini(state, TAVOR_RSRC_CLEANUP_ALL); 1733 /* FALLTHROUGH */ 1734 1735 case TAVOR_DRV_CLEANUP_LEVEL6: 1736 /* Then cleanup the phase1 resources */ 1737 tavor_rsrc_fini(state, TAVOR_RSRC_CLEANUP_PHASE1_COMPLETE); 1738 /* FALLTHROUGH */ 1739 1740 case TAVOR_DRV_CLEANUP_LEVEL5: 1741 /* 1742 * Post the SYS_DIS command to Tavor firmware to shut 1743 * everything down again. If we fail here then print a 1744 * warning and return. Something (probably in HW, but maybe 1745 * in SW) has gone seriously wrong. 1746 */ 1747 status = tavor_sys_dis_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN); 1748 if (status != TAVOR_CMD_SUCCESS) { 1749 TAVOR_WARNING(state, "failed to shutdown hardware"); 1750 TNF_PROBE_0(tavor_hw_fini_sys_dis_fail, 1751 TAVOR_TNF_ERROR, ""); 1752 TAVOR_TNF_EXIT(tavor_hw_fini); 1753 return; 1754 } 1755 /* FALLTHROUGH */ 1756 1757 case TAVOR_DRV_CLEANUP_LEVEL4: 1758 /* Teardown any resources allocated for the config profile */ 1759 tavor_cfg_profile_fini(state); 1760 /* FALLTHROUGH */ 1761 1762 case TAVOR_DRV_CLEANUP_LEVEL3: 1763 ddi_regs_map_free(&state->ts_reg_ddrhdl); 1764 /* FALLTHROUGH */ 1765 1766 case TAVOR_DRV_CLEANUP_LEVEL2: 1767 ddi_regs_map_free(&state->ts_reg_uarhdl); 1768 /* FALLTHROUGH */ 1769 1770 case TAVOR_DRV_CLEANUP_LEVEL1: 1771 case TAVOR_DRV_CLEANUP_LEVEL0: 1772 /* 1773 * LEVEL1 and LEVEL0 resources are freed in 1774 * tavor_drv_fini2(). 1775 */ 1776 break; 1777 1778 default: 1779 TAVOR_WARNING(state, "unexpected driver cleanup level"); 1780 TNF_PROBE_0(tavor_hw_fini_default_fail, TAVOR_TNF_ERROR, ""); 1781 TAVOR_TNF_EXIT(tavor_hw_fini); 1782 return; 1783 } 1784 1785 TAVOR_TNF_EXIT(tavor_hw_fini); 1786 } 1787 1788 1789 /* 1790 * tavor_soft_state_init() 1791 * Context: Only called from attach() path context 1792 */ 1793 static int 1794 tavor_soft_state_init(tavor_state_t *state) 1795 { 1796 ibt_hca_attr_t *hca_attr; 1797 uint64_t maxval, val; 1798 ibt_hca_flags_t caps = IBT_HCA_NO_FLAGS; 1799 int status; 1800 1801 TAVOR_TNF_ENTER(tavor_soft_state_init); 1802 1803 /* 1804 * The ibc_hca_info_t struct is passed to the IBTF. This is the 1805 * routine where we initialize it. Many of the init values come from 1806 * either configuration variables or successful queries of the Tavor 1807 * hardware abilities 1808 */ 1809 state->ts_ibtfinfo.hca_ci_vers = IBCI_V4; 1810 state->ts_ibtfinfo.hca_handle = (ibc_hca_hdl_t)state; 1811 state->ts_ibtfinfo.hca_ops = &tavor_ibc_ops; 1812 1813 hca_attr = kmem_zalloc(sizeof (ibt_hca_attr_t), KM_SLEEP); 1814 state->ts_ibtfinfo.hca_attr = hca_attr; 1815 1816 hca_attr->hca_dip = state->ts_dip; 1817 hca_attr->hca_fw_major_version = state->ts_fw.fw_rev_major; 1818 hca_attr->hca_fw_minor_version = state->ts_fw.fw_rev_minor; 1819 hca_attr->hca_fw_micro_version = state->ts_fw.fw_rev_subminor; 1820 1821 /* 1822 * Determine HCA capabilities: 1823 * No default support for IBT_HCA_RD, IBT_HCA_RAW_MULTICAST, 1824 * IBT_HCA_ATOMICS_GLOBAL, IBT_HCA_RESIZE_CHAN, IBT_HCA_INIT_TYPE, 1825 * or IBT_HCA_SHUTDOWN_PORT 1826 * But IBT_HCA_AH_PORT_CHECK, IBT_HCA_SQD_RTS_PORT, IBT_HCA_SI_GUID, 1827 * IBT_HCA_RNR_NAK, and IBT_HCA_CURRENT_QP_STATE are always 1828 * supported 1829 * All other features are conditionally supported, depending on the 1830 * status return by the Tavor HCA (in QUERY_DEV_LIM) 1831 */ 1832 if (state->ts_devlim.ud_multi) { 1833 caps |= IBT_HCA_UD_MULTICAST; 1834 } 1835 if (state->ts_devlim.atomic) { 1836 caps |= IBT_HCA_ATOMICS_HCA; 1837 } 1838 if (state->ts_devlim.apm) { 1839 caps |= IBT_HCA_AUTO_PATH_MIG; 1840 } 1841 if (state->ts_devlim.pkey_v) { 1842 caps |= IBT_HCA_PKEY_CNTR; 1843 } 1844 if (state->ts_devlim.qkey_v) { 1845 caps |= IBT_HCA_QKEY_CNTR; 1846 } 1847 if (state->ts_cfg_profile->cp_srq_enable) { 1848 caps |= IBT_HCA_SRQ | IBT_HCA_RESIZE_SRQ; 1849 } 1850 caps |= (IBT_HCA_AH_PORT_CHECK | IBT_HCA_SQD_SQD_PORT | 1851 IBT_HCA_SI_GUID | IBT_HCA_RNR_NAK | IBT_HCA_CURRENT_QP_STATE | 1852 IBT_HCA_PORT_UP | IBT_HCA_SQD_STATE); 1853 hca_attr->hca_flags = caps; 1854 hca_attr->hca_flags2 = IBT_HCA2_DMA_MR; 1855 1856 /* Determine VendorID, DeviceID, and revision ID */ 1857 hca_attr->hca_vendor_id = state->ts_adapter.vendor_id; 1858 hca_attr->hca_device_id = state->ts_adapter.device_id; 1859 hca_attr->hca_version_id = state->ts_adapter.rev_id; 1860 1861 /* 1862 * Determine number of available QPs and max QP size. Number of 1863 * available QPs is determined by subtracting the number of 1864 * "reserved QPs" (i.e. reserved for firmware use) from the 1865 * total number configured. 1866 */ 1867 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_qp); 1868 hca_attr->hca_max_qp = val - ((uint64_t)1 << 1869 state->ts_devlim.log_rsvd_qp); 1870 maxval = ((uint64_t)1 << state->ts_devlim.log_max_qp_sz); 1871 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_qp_sz); 1872 if (val > maxval) { 1873 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 1874 TNF_PROBE_2(tavor_soft_state_init_maxqpsz_toobig_fail, 1875 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max QP size " 1876 "exceeds device maximum", tnf_uint, maxsz, maxval); 1877 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1878 "soft_state_init_maxqpsz_toobig_fail"); 1879 TAVOR_TNF_EXIT(tavor_soft_state_init); 1880 return (DDI_FAILURE); 1881 } 1882 hca_attr->hca_max_qp_sz = val; 1883 1884 /* Determine max scatter-gather size in WQEs */ 1885 maxval = state->ts_devlim.max_sg; 1886 val = state->ts_cfg_profile->cp_wqe_max_sgl; 1887 if (val > maxval) { 1888 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 1889 TNF_PROBE_2(tavor_soft_state_init_toomanysgl_fail, 1890 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of sgl " 1891 "exceeds device maximum", tnf_uint, maxsgl, maxval); 1892 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1893 "soft_state_init_toomanysgl_fail"); 1894 TAVOR_TNF_EXIT(tavor_soft_state_init); 1895 return (DDI_FAILURE); 1896 } 1897 /* If the rounded value for max SGL is too large, cap it */ 1898 if (state->ts_cfg_profile->cp_wqe_real_max_sgl > maxval) { 1899 state->ts_cfg_profile->cp_wqe_real_max_sgl = maxval; 1900 val = maxval; 1901 } else { 1902 val = state->ts_cfg_profile->cp_wqe_real_max_sgl; 1903 } 1904 1905 hca_attr->hca_max_sgl = val; 1906 hca_attr->hca_max_rd_sgl = 0; /* zero because RD is unsupported */ 1907 1908 /* 1909 * Determine number of available CQs and max CQ size. Number of 1910 * available CQs is determined by subtracting the number of 1911 * "reserved CQs" (i.e. reserved for firmware use) from the 1912 * total number configured. 1913 */ 1914 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_cq); 1915 hca_attr->hca_max_cq = val - ((uint64_t)1 << 1916 state->ts_devlim.log_rsvd_cq); 1917 maxval = ((uint64_t)1 << state->ts_devlim.log_max_cq_sz); 1918 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_cq_sz) - 1; 1919 if (val > maxval) { 1920 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 1921 TNF_PROBE_2(tavor_soft_state_init_maxcqsz_toobig_fail, 1922 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max CQ size " 1923 "exceeds device maximum", tnf_uint, maxsz, maxval); 1924 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1925 "soft_state_init_maxcqsz_toobig_fail"); 1926 TAVOR_TNF_EXIT(tavor_soft_state_init); 1927 return (DDI_FAILURE); 1928 } 1929 hca_attr->hca_max_cq_sz = val; 1930 1931 /* 1932 * Determine number of available SRQs and max SRQ size. Number of 1933 * available SRQs is determined by subtracting the number of 1934 * "reserved SRQs" (i.e. reserved for firmware use) from the 1935 * total number configured. 1936 */ 1937 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_srq); 1938 hca_attr->hca_max_srqs = val - ((uint64_t)1 << 1939 state->ts_devlim.log_rsvd_srq); 1940 maxval = ((uint64_t)1 << state->ts_devlim.log_max_srq_sz); 1941 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_srq_sz); 1942 1943 if (val > maxval) { 1944 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 1945 TNF_PROBE_2(tavor_soft_state_init_maxsrqsz_toobig_fail, 1946 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max SRQ size " 1947 "exceeds device maximum", tnf_uint, maxsz, maxval); 1948 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1949 "soft_state_init_maxsrqsz_toobig_fail"); 1950 TAVOR_TNF_EXIT(tavor_soft_state_init); 1951 return (DDI_FAILURE); 1952 } 1953 hca_attr->hca_max_srqs_sz = val; 1954 1955 val = state->ts_cfg_profile->cp_srq_max_sgl; 1956 maxval = state->ts_devlim.max_sg; 1957 if (val > maxval) { 1958 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 1959 TNF_PROBE_2(tavor_soft_state_init_toomanysrqsgl_fail, 1960 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of srq " 1961 "sgl exceeds device maximum", tnf_uint, maxsgl, maxval); 1962 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1963 "soft_state_init_toomanysrqsgl_fail"); 1964 TAVOR_TNF_EXIT(tavor_soft_state_init); 1965 return (DDI_FAILURE); 1966 } 1967 hca_attr->hca_max_srq_sgl = val; 1968 1969 /* 1970 * Determine supported HCA page sizes 1971 * XXX 1972 * For now we simply return the system pagesize as the only supported 1973 * pagesize 1974 */ 1975 hca_attr->hca_page_sz = ((PAGESIZE == (1 << 13)) ? IBT_PAGE_8K : 1976 IBT_PAGE_4K); 1977 1978 /* 1979 * Determine number of available MemReg, MemWin, and their max size. 1980 * Number of available MRs and MWs is determined by subtracting 1981 * the number of "reserved MPTs" (i.e. reserved for firmware use) 1982 * from the total number configured for each. 1983 */ 1984 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_mpt); 1985 hca_attr->hca_max_memr = val - ((uint64_t)1 << 1986 state->ts_devlim.log_rsvd_mpt); 1987 hca_attr->hca_max_mem_win = val - ((uint64_t)1 << 1988 state->ts_devlim.log_rsvd_mpt); 1989 maxval = state->ts_devlim.log_max_mrw_sz; 1990 val = state->ts_cfg_profile->cp_log_max_mrw_sz; 1991 if (val > maxval) { 1992 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 1993 TNF_PROBE_2(tavor_soft_state_init_maxmrwsz_toobig_fail, 1994 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max mrw size " 1995 "exceeds device maximum", tnf_uint, maxsz, maxval); 1996 TAVOR_ATTACH_MSG(state->ts_attach_buf, 1997 "soft_state_init_maxmrwsz_toobig_fail"); 1998 TAVOR_TNF_EXIT(tavor_soft_state_init); 1999 return (DDI_FAILURE); 2000 } 2001 hca_attr->hca_max_memr_len = ((uint64_t)1 << val); 2002 2003 /* Determine RDMA/Atomic properties */ 2004 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_rdb); 2005 hca_attr->hca_max_rsc = val; 2006 val = state->ts_cfg_profile->cp_hca_max_rdma_in_qp; 2007 hca_attr->hca_max_rdma_in_qp = val; 2008 val = state->ts_cfg_profile->cp_hca_max_rdma_out_qp; 2009 hca_attr->hca_max_rdma_out_qp = val; 2010 hca_attr->hca_max_rdma_in_ee = 0; 2011 hca_attr->hca_max_rdma_out_ee = 0; 2012 2013 /* 2014 * Determine maximum number of raw IPv6 and Ether QPs. Set to 0 2015 * because neither type of raw QP is supported 2016 */ 2017 hca_attr->hca_max_ipv6_qp = 0; 2018 hca_attr->hca_max_ether_qp = 0; 2019 2020 /* Determine max number of MCGs and max QP-per-MCG */ 2021 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_qp); 2022 hca_attr->hca_max_mcg_qps = val; 2023 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_mcg); 2024 hca_attr->hca_max_mcg = val; 2025 val = state->ts_cfg_profile->cp_num_qp_per_mcg; 2026 hca_attr->hca_max_qp_per_mcg = val; 2027 2028 /* Determine max number partitions (i.e. PKeys) */ 2029 maxval = ((uint64_t)1 << state->ts_devlim.log_max_pkey); 2030 val = ((uint64_t)state->ts_cfg_profile->cp_num_ports << 2031 state->ts_cfg_profile->cp_log_max_pkeytbl); 2032 2033 if (val > maxval) { 2034 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 2035 TNF_PROBE_2(tavor_soft_state_init_toomanypkey_fail, 2036 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of PKeys " 2037 "exceeds device maximum", tnf_uint, maxpkey, maxval); 2038 TAVOR_ATTACH_MSG(state->ts_attach_buf, 2039 "soft_state_init_toomanypkey_fail"); 2040 TAVOR_TNF_EXIT(tavor_soft_state_init); 2041 return (DDI_FAILURE); 2042 } 2043 hca_attr->hca_max_partitions = val; 2044 2045 /* Determine number of ports */ 2046 maxval = state->ts_devlim.num_ports; 2047 val = state->ts_cfg_profile->cp_num_ports; 2048 if ((val > maxval) || (val == 0)) { 2049 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 2050 TNF_PROBE_2(tavor_soft_state_init_toomanyports_fail, 2051 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of ports " 2052 "exceeds device maximum", tnf_uint, maxports, maxval); 2053 TAVOR_ATTACH_MSG(state->ts_attach_buf, 2054 "soft_state_init_toomanyports_fail"); 2055 TAVOR_TNF_EXIT(tavor_soft_state_init); 2056 return (DDI_FAILURE); 2057 } 2058 hca_attr->hca_nports = val; 2059 2060 /* Copy NodeGUID and SystemImageGUID from softstate */ 2061 hca_attr->hca_node_guid = state->ts_nodeguid; 2062 hca_attr->hca_si_guid = state->ts_sysimgguid; 2063 2064 /* 2065 * Determine local ACK delay. Use the value suggested by the Tavor 2066 * hardware (from the QUERY_DEV_LIM command) 2067 */ 2068 hca_attr->hca_local_ack_delay = state->ts_devlim.ca_ack_delay; 2069 2070 /* Determine max SGID table and PKey table sizes */ 2071 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_gidtbl); 2072 hca_attr->hca_max_port_sgid_tbl_sz = val; 2073 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_max_pkeytbl); 2074 hca_attr->hca_max_port_pkey_tbl_sz = val; 2075 2076 /* Determine max number of PDs */ 2077 maxval = ((uint64_t)1 << state->ts_devlim.log_max_pd); 2078 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_pd); 2079 if (val > maxval) { 2080 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 2081 TNF_PROBE_2(tavor_soft_state_init_toomanypd_fail, 2082 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of PD " 2083 "exceeds device maximum", tnf_uint, maxpd, maxval); 2084 TAVOR_ATTACH_MSG(state->ts_attach_buf, 2085 "soft_state_init_toomanypd_fail"); 2086 TAVOR_TNF_EXIT(tavor_soft_state_init); 2087 return (DDI_FAILURE); 2088 } 2089 hca_attr->hca_max_pd = val; 2090 2091 /* Determine max number of Address Handles */ 2092 maxval = ((uint64_t)1 << state->ts_devlim.log_max_av); 2093 val = ((uint64_t)1 << state->ts_cfg_profile->cp_log_num_ah); 2094 if (val > maxval) { 2095 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 2096 TNF_PROBE_2(tavor_soft_state_init_toomanyah_fail, 2097 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "number of AH " 2098 "exceeds device maximum", tnf_uint, maxah, maxval); 2099 TAVOR_ATTACH_MSG(state->ts_attach_buf, 2100 "soft_state_init_toomanyah_fail"); 2101 TAVOR_TNF_EXIT(tavor_soft_state_init); 2102 return (DDI_FAILURE); 2103 } 2104 hca_attr->hca_max_ah = val; 2105 2106 /* No RDDs or EECs (since Reliable Datagram is not supported) */ 2107 hca_attr->hca_max_rdd = 0; 2108 hca_attr->hca_max_eec = 0; 2109 2110 /* Initialize lock for reserved UAR page access */ 2111 mutex_init(&state->ts_uar_lock, NULL, MUTEX_DRIVER, 2112 DDI_INTR_PRI(state->ts_intrmsi_pri)); 2113 2114 /* Initialize the flash fields */ 2115 state->ts_fw_flashstarted = 0; 2116 mutex_init(&state->ts_fw_flashlock, NULL, MUTEX_DRIVER, 2117 DDI_INTR_PRI(state->ts_intrmsi_pri)); 2118 2119 /* Initialize the lock for the info ioctl */ 2120 mutex_init(&state->ts_info_lock, NULL, MUTEX_DRIVER, 2121 DDI_INTR_PRI(state->ts_intrmsi_pri)); 2122 2123 /* Initialize the AVL tree for QP number support */ 2124 tavor_qpn_avl_init(state); 2125 2126 /* Initialize the kstat info structure */ 2127 status = tavor_kstat_init(state); 2128 if (status != DDI_SUCCESS) { 2129 tavor_qpn_avl_fini(state); 2130 mutex_destroy(&state->ts_info_lock); 2131 mutex_destroy(&state->ts_fw_flashlock); 2132 mutex_destroy(&state->ts_uar_lock); 2133 kmem_free(hca_attr, sizeof (ibt_hca_attr_t)); 2134 TNF_PROBE_0(tavor_soft_state_init_kstatinit_fail, 2135 TAVOR_TNF_ERROR, ""); 2136 TAVOR_ATTACH_MSG(state->ts_attach_buf, 2137 "soft_state_init_kstatinit_fail"); 2138 TAVOR_TNF_EXIT(tavor_soft_state_init); 2139 return (DDI_FAILURE); 2140 } 2141 2142 TAVOR_TNF_EXIT(tavor_soft_state_init); 2143 return (DDI_SUCCESS); 2144 } 2145 2146 2147 /* 2148 * tavor_soft_state_fini() 2149 * Context: Called only from detach() path context 2150 */ 2151 static void 2152 tavor_soft_state_fini(tavor_state_t *state) 2153 { 2154 TAVOR_TNF_ENTER(tavor_soft_state_fini); 2155 2156 /* Teardown the kstat info */ 2157 tavor_kstat_fini(state); 2158 2159 /* Teardown the AVL tree for QP number support */ 2160 tavor_qpn_avl_fini(state); 2161 2162 /* Free up info ioctl mutex */ 2163 mutex_destroy(&state->ts_info_lock); 2164 2165 /* Free up flash mutex */ 2166 mutex_destroy(&state->ts_fw_flashlock); 2167 2168 /* Free up the UAR page access mutex */ 2169 mutex_destroy(&state->ts_uar_lock); 2170 2171 /* Free up the hca_attr struct */ 2172 kmem_free(state->ts_ibtfinfo.hca_attr, sizeof (ibt_hca_attr_t)); 2173 2174 TAVOR_TNF_EXIT(tavor_soft_state_fini); 2175 } 2176 2177 2178 /* 2179 * tavor_hca_config_setup() 2180 * Context: Only called from attach() path context 2181 */ 2182 static void 2183 tavor_hca_config_setup(tavor_state_t *state, 2184 tavor_hw_initqueryhca_t *inithca) 2185 { 2186 tavor_rsrc_pool_info_t *rsrc_pool; 2187 uint64_t ddr_baseaddr, ddr_base_map_addr; 2188 uint64_t offset, addr; 2189 uint_t mcg_size; 2190 2191 TAVOR_TNF_ENTER(tavor_hca_config_setup); 2192 2193 /* Set "host endianness". Default is big endian */ 2194 #ifdef _LITTLE_ENDIAN 2195 inithca->big_endian = 0; 2196 #else 2197 inithca->big_endian = 1; 2198 #endif 2199 /* No Address Vector Protection, but Port Checking on by default */ 2200 inithca->udav_chk = TAVOR_UDAV_PROTECT_DISABLED; 2201 inithca->udav_port_chk = TAVOR_UDAV_PORTCHK_ENABLED; 2202 2203 ddr_baseaddr = (uint64_t)(uintptr_t)state->ts_reg_ddr_baseaddr; 2204 ddr_base_map_addr = (uint64_t)state->ts_ddr.ddr_baseaddr; 2205 2206 /* Setup QPC table */ 2207 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_QPC]; 2208 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2209 addr = ddr_base_map_addr + offset; 2210 inithca->context.qpc_baseaddr_h = (addr >> 32); 2211 inithca->context.qpc_baseaddr_l = (addr & 0xFFFFFFFF) >> 7; 2212 inithca->context.log_num_qp = state->ts_cfg_profile->cp_log_num_qp; 2213 2214 /* Setup EEC table (initialize to zero - RD unsupported) */ 2215 inithca->context.eec_baseaddr_h = 0; 2216 inithca->context.eec_baseaddr_l = 0; 2217 inithca->context.log_num_ee = 0; 2218 2219 /* Setup CQC table */ 2220 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_CQC]; 2221 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2222 addr = ddr_base_map_addr + offset; 2223 inithca->context.cqc_baseaddr_h = (addr >> 32); 2224 inithca->context.cqc_baseaddr_l = (addr & 0xFFFFFFFF) >> 6; 2225 inithca->context.log_num_cq = state->ts_cfg_profile->cp_log_num_cq; 2226 2227 /* Setup SRQC table */ 2228 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_SRQC]; 2229 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2230 addr = ddr_base_map_addr + offset; 2231 inithca->context.srqc_baseaddr_h = (addr >> 32); 2232 inithca->context.srqc_baseaddr_l = (addr & 0xFFFFFFFF) >> 6; 2233 inithca->context.log_num_srq = 2234 state->ts_cfg_profile->cp_log_num_srq; 2235 2236 /* Setup EQPC table */ 2237 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_EQPC]; 2238 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2239 addr = ddr_base_map_addr + offset; 2240 inithca->context.eqpc_baseaddr = addr; 2241 2242 /* Setup EEEC table (initialize to zero - RD unsupported) */ 2243 inithca->context.eeec_baseaddr = 0; 2244 2245 /* Setup EQC table */ 2246 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_EQC]; 2247 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2248 addr = ddr_base_map_addr + offset; 2249 inithca->context.eqc_baseaddr_h = (addr >> 32); 2250 inithca->context.eqc_baseaddr_l = (addr & 0xFFFFFFFF) >> 6; 2251 inithca->context.log_num_eq = TAVOR_NUM_EQ_SHIFT; 2252 2253 /* Setup RDB table */ 2254 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_RDB]; 2255 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2256 addr = ddr_base_map_addr + offset; 2257 inithca->context.rdb_baseaddr_h = (addr >> 32); 2258 inithca->context.rdb_baseaddr_l = 0; 2259 2260 /* Setup Multicast */ 2261 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MCG]; 2262 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2263 addr = ddr_base_map_addr + offset; 2264 inithca->multi.mc_baseaddr = addr; 2265 mcg_size = TAVOR_MCGMEM_SZ(state); 2266 inithca->multi.log_mc_tbl_ent = highbit(mcg_size) - 1; 2267 inithca->multi.mc_tbl_hash_sz = 2268 (1 << state->ts_cfg_profile->cp_log_num_mcg_hash); 2269 inithca->multi.mc_hash_fn = TAVOR_MCG_DEFAULT_HASH_FN; 2270 inithca->multi.log_mc_tbl_sz = state->ts_cfg_profile->cp_log_num_mcg; 2271 2272 2273 /* Setup TPT */ 2274 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MPT]; 2275 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2276 addr = ddr_base_map_addr + offset; 2277 inithca->tpt.mpt_baseaddr = addr; 2278 inithca->tpt.mttseg_sz = TAVOR_MTTSEG_SIZE_SHIFT; 2279 inithca->tpt.log_mpt_sz = state->ts_cfg_profile->cp_log_num_mpt; 2280 inithca->tpt.mtt_version = TAVOR_MTT_PG_WALK_VER; 2281 2282 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MTT]; 2283 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2284 addr = ddr_base_map_addr + offset; 2285 inithca->tpt.mtt_baseaddr = addr; 2286 2287 /* Setup UAR */ 2288 rsrc_pool = &state->ts_rsrc_hdl[TAVOR_UAR_SCR]; 2289 offset = (uint64_t)(uintptr_t)rsrc_pool->rsrc_start - ddr_baseaddr; 2290 addr = ddr_base_map_addr + offset; 2291 inithca->uar.uarscr_baseaddr = addr; 2292 2293 inithca->uar.uar_pg_sz = PAGESHIFT - 0xC; 2294 2295 TAVOR_TNF_EXIT(tavor_hca_config_setup); 2296 } 2297 2298 2299 /* 2300 * tavor_hca_port_init() 2301 * Context: Only called from attach() path context 2302 */ 2303 static int 2304 tavor_hca_port_init(tavor_state_t *state) 2305 { 2306 tavor_hw_initib_t *portinits, *initib; 2307 tavor_cfg_profile_t *cfgprof; 2308 uint_t num_ports; 2309 int i, status; 2310 uint64_t maxval, val; 2311 uint64_t sysimgguid, nodeguid, portguid; 2312 2313 TAVOR_TNF_ENTER(tavor_hca_port_init); 2314 2315 cfgprof = state->ts_cfg_profile; 2316 2317 /* Get number of HCA ports */ 2318 num_ports = cfgprof->cp_num_ports; 2319 2320 /* Allocate space for Tavor port init struct(s) */ 2321 portinits = (tavor_hw_initib_t *)kmem_zalloc(num_ports * 2322 sizeof (tavor_hw_initib_t), KM_SLEEP); 2323 2324 /* Post command to initialize Tavor HCA port */ 2325 for (i = 0; i < num_ports; i++) { 2326 initib = &portinits[i]; 2327 2328 /* 2329 * Determine whether we need to override the firmware's 2330 * default SystemImageGUID setting. 2331 */ 2332 sysimgguid = cfgprof->cp_sysimgguid; 2333 if (sysimgguid != 0) { 2334 initib->set_sysimg_guid = 1; 2335 initib->sysimg_guid = sysimgguid; 2336 } 2337 2338 /* 2339 * Determine whether we need to override the firmware's 2340 * default NodeGUID setting. 2341 */ 2342 nodeguid = cfgprof->cp_nodeguid; 2343 if (nodeguid != 0) { 2344 initib->set_node_guid = 1; 2345 initib->node_guid = nodeguid; 2346 } 2347 2348 /* 2349 * Determine whether we need to override the firmware's 2350 * default PortGUID setting. 2351 */ 2352 portguid = cfgprof->cp_portguid[i]; 2353 if (portguid != 0) { 2354 initib->set_port_guid0 = 1; 2355 initib->guid0 = portguid; 2356 } 2357 2358 /* Validate max MTU size */ 2359 maxval = state->ts_devlim.max_mtu; 2360 val = cfgprof->cp_max_mtu; 2361 if (val > maxval) { 2362 TNF_PROBE_2(tavor_hca_port_init_maxmtu_fail, 2363 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max " 2364 "MTU size exceeds device maximum", tnf_uint, 2365 maxmtu, maxval); 2366 TAVOR_TNF_EXIT(tavor_hca_port_init); 2367 goto init_ports_fail; 2368 } 2369 initib->mtu_cap = val; 2370 2371 /* Validate the max port width */ 2372 maxval = state->ts_devlim.max_port_width; 2373 val = cfgprof->cp_max_port_width; 2374 if (val > maxval) { 2375 TNF_PROBE_2(tavor_hca_port_init_maxportwidth_fail, 2376 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max " 2377 "port width exceeds device maximum", tnf_uint, 2378 maxportwidth, maxval); 2379 TAVOR_TNF_EXIT(tavor_hca_port_init); 2380 goto init_ports_fail; 2381 } 2382 initib->port_width_cap = val; 2383 2384 /* Validate max VL cap size */ 2385 maxval = state->ts_devlim.max_vl; 2386 val = cfgprof->cp_max_vlcap; 2387 if (val > maxval) { 2388 TNF_PROBE_2(tavor_hca_port_init_maxvlcap_fail, 2389 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max " 2390 "VLcap size exceeds device maximum", tnf_uint, 2391 maxvlcap, maxval); 2392 TAVOR_TNF_EXIT(tavor_hca_port_init); 2393 goto init_ports_fail; 2394 } 2395 initib->vl_cap = val; 2396 2397 /* Validate max GID table size */ 2398 maxval = ((uint64_t)1 << state->ts_devlim.log_max_gid); 2399 val = ((uint64_t)1 << cfgprof->cp_log_max_gidtbl); 2400 if (val > maxval) { 2401 TNF_PROBE_2(tavor_hca_port_init_gidtable_fail, 2402 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max " 2403 "GID table size exceeds device maximum", tnf_uint, 2404 maxgidtbl, maxval); 2405 TAVOR_TNF_EXIT(tavor_hca_port_init); 2406 goto init_ports_fail; 2407 } 2408 initib->max_gid = val; 2409 2410 /* Validate max PKey table size */ 2411 maxval = ((uint64_t)1 << state->ts_devlim.log_max_pkey); 2412 val = ((uint64_t)1 << cfgprof->cp_log_max_pkeytbl); 2413 if (val > maxval) { 2414 TNF_PROBE_2(tavor_hca_port_init_pkeytable_fail, 2415 TAVOR_TNF_ERROR, "", tnf_string, errmsg, "max " 2416 "PKey table size exceeds device maximum", tnf_uint, 2417 maxpkeytbl, maxval); 2418 TAVOR_TNF_EXIT(tavor_hca_port_init); 2419 goto init_ports_fail; 2420 } 2421 initib->max_pkey = val; 2422 2423 /* 2424 * Post the INIT_IB command to Tavor firmware. When this 2425 * command completes, the corresponding Tavor port will be 2426 * physically "Up" and initialized. 2427 */ 2428 status = tavor_init_ib_cmd_post(state, initib, i + 1, 2429 TAVOR_CMD_NOSLEEP_SPIN); 2430 if (status != TAVOR_CMD_SUCCESS) { 2431 cmn_err(CE_CONT, "Tavor: INIT_IB (port %02d) command " 2432 "failed: %08x\n", i + 1, status); 2433 TNF_PROBE_2(tavor_hca_port_init_init_ib_cmd_fail, 2434 TAVOR_TNF_ERROR, "", tnf_uint, cmd_status, status, 2435 tnf_uint, port, i + 1); 2436 TAVOR_TNF_EXIT(tavor_hca_port_init); 2437 goto init_ports_fail; 2438 } 2439 } 2440 2441 /* Free up the memory for Tavor port init struct(s), return success */ 2442 kmem_free(portinits, num_ports * sizeof (tavor_hw_initib_t)); 2443 TAVOR_TNF_EXIT(tavor_hca_port_init); 2444 return (DDI_SUCCESS); 2445 2446 init_ports_fail: 2447 /* 2448 * Free up the memory for Tavor port init struct(s), shutdown any 2449 * successfully initialized ports, and return failure 2450 */ 2451 kmem_free(portinits, num_ports * sizeof (tavor_hw_initib_t)); 2452 (void) tavor_hca_ports_shutdown(state, i); 2453 2454 TAVOR_TNF_EXIT(tavor_hca_port_init); 2455 return (DDI_FAILURE); 2456 } 2457 2458 2459 /* 2460 * tavor_hca_ports_shutdown() 2461 * Context: Only called from attach() and/or detach() path contexts 2462 */ 2463 static int 2464 tavor_hca_ports_shutdown(tavor_state_t *state, uint_t num_init) 2465 { 2466 int i, status; 2467 2468 TAVOR_TNF_ENTER(tavor_hca_ports_shutdown); 2469 2470 /* 2471 * Post commands to shutdown all init'd Tavor HCA ports. Note: if 2472 * any of these commands fail for any reason, it would be entirely 2473 * unexpected and probably indicative a serious problem (HW or SW). 2474 * Although we do return void from this function, this type of failure 2475 * should not go unreported. That is why we have the warning message 2476 * and the detailed TNF information. 2477 */ 2478 for (i = 0; i < num_init; i++) { 2479 status = tavor_close_ib_cmd_post(state, i + 1, 2480 TAVOR_CMD_NOSLEEP_SPIN); 2481 if (status != TAVOR_CMD_SUCCESS) { 2482 TAVOR_WARNING(state, "failed to shutdown HCA port"); 2483 TNF_PROBE_2(tavor_hca_ports_shutdown_close_ib_cmd_fail, 2484 TAVOR_TNF_ERROR, "", tnf_uint, cmd_status, status, 2485 tnf_uint, port, i + 1); 2486 TAVOR_TNF_EXIT(tavor_hca_ports_shutdown); 2487 return (status); 2488 } 2489 } 2490 2491 TAVOR_TNF_EXIT(tavor_hca_ports_shutdown); 2492 2493 return (TAVOR_CMD_SUCCESS); 2494 } 2495 2496 2497 /* 2498 * tavor_internal_uarpgs_init 2499 * Context: Only called from attach() path context 2500 */ 2501 static int 2502 tavor_internal_uarpgs_init(tavor_state_t *state) 2503 { 2504 int status; 2505 2506 TAVOR_TNF_ENTER(tavor_internal_uarpgs_init); 2507 2508 /* 2509 * Save away reserved Tavor UAR page #0. This UAR page is not to 2510 * be used by software. 2511 */ 2512 status = tavor_rsrc_alloc(state, TAVOR_UARPG, 1, TAVOR_SLEEP, 2513 &state->ts_uarpg0_rsrc_rsrvd); 2514 if (status != DDI_SUCCESS) { 2515 TNF_PROBE_0(tavor_uarpg0_rsrcalloc_fail, TAVOR_TNF_ERROR, ""); 2516 TAVOR_TNF_EXIT(tavor_internal_uarpgs_init); 2517 return (DDI_FAILURE); 2518 } 2519 2520 /* 2521 * Save away Tavor UAR page #1 (for internal use). This UAR page is 2522 * the privileged UAR page through which all kernel generated 2523 * doorbells will be rung. 2524 */ 2525 status = tavor_rsrc_alloc(state, TAVOR_UARPG, 1, TAVOR_SLEEP, 2526 &state->ts_uarpg1_rsrc); 2527 if (status != DDI_SUCCESS) { 2528 tavor_rsrc_free(state, &state->ts_uarpg0_rsrc_rsrvd); 2529 TNF_PROBE_0(tavor_uarpg1_rsrcalloc_fail, TAVOR_TNF_ERROR, ""); 2530 TAVOR_TNF_EXIT(tavor_internal_uarpgs_init); 2531 return (DDI_FAILURE); 2532 } 2533 2534 /* Setup pointer to UAR page #1 doorbells */ 2535 state->ts_uar = (tavor_hw_uar_t *)state->ts_uarpg1_rsrc->tr_addr; 2536 2537 TAVOR_TNF_EXIT(tavor_internal_uarpgs_init); 2538 return (DDI_SUCCESS); 2539 } 2540 2541 2542 /* 2543 * tavor_internal_uarpgs_fini 2544 * Context: Only called from attach() and/or detach() path contexts 2545 */ 2546 static void 2547 tavor_internal_uarpgs_fini(tavor_state_t *state) 2548 { 2549 TAVOR_TNF_ENTER(tavor_internal_uarpgs_fini); 2550 2551 /* Free up Tavor UAR page #1 (kernel driver doorbells) */ 2552 tavor_rsrc_free(state, &state->ts_uarpg1_rsrc); 2553 2554 /* Free up Tavor UAR page #0 (reserved) */ 2555 tavor_rsrc_free(state, &state->ts_uarpg0_rsrc_rsrvd); 2556 2557 TAVOR_TNF_EXIT(tavor_internal_uarpgs_fini); 2558 } 2559 2560 2561 /* 2562 * tavor_special_qp_contexts_reserve() 2563 * Context: Only called from attach() path context 2564 */ 2565 static int 2566 tavor_special_qp_contexts_reserve(tavor_state_t *state) 2567 { 2568 tavor_rsrc_t *qp0_rsrc, *qp1_rsrc; 2569 int status; 2570 2571 TAVOR_TNF_ENTER(tavor_special_qp_contexts_reserve); 2572 2573 /* Initialize the lock used for special QP rsrc management */ 2574 mutex_init(&state->ts_spec_qplock, NULL, MUTEX_DRIVER, 2575 DDI_INTR_PRI(state->ts_intrmsi_pri)); 2576 2577 /* 2578 * Reserve contexts for QP0. These QP contexts will be setup to 2579 * act as aliases for the real QP0. Note: We are required to grab 2580 * two QPs (one per port) even if we are operating in single-port 2581 * mode. 2582 */ 2583 status = tavor_rsrc_alloc(state, TAVOR_QPC, 2, TAVOR_SLEEP, &qp0_rsrc); 2584 if (status != DDI_SUCCESS) { 2585 mutex_destroy(&state->ts_spec_qplock); 2586 TNF_PROBE_0(tavor_special_qp_contexts_reserve_qp0_fail, 2587 TAVOR_TNF_ERROR, ""); 2588 TAVOR_TNF_EXIT(tavor_special_qp_contexts_reserve); 2589 return (DDI_FAILURE); 2590 } 2591 state->ts_spec_qp0 = qp0_rsrc; 2592 2593 /* 2594 * Reserve contexts for QP1. These QP contexts will be setup to 2595 * act as aliases for the real QP1. Note: We are required to grab 2596 * two QPs (one per port) even if we are operating in single-port 2597 * mode. 2598 */ 2599 status = tavor_rsrc_alloc(state, TAVOR_QPC, 2, TAVOR_SLEEP, &qp1_rsrc); 2600 if (status != DDI_SUCCESS) { 2601 tavor_rsrc_free(state, &qp0_rsrc); 2602 mutex_destroy(&state->ts_spec_qplock); 2603 TNF_PROBE_0(tavor_special_qp_contexts_reserve_qp1_fail, 2604 TAVOR_TNF_ERROR, ""); 2605 TAVOR_TNF_EXIT(tavor_special_qp_contexts_reserve); 2606 return (DDI_FAILURE); 2607 } 2608 state->ts_spec_qp1 = qp1_rsrc; 2609 2610 TAVOR_TNF_EXIT(tavor_special_qp_contexts_reserve); 2611 return (DDI_SUCCESS); 2612 } 2613 2614 2615 /* 2616 * tavor_special_qp_contexts_unreserve() 2617 * Context: Only called from attach() and/or detach() path contexts 2618 */ 2619 static void 2620 tavor_special_qp_contexts_unreserve(tavor_state_t *state) 2621 { 2622 TAVOR_TNF_ENTER(tavor_special_qp_contexts_unreserve); 2623 2624 /* Unreserve contexts for QP1 */ 2625 tavor_rsrc_free(state, &state->ts_spec_qp1); 2626 2627 /* Unreserve contexts for QP0 */ 2628 tavor_rsrc_free(state, &state->ts_spec_qp0); 2629 2630 /* Destroy the lock used for special QP rsrc management */ 2631 mutex_destroy(&state->ts_spec_qplock); 2632 2633 TAVOR_TNF_EXIT(tavor_special_qp_contexts_unreserve); 2634 } 2635 2636 2637 /* 2638 * tavor_sw_reset() 2639 * Context: Currently called only from attach() path context 2640 */ 2641 static int 2642 tavor_sw_reset(tavor_state_t *state) 2643 { 2644 dev_info_t *dip, *pdip; 2645 ddi_acc_handle_t hdl = state->ts_pci_cfghdl, phdl; 2646 uint32_t reset_delay; 2647 int status, i; 2648 2649 TAVOR_TNF_ENTER(tavor_sw_reset); 2650 2651 /* 2652 * If the configured software reset delay is set to zero, then we 2653 * will not attempt a software reset of the Tavor device. 2654 */ 2655 reset_delay = state->ts_cfg_profile->cp_sw_reset_delay; 2656 if (reset_delay == 0) { 2657 TAVOR_TNF_EXIT(tavor_sw_reset); 2658 return (DDI_SUCCESS); 2659 } 2660 2661 /* 2662 * Get dip for HCA device _and_ parent device as well. Parent access 2663 * is necessary here because software reset of the Tavor hardware 2664 * will reinitialize both the config registers of the PCI bridge 2665 * (parent, if it exists) and the IB HCA (self) 2666 */ 2667 dip = state->ts_dip; 2668 pdip = ddi_get_parent(dip); 2669 2670 /* Query the PCI capabilities of the HCA device */ 2671 tavor_pci_capability_list(state, hdl); 2672 2673 /* 2674 * Read all PCI config info (reg0...reg63). Note: According to the 2675 * Tavor software reset application note, we should not read or 2676 * restore the values in reg22 and reg23. 2677 */ 2678 for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) { 2679 if ((i != TAVOR_SW_RESET_REG22_RSVD) && 2680 (i != TAVOR_SW_RESET_REG23_RSVD)) { 2681 state->ts_cfg_data[i] = pci_config_get32(hdl, i << 2); 2682 } 2683 } 2684 2685 if (TAVOR_PARENT_IS_BRIDGE(pdip)) { 2686 /* 2687 * Setup for PCI config read/write of bridge device 2688 */ 2689 status = pci_config_setup(pdip, &phdl); 2690 if (status != DDI_SUCCESS) { 2691 TNF_PROBE_0(tavor_sw_reset_pcicfg_p_fail, 2692 TAVOR_TNF_ERROR, ""); 2693 TAVOR_TNF_EXIT(tavor_sw_reset); 2694 return (DDI_FAILURE); 2695 } 2696 2697 /* 2698 * Read all PCI config info (reg0...reg63). Note: According to 2699 * the Tavor software reset application note, we should not 2700 * read or restore the values in reg22 and reg23. 2701 */ 2702 for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) { 2703 if ((i != TAVOR_SW_RESET_REG22_RSVD) && 2704 (i != TAVOR_SW_RESET_REG23_RSVD)) { 2705 state->ts_cfg_pdata[i] = 2706 pci_config_get32(phdl, i << 2); 2707 } 2708 } 2709 } 2710 2711 /* 2712 * Perform the software reset (by writing 1 at offset 0xF0010) 2713 */ 2714 ddi_put32(state->ts_reg_cmdhdl, state->ts_cmd_regs.sw_reset, 2715 TAVOR_SW_RESET_START); 2716 2717 drv_usecwait(reset_delay); 2718 2719 if (TAVOR_PARENT_IS_BRIDGE(pdip)) { 2720 /* 2721 * Bridge exists, so wait for the bridge to become ready. 2722 * 2723 * The above delay is necessary to avoid system panic from 2724 * Master Abort. If the device is accessed before this delay, 2725 * device will not respond to config cycles and they will be 2726 * terminate with a Master Abort which will panic the system. 2727 * Below is the loop we use to poll status from the device to 2728 * determine if it is OK to proceed. 2729 */ 2730 i = 0; 2731 while (pci_config_get32(phdl, 0) == TAVOR_SW_RESET_NOTDONE) { 2732 drv_usecwait(TAVOR_SW_RESET_POLL_DELAY); 2733 } 2734 2735 /* 2736 * Write all the PCI config registers back into each device 2737 * (except for reg22 and reg23 - see above) 2738 */ 2739 for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) { 2740 if ((i != TAVOR_SW_RESET_REG22_RSVD) && 2741 (i != TAVOR_SW_RESET_REG23_RSVD)) { 2742 pci_config_put32(phdl, i << 2, 2743 state->ts_cfg_pdata[i]); 2744 } 2745 } 2746 2747 /* 2748 * Tear down the config setup (for bridge device) 2749 */ 2750 pci_config_teardown(&phdl); 2751 2752 /* No Bridge Device */ 2753 } else { 2754 /* 2755 * Bridge does not exist, so instead wait for the device itself 2756 * to become ready. 2757 * 2758 * The above delay is necessary to avoid system panic from 2759 * Master Abort. If the device is accessed before this delay, 2760 * device will not respond to config cycles and they will be 2761 * terminate with a Master Abort which will panic the system. 2762 * Below is the loop we use to poll status from the device to 2763 * determine if it is OK to proceed. 2764 */ 2765 i = 0; 2766 while (pci_config_get32(hdl, 0) == TAVOR_SW_RESET_NOTDONE) { 2767 drv_usecwait(TAVOR_SW_RESET_POLL_DELAY); 2768 } 2769 } 2770 2771 for (i = 0; i < TAVOR_SW_RESET_NUMREGS; i++) { 2772 if ((i != TAVOR_SW_RESET_REG22_RSVD) && 2773 (i != TAVOR_SW_RESET_REG23_RSVD)) { 2774 pci_config_put32(hdl, i << 2, state->ts_cfg_data[i]); 2775 } 2776 } 2777 2778 TAVOR_TNF_EXIT(tavor_sw_reset); 2779 return (DDI_SUCCESS); 2780 } 2781 2782 2783 /* 2784 * tavor_mcg_init() 2785 * Context: Only called from attach() path context 2786 */ 2787 static int 2788 tavor_mcg_init(tavor_state_t *state) 2789 { 2790 uint_t mcg_tmp_sz; 2791 2792 TAVOR_TNF_ENTER(tavor_mcg_init); 2793 2794 /* 2795 * Allocate space for the MCG temporary copy buffer. This is 2796 * used by the Attach/Detach Multicast Group code 2797 */ 2798 mcg_tmp_sz = TAVOR_MCGMEM_SZ(state); 2799 state->ts_mcgtmp = kmem_zalloc(mcg_tmp_sz, KM_SLEEP); 2800 2801 /* 2802 * Initialize the multicast group mutex. This ensures atomic 2803 * access to add, modify, and remove entries in the multicast 2804 * group hash lists. 2805 */ 2806 mutex_init(&state->ts_mcglock, NULL, MUTEX_DRIVER, 2807 DDI_INTR_PRI(state->ts_intrmsi_pri)); 2808 2809 TAVOR_TNF_EXIT(tavor_mcg_init); 2810 return (DDI_SUCCESS); 2811 } 2812 2813 2814 /* 2815 * tavor_mcg_fini() 2816 * Context: Only called from attach() and/or detach() path contexts 2817 */ 2818 static void 2819 tavor_mcg_fini(tavor_state_t *state) 2820 { 2821 uint_t mcg_tmp_sz; 2822 2823 TAVOR_TNF_ENTER(tavor_mcg_fini); 2824 2825 /* Free up the space used for the MCG temporary copy buffer */ 2826 mcg_tmp_sz = TAVOR_MCGMEM_SZ(state); 2827 kmem_free(state->ts_mcgtmp, mcg_tmp_sz); 2828 2829 /* Destroy the multicast group mutex */ 2830 mutex_destroy(&state->ts_mcglock); 2831 2832 TAVOR_TNF_EXIT(tavor_mcg_fini); 2833 } 2834 2835 2836 /* 2837 * tavor_fw_version_check() 2838 * Context: Only called from attach() path context 2839 */ 2840 static int 2841 tavor_fw_version_check(tavor_state_t *state) 2842 { 2843 uint_t tavor_fw_ver_major; 2844 uint_t tavor_fw_ver_minor; 2845 uint_t tavor_fw_ver_subminor; 2846 2847 /* 2848 * Depending on which version of driver we have attached, the firmware 2849 * version checks will be different. We set up the comparison values 2850 * for both HCA Mode (Tavor hardware) or COMPAT Mode (Arbel hardware 2851 * running in tavor mode). 2852 */ 2853 switch (state->ts_operational_mode) { 2854 case TAVOR_HCA_MODE: 2855 tavor_fw_ver_major = TAVOR_FW_VER_MAJOR; 2856 tavor_fw_ver_minor = TAVOR_FW_VER_MINOR; 2857 tavor_fw_ver_subminor = TAVOR_FW_VER_SUBMINOR; 2858 break; 2859 2860 case TAVOR_COMPAT_MODE: 2861 tavor_fw_ver_major = TAVOR_COMPAT_FW_VER_MAJOR; 2862 tavor_fw_ver_minor = TAVOR_COMPAT_FW_VER_MINOR; 2863 tavor_fw_ver_subminor = TAVOR_COMPAT_FW_VER_SUBMINOR; 2864 break; 2865 2866 default: 2867 return (DDI_FAILURE); 2868 } 2869 2870 /* 2871 * If FW revision major number is less than acceptable, 2872 * return failure, else if greater return success. If 2873 * the major numbers are equal than check the minor number 2874 */ 2875 if (state->ts_fw.fw_rev_major < tavor_fw_ver_major) { 2876 return (DDI_FAILURE); 2877 } else if (state->ts_fw.fw_rev_major > tavor_fw_ver_major) { 2878 return (DDI_SUCCESS); 2879 } 2880 /* 2881 * Do the same check as above, except for minor revision numbers 2882 * If the minor numbers are equal than check the subminor number 2883 */ 2884 if (state->ts_fw.fw_rev_minor < tavor_fw_ver_minor) { 2885 return (DDI_FAILURE); 2886 } else if (state->ts_fw.fw_rev_minor > tavor_fw_ver_minor) { 2887 return (DDI_SUCCESS); 2888 } 2889 2890 /* 2891 * Once again we do the same check as above, except for the subminor 2892 * revision number. If the subminor numbers are equal here, then 2893 * these are the same firmware version, return success 2894 */ 2895 if (state->ts_fw.fw_rev_subminor < tavor_fw_ver_subminor) { 2896 return (DDI_FAILURE); 2897 } else if (state->ts_fw.fw_rev_subminor > tavor_fw_ver_subminor) { 2898 return (DDI_SUCCESS); 2899 } 2900 2901 return (DDI_SUCCESS); 2902 } 2903 2904 2905 /* 2906 * tavor_device_info_report() 2907 * Context: Only called from attach() path context 2908 */ 2909 static void 2910 tavor_device_info_report(tavor_state_t *state) 2911 { 2912 cmn_err(CE_CONT, "?tavor%d: FW ver: %04d.%04d.%04d, " 2913 "HW rev: %02x\n", state->ts_instance, state->ts_fw.fw_rev_major, 2914 state->ts_fw.fw_rev_minor, state->ts_fw.fw_rev_subminor, 2915 state->ts_adapter.rev_id); 2916 cmn_err(CE_CONT, "?tavor%d: %64s (0x%016" PRIx64 ")\n", 2917 state->ts_instance, state->ts_nodedesc, state->ts_nodeguid); 2918 } 2919 2920 2921 /* 2922 * tavor_pci_capability_list() 2923 * Context: Only called from attach() path context 2924 */ 2925 static void 2926 tavor_pci_capability_list(tavor_state_t *state, ddi_acc_handle_t hdl) 2927 { 2928 uint_t offset, data; 2929 2930 TAVOR_TNF_ENTER(tavor_pci_capability_list); 2931 2932 /* 2933 * Check for the "PCI Capabilities" bit in the "Status Register". 2934 * Bit 4 in this register indicates the presence of a "PCI 2935 * Capabilities" list. 2936 */ 2937 data = pci_config_get16(hdl, 0x6); 2938 if ((data & 0x10) == 0) { 2939 TNF_PROBE_0(tavor_pci_capab_list_fail, TAVOR_TNF_ERROR, ""); 2940 TAVOR_TNF_EXIT(tavor_pci_capability_list); 2941 return; 2942 } 2943 2944 /* 2945 * Starting from offset 0x34 in PCI config space, find the 2946 * head of "PCI capabilities" list, and walk the list. If 2947 * capabilities of a known type are encountered (e.g. 2948 * "PCI-X Capability"), then call the appropriate handler 2949 * function. 2950 */ 2951 offset = pci_config_get8(hdl, 0x34); 2952 while (offset != 0x0) { 2953 data = pci_config_get8(hdl, offset); 2954 2955 /* 2956 * Check for known capability types. Tavor has the 2957 * following: 2958 * o VPD Capability (0x03) 2959 * o PCI-X Capability (0x07) 2960 * o MSI Capability (0x05) 2961 * o MSIX Capability (0x11) 2962 */ 2963 switch (data) { 2964 case 0x03: 2965 tavor_pci_capability_vpd(state, hdl, offset); 2966 break; 2967 case 0x07: 2968 tavor_pci_capability_pcix(state, hdl, offset); 2969 break; 2970 case 0x05: 2971 break; 2972 default: 2973 break; 2974 } 2975 2976 /* Get offset of next entry in list */ 2977 offset = pci_config_get8(hdl, offset + 1); 2978 } 2979 2980 TAVOR_TNF_EXIT(tavor_pci_capability_list); 2981 } 2982 2983 /* 2984 * tavor_pci_read_vpd() 2985 * Context: Only called from attach() path context 2986 * utility routine for tavor_pci_capability_vpd() 2987 */ 2988 static int 2989 tavor_pci_read_vpd(ddi_acc_handle_t hdl, uint_t offset, uint32_t addr, 2990 uint32_t *data) 2991 { 2992 int retry = 4; /* retry counter for EEPROM poll */ 2993 uint32_t val; 2994 int vpd_addr = offset + 2; 2995 int vpd_data = offset + 4; 2996 2997 TAVOR_TNF_ENTER(tavor_pci_read_vpd); 2998 2999 /* 3000 * In order to read a 32-bit value from VPD, we are to write down 3001 * the address (offset in the VPD itself) to the address register. 3002 * To signal the read, we also clear bit 31. We then poll on bit 31 3003 * and when it is set, we can then read our 4 bytes from the data 3004 * register. 3005 */ 3006 (void) pci_config_put32(hdl, offset, addr << 16); 3007 do { 3008 drv_usecwait(1000); 3009 val = pci_config_get16(hdl, vpd_addr); 3010 if ((val >> 15) & 0x01) { 3011 *data = pci_config_get32(hdl, vpd_data); 3012 TAVOR_TNF_EXIT(tavor_pci_read_vpd); 3013 return (DDI_SUCCESS); 3014 } 3015 } while (--retry); 3016 3017 TNF_PROBE_0(tavor_pci_read_vpd_fail, TAVOR_TNF_ERROR, ""); 3018 TAVOR_TNF_EXIT(tavor_pci_read_vpd); 3019 return (DDI_FAILURE); 3020 } 3021 3022 3023 /* 3024 * tavor_pci_capability_vpd() 3025 * Context: Only called from attach() path context 3026 */ 3027 static void 3028 tavor_pci_capability_vpd(tavor_state_t *state, ddi_acc_handle_t hdl, 3029 uint_t offset) 3030 { 3031 uint8_t name_length; 3032 uint8_t pn_length; 3033 int i, err = 0; 3034 int vpd_str_id = 0; 3035 int vpd_ro_desc; 3036 int vpd_ro_pn_desc; 3037 #ifndef _LITTLE_ENDIAN 3038 uint32_t data32; 3039 #endif /* _LITTLE_ENDIAN */ 3040 union { 3041 uint32_t vpd_int[TAVOR_VPD_HDR_DWSIZE]; 3042 uchar_t vpd_char[TAVOR_VPD_HDR_BSIZE]; 3043 } vpd; 3044 3045 TAVOR_TNF_ENTER(tavor_pci_capability_vpd); 3046 3047 /* 3048 * Read Vital Product Data (VPD) from PCI-X capability. 3049 */ 3050 for (i = 0; i < TAVOR_VPD_HDR_DWSIZE; i++) { 3051 err = tavor_pci_read_vpd(hdl, offset, i << 2, &vpd.vpd_int[i]); 3052 if (err != DDI_SUCCESS) { 3053 cmn_err(CE_NOTE, "!VPD read failed\n"); 3054 goto out; 3055 } 3056 } 3057 3058 #ifndef _LITTLE_ENDIAN 3059 /* 3060 * Need to swap bytes for big endian. 3061 */ 3062 for (i = 0; i < TAVOR_VPD_HDR_DWSIZE; i++) { 3063 data32 = vpd.vpd_int[i]; 3064 vpd.vpd_char[(i << 2) + 3] = 3065 (uchar_t)((data32 & 0xFF000000) >> 24); 3066 vpd.vpd_char[(i << 2) + 2] = 3067 (uchar_t)((data32 & 0x00FF0000) >> 16); 3068 vpd.vpd_char[(i << 2) + 1] = 3069 (uchar_t)((data32 & 0x0000FF00) >> 8); 3070 vpd.vpd_char[i << 2] = (uchar_t)(data32 & 0x000000FF); 3071 } 3072 #endif /* _LITTLE_ENDIAN */ 3073 3074 /* Check for VPD String ID Tag */ 3075 if (vpd.vpd_char[vpd_str_id] == 0x82) { 3076 /* get the product name */ 3077 name_length = (uint8_t)vpd.vpd_char[vpd_str_id + 1]; 3078 if (name_length > sizeof (state->ts_hca_name)) { 3079 cmn_err(CE_NOTE, "!VPD name too large (0x%x)\n", 3080 name_length); 3081 goto out; 3082 } 3083 (void) memcpy(state->ts_hca_name, &vpd.vpd_char[vpd_str_id + 3], 3084 name_length); 3085 state->ts_hca_name[name_length] = 0; 3086 3087 /* get the part number */ 3088 vpd_ro_desc = name_length + 3; /* read-only tag location */ 3089 vpd_ro_pn_desc = vpd_ro_desc + 3; /* P/N keyword location */ 3090 /* 3091 * Verify read-only tag and Part Number keyword. 3092 */ 3093 if (vpd.vpd_char[vpd_ro_desc] != 0x90 || 3094 (vpd.vpd_char[vpd_ro_pn_desc] != 'P' && 3095 vpd.vpd_char[vpd_ro_pn_desc + 1] != 'N')) { 3096 cmn_err(CE_NOTE, "!VPD Part Number not found\n"); 3097 goto out; 3098 } 3099 3100 pn_length = (uint8_t)vpd.vpd_char[vpd_ro_pn_desc + 2]; 3101 if (pn_length > sizeof (state->ts_hca_pn)) { 3102 cmn_err(CE_NOTE, "!VPD part number too large (0x%x)\n", 3103 name_length); 3104 goto out; 3105 } 3106 (void) memcpy(state->ts_hca_pn, 3107 &vpd.vpd_char[vpd_ro_pn_desc + 3], 3108 pn_length); 3109 state->ts_hca_pn[pn_length] = 0; 3110 state->ts_hca_pn_len = pn_length; 3111 } else { 3112 /* Wrong VPD String ID Tag */ 3113 cmn_err(CE_NOTE, "!VPD String ID Tag not found, tag: %02x\n", 3114 vpd.vpd_char[0]); 3115 goto out; 3116 } 3117 TAVOR_TNF_EXIT(tavor_pci_capability_vpd); 3118 return; 3119 out: 3120 state->ts_hca_pn_len = 0; 3121 TNF_PROBE_0(tavor_pci_capability_vpd_fail, TAVOR_TNF_ERROR, ""); 3122 TAVOR_TNF_EXIT(tavor_pci_capability_vpd); 3123 } 3124 3125 /* 3126 * tavor_pci_capability_pcix() 3127 * Context: Only called from attach() path context 3128 */ 3129 static void 3130 tavor_pci_capability_pcix(tavor_state_t *state, ddi_acc_handle_t hdl, 3131 uint_t offset) 3132 { 3133 uint_t command, status; 3134 int max_out_splt_trans, max_mem_rd_byte_cnt; 3135 int designed_max_out_splt_trans, designed_max_mem_rd_byte_cnt; 3136 3137 TAVOR_TNF_ENTER(tavor_pci_capability_pcix); 3138 3139 /* 3140 * Query the current values for the PCI-X Command Register and 3141 * the PCI-X Status Register. 3142 */ 3143 command = pci_config_get16(hdl, offset + 2); 3144 status = pci_config_get32(hdl, offset + 4); 3145 3146 /* 3147 * Check for config property specifying "maximum outstanding 3148 * split transactions". If the property is defined and valid 3149 * (i.e. no larger than the so-called "designed maximum"), 3150 * then use the specified value to update the PCI-X Command Register. 3151 * Otherwise, extract the value from the Tavor config profile. 3152 */ 3153 designed_max_out_splt_trans = ((status >> 23) & 7); 3154 max_out_splt_trans = ddi_prop_get_int(DDI_DEV_T_ANY, state->ts_dip, 3155 DDI_PROP_DONTPASS, "pcix-max-outstanding-split-trans", -1); 3156 if ((max_out_splt_trans != -1) && 3157 ((max_out_splt_trans < 0) || 3158 (max_out_splt_trans > designed_max_out_splt_trans))) { 3159 cmn_err(CE_NOTE, "!tavor%d: property \"pcix-max-outstanding-" 3160 "split-trans\" (%d) invalid or exceeds device maximum" 3161 " (%d), using default value (%d)\n", state->ts_instance, 3162 max_out_splt_trans, designed_max_out_splt_trans, 3163 state->ts_cfg_profile->cp_max_out_splt_trans); 3164 max_out_splt_trans = 3165 state->ts_cfg_profile->cp_max_out_splt_trans; 3166 } else if (max_out_splt_trans == -1) { 3167 max_out_splt_trans = 3168 state->ts_cfg_profile->cp_max_out_splt_trans; 3169 } 3170 3171 /* 3172 * The config profile setting for max_out_splt_trans is determined 3173 * based on arch. Check tavor_cfg.c for more information. A value of 3174 * '-1' in the patchable variable means "do not change". A value of 3175 * '0' means 1 outstanding splt trans and other values as defined by 3176 * PCI. So we do one more check here, that if 'max_out_splt_trans' is 3177 * -1 (ie: < 0) we do not set the PCI command and leave it at the 3178 * default. 3179 */ 3180 if (max_out_splt_trans >= 0) { 3181 command = ((command & 0xFF8F) | max_out_splt_trans << 4); 3182 } 3183 3184 /* 3185 * Check for config property specifying "maximum memory read 3186 * byte count. If the property is defined and valid 3187 * (i.e. no larger than the so-called "designed maximum"), 3188 * then use the specified value to update the PCI-X Command Register. 3189 * Otherwise, extract the value from the Tavor config profile. 3190 */ 3191 designed_max_mem_rd_byte_cnt = ((status >> 21) & 3); 3192 max_mem_rd_byte_cnt = ddi_prop_get_int(DDI_DEV_T_ANY, state->ts_dip, 3193 DDI_PROP_DONTPASS, "pcix-max-read-byte-count", -1); 3194 if ((max_mem_rd_byte_cnt != -1) && 3195 ((max_mem_rd_byte_cnt < 0) || 3196 (max_mem_rd_byte_cnt > designed_max_mem_rd_byte_cnt))) { 3197 cmn_err(CE_NOTE, "!tavor%d: property \"pcix-max-read-byte-" 3198 "count\" (%d) invalid or exceeds device maximum" 3199 " (%d), using default value (%d)\n", state->ts_instance, 3200 max_mem_rd_byte_cnt, designed_max_mem_rd_byte_cnt, 3201 state->ts_cfg_profile->cp_max_mem_rd_byte_cnt); 3202 max_mem_rd_byte_cnt = 3203 state->ts_cfg_profile->cp_max_mem_rd_byte_cnt; 3204 } else if (max_mem_rd_byte_cnt == -1) { 3205 max_mem_rd_byte_cnt = 3206 state->ts_cfg_profile->cp_max_mem_rd_byte_cnt; 3207 } 3208 3209 /* 3210 * The config profile setting for max_mem_rd_byte_cnt is determined 3211 * based on arch. Check tavor_cfg.c for more information. A value of 3212 * '-1' in the patchable variable means "do not change". A value of 3213 * '0' means minimum (512B) read, and other values as defined by 3214 * PCI. So we do one more check here, that if 'max_mem_rd_byte_cnt' is 3215 * -1 (ie: < 0) we do not set the PCI command and leave it at the 3216 * default. 3217 */ 3218 if (max_mem_rd_byte_cnt >= 0) { 3219 command = ((command & 0xFFF3) | max_mem_rd_byte_cnt << 2); 3220 } 3221 3222 /* 3223 * Update the PCI-X Command Register with the newly configured 3224 * values. 3225 */ 3226 pci_config_put16(hdl, offset + 2, command); 3227 3228 TAVOR_TNF_EXIT(tavor_pci_capability_pcix); 3229 } 3230 3231 3232 /* 3233 * tavor_intr_or_msi_init() 3234 * Context: Only called from attach() path context 3235 */ 3236 static int 3237 tavor_intr_or_msi_init(tavor_state_t *state) 3238 { 3239 int status; 3240 3241 TAVOR_TNF_ENTER(tavor_intr_or_msi_init); 3242 3243 /* Query for the list of supported interrupt event types */ 3244 status = ddi_intr_get_supported_types(state->ts_dip, 3245 &state->ts_intr_types_avail); 3246 if (status != DDI_SUCCESS) { 3247 TNF_PROBE_0(tavor_intr_or_msi_init_gettypes_fail, 3248 TAVOR_TNF_ERROR, ""); 3249 TAVOR_TNF_EXIT(tavor_intr_or_msi_init); 3250 return (DDI_FAILURE); 3251 } 3252 3253 /* 3254 * If Tavor/Arbel supports MSI in this system (and, if it 3255 * hasn't been overridden by a configuration variable), then 3256 * the default behavior is to use a single MSI. Otherwise, 3257 * fallback to using legacy interrupts. Also, if MSI allocatis chosen, 3258 * but fails for whatever reasons, then fallback to using legacy 3259 * interrupts. 3260 */ 3261 if ((state->ts_cfg_profile->cp_use_msi_if_avail != 0) && 3262 (state->ts_intr_types_avail & DDI_INTR_TYPE_MSI)) { 3263 status = tavor_add_intrs(state, DDI_INTR_TYPE_MSI); 3264 if (status == DDI_SUCCESS) { 3265 state->ts_intr_type_chosen = DDI_INTR_TYPE_MSI; 3266 TAVOR_TNF_EXIT(tavor_intr_or_msi_init); 3267 return (DDI_SUCCESS); 3268 } 3269 } 3270 3271 /* 3272 * MSI interrupt allocation failed, or was not available. Fallback to 3273 * legacy interrupt support. 3274 */ 3275 if (state->ts_intr_types_avail & DDI_INTR_TYPE_FIXED) { 3276 status = tavor_add_intrs(state, DDI_INTR_TYPE_FIXED); 3277 if (status == DDI_SUCCESS) { 3278 state->ts_intr_type_chosen = DDI_INTR_TYPE_FIXED; 3279 TAVOR_TNF_EXIT(tavor_intr_or_msi_init); 3280 return (DDI_SUCCESS); 3281 } 3282 } 3283 3284 /* 3285 * Neither MSI or legacy interrupts were successful. return failure. 3286 */ 3287 TAVOR_TNF_EXIT(tavor_intr_or_msi_setup); 3288 return (DDI_FAILURE); 3289 } 3290 3291 /* 3292 * tavor_add_intrs() 3293 * Context: Only called from attach() patch context 3294 */ 3295 static int 3296 tavor_add_intrs(tavor_state_t *state, int intr_type) 3297 { 3298 int status; 3299 3300 TAVOR_TNF_ENTER(tavor_add_intrs); 3301 3302 /* Get number of interrupts/MSI supported */ 3303 status = ddi_intr_get_nintrs(state->ts_dip, intr_type, 3304 &state->ts_intrmsi_count); 3305 if (status != DDI_SUCCESS) { 3306 TNF_PROBE_0(tavor_add_intrs_getnintrs_fail, 3307 TAVOR_TNF_ERROR, ""); 3308 TAVOR_TNF_EXIT(tavor_add_intrs); 3309 return (DDI_FAILURE); 3310 } 3311 3312 /* Get number of available interrupts/MSI */ 3313 status = ddi_intr_get_navail(state->ts_dip, intr_type, 3314 &state->ts_intrmsi_avail); 3315 if (status != DDI_SUCCESS) { 3316 TNF_PROBE_0(tavor_add_intrs_getnavail_fail, 3317 TAVOR_TNF_ERROR, ""); 3318 TAVOR_TNF_EXIT(tavor_add_intrs); 3319 return (DDI_FAILURE); 3320 } 3321 3322 /* Ensure that we have at least one (1) usable MSI or interrupt */ 3323 if ((state->ts_intrmsi_avail < 1) || (state->ts_intrmsi_count < 1)) { 3324 TNF_PROBE_0(tavor_add_intrs_notenoughts_intrmsi_fail, 3325 TAVOR_TNF_ERROR, ""); 3326 TAVOR_TNF_EXIT(tavor_add_intrs); 3327 return (DDI_FAILURE); 3328 } 3329 3330 /* Attempt to allocate a single interrupt/MSI handle */ 3331 status = ddi_intr_alloc(state->ts_dip, &state->ts_intrmsi_hdl, 3332 intr_type, 0, 1, &state->ts_intrmsi_allocd, 3333 DDI_INTR_ALLOC_STRICT); 3334 if (status != DDI_SUCCESS) { 3335 TNF_PROBE_0(tavor_add_intrs_intralloc_fail, 3336 TAVOR_TNF_ERROR, ""); 3337 TAVOR_TNF_EXIT(tavor_add_intrs); 3338 return (DDI_FAILURE); 3339 } 3340 3341 /* Ensure that we have allocated at least one (1) MSI or interrupt */ 3342 if (state->ts_intrmsi_allocd < 1) { 3343 TNF_PROBE_0(tavor_add_intrs_noallocts_intrmsi_fail, 3344 TAVOR_TNF_ERROR, ""); 3345 TAVOR_TNF_EXIT(tavor_add_intrs); 3346 return (DDI_FAILURE); 3347 } 3348 3349 /* 3350 * Extract the priority for the allocated interrupt/MSI. This 3351 * will be used later when initializing certain mutexes. 3352 */ 3353 status = ddi_intr_get_pri(state->ts_intrmsi_hdl, 3354 &state->ts_intrmsi_pri); 3355 if (status != DDI_SUCCESS) { 3356 /* Free the allocated interrupt/MSI handle */ 3357 (void) ddi_intr_free(state->ts_intrmsi_hdl); 3358 3359 TNF_PROBE_0(tavor_add_intrs_getpri_fail, 3360 TAVOR_TNF_ERROR, ""); 3361 TAVOR_TNF_EXIT(tavor_add_intrs); 3362 return (DDI_FAILURE); 3363 } 3364 3365 /* Make sure the interrupt/MSI priority is below 'high level' */ 3366 if (state->ts_intrmsi_pri >= ddi_intr_get_hilevel_pri()) { 3367 /* Free the allocated interrupt/MSI handle */ 3368 (void) ddi_intr_free(state->ts_intrmsi_hdl); 3369 3370 TNF_PROBE_0(tavor_add_intrs_hilevelpri_fail, 3371 TAVOR_TNF_ERROR, ""); 3372 TAVOR_TNF_EXIT(tavor_add_intrs); 3373 return (DDI_FAILURE); 3374 } 3375 3376 /* Get add'l capability information regarding interrupt/MSI */ 3377 status = ddi_intr_get_cap(state->ts_intrmsi_hdl, 3378 &state->ts_intrmsi_cap); 3379 if (status != DDI_SUCCESS) { 3380 /* Free the allocated interrupt/MSI handle */ 3381 (void) ddi_intr_free(state->ts_intrmsi_hdl); 3382 3383 TNF_PROBE_0(tavor_add_intrs_getcap_fail, 3384 TAVOR_TNF_ERROR, ""); 3385 TAVOR_TNF_EXIT(tavor_add_intrs); 3386 return (DDI_FAILURE); 3387 } 3388 3389 TAVOR_TNF_EXIT(tavor_add_intrs); 3390 return (DDI_SUCCESS); 3391 } 3392 3393 3394 /* 3395 * tavor_intr_or_msi_fini() 3396 * Context: Only called from attach() and/or detach() path contexts 3397 */ 3398 static int 3399 tavor_intr_or_msi_fini(tavor_state_t *state) 3400 { 3401 int status; 3402 3403 TAVOR_TNF_ENTER(tavor_intr_or_msi_fini); 3404 3405 /* Free the allocated interrupt/MSI handle */ 3406 status = ddi_intr_free(state->ts_intrmsi_hdl); 3407 if (status != DDI_SUCCESS) { 3408 TNF_PROBE_0(tavor_intr_or_msi_fini_freehdl_fail, 3409 TAVOR_TNF_ERROR, ""); 3410 TAVOR_TNF_EXIT(tavor_intr_or_msi_fini); 3411 return (DDI_FAILURE); 3412 } 3413 3414 TAVOR_TNF_EXIT(tavor_intr_or_msi_fini); 3415 return (DDI_SUCCESS); 3416 } 3417 3418 3419 /* Disable Tavor interrupts */ 3420 static int 3421 tavor_intr_disable(tavor_state_t *state) 3422 { 3423 ushort_t msi_ctrl = 0, caps_ctrl = 0; 3424 ddi_acc_handle_t pci_cfg_hdl = state->ts_pci_cfghdl; 3425 ASSERT(pci_cfg_hdl != NULL); 3426 ASSERT(state->ts_intr_types_avail & 3427 (DDI_INTR_TYPE_FIXED | DDI_INTR_TYPE_MSI)); 3428 3429 /* 3430 * Check if MSI interrupts are used. If so, disable MSI interupts. 3431 * If not, since Tavor doesn't support MSI-X interrupts, assuming the 3432 * legacy interrupt is used instead, disable the legacy interrupt. 3433 */ 3434 if ((state->ts_cfg_profile->cp_use_msi_if_avail != 0) && 3435 (state->ts_intr_types_avail & DDI_INTR_TYPE_MSI)) { 3436 3437 if ((PCI_CAP_LOCATE(pci_cfg_hdl, PCI_CAP_ID_MSI, 3438 &caps_ctrl) == DDI_SUCCESS)) { 3439 if ((msi_ctrl = PCI_CAP_GET16(pci_cfg_hdl, NULL, 3440 caps_ctrl, PCI_MSI_CTRL)) == PCI_CAP_EINVAL16) 3441 return (DDI_FAILURE); 3442 } 3443 ASSERT(msi_ctrl != 0); 3444 3445 if (!(msi_ctrl & PCI_MSI_ENABLE_BIT)) 3446 return (DDI_SUCCESS); 3447 3448 if (msi_ctrl & PCI_MSI_PVM_MASK) { 3449 int offset = (msi_ctrl & PCI_MSI_64BIT_MASK) ? 3450 PCI_MSI_64BIT_MASKBITS : PCI_MSI_32BIT_MASK; 3451 3452 /* Clear all inums in MSI */ 3453 PCI_CAP_PUT32(pci_cfg_hdl, NULL, caps_ctrl, 3454 offset, 0x0); 3455 } 3456 3457 /* Disable MSI interrupts */ 3458 msi_ctrl &= ~PCI_MSI_ENABLE_BIT; 3459 PCI_CAP_PUT16(pci_cfg_hdl, NULL, caps_ctrl, PCI_MSI_CTRL, 3460 msi_ctrl); 3461 3462 } else { 3463 uint16_t cmdreg = pci_config_get16(pci_cfg_hdl, PCI_CONF_COMM); 3464 ASSERT(state->ts_intr_types_avail & DDI_INTR_TYPE_FIXED); 3465 3466 /* Disable the legacy interrupts */ 3467 cmdreg |= PCI_COMM_INTX_DISABLE; 3468 pci_config_put16(pci_cfg_hdl, PCI_CONF_COMM, cmdreg); 3469 } 3470 3471 return (DDI_SUCCESS); 3472 } 3473 3474 /* Tavor quiesce(9F) entry */ 3475 static int 3476 tavor_quiesce(dev_info_t *dip) 3477 { 3478 tavor_state_t *state = ddi_get_soft_state(tavor_statep, 3479 DEVI(dip)->devi_instance); 3480 ASSERT(state != NULL); 3481 3482 /* start fastreboot */ 3483 state->ts_quiescing = B_TRUE; 3484 3485 /* If it's in maintenance mode, do nothing but return with SUCCESS */ 3486 if (!TAVOR_IS_OPERATIONAL(state->ts_operational_mode)) { 3487 return (DDI_SUCCESS); 3488 } 3489 3490 /* Shutdown HCA ports */ 3491 if (tavor_hca_ports_shutdown(state, 3492 state->ts_cfg_profile->cp_num_ports) != TAVOR_CMD_SUCCESS) { 3493 state->ts_quiescing = B_FALSE; 3494 return (DDI_FAILURE); 3495 } 3496 3497 /* Close HCA */ 3498 if (tavor_close_hca_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN) != 3499 TAVOR_CMD_SUCCESS) { 3500 state->ts_quiescing = B_FALSE; 3501 return (DDI_FAILURE); 3502 } 3503 3504 /* Shutdown FW */ 3505 if (tavor_sys_dis_cmd_post(state, TAVOR_CMD_NOSLEEP_SPIN) != 3506 TAVOR_CMD_SUCCESS) { 3507 state->ts_quiescing = B_FALSE; 3508 return (DDI_FAILURE); 3509 } 3510 3511 /* Disable interrupts */ 3512 if (tavor_intr_disable(state) != DDI_SUCCESS) { 3513 state->ts_quiescing = B_FALSE; 3514 return (DDI_FAILURE); 3515 } 3516 3517 /* SW-reset */ 3518 if (tavor_sw_reset(state) != DDI_SUCCESS) { 3519 state->ts_quiescing = B_FALSE; 3520 return (DDI_FAILURE); 3521 } 3522 3523 return (DDI_SUCCESS); 3524 }