1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * hermon_ioctl.c
  28  *    Hemron IOCTL Routines
  29  *
  30  *    Implements all ioctl access into the driver.  This includes all routines
  31  *    necessary for updating firmware, accessing the hermon flash device, and
  32  *    providing interfaces for VTS.
  33  */
  34 
  35 #include <sys/types.h>
  36 #include <sys/conf.h>
  37 #include <sys/ddi.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/modctl.h>
  40 #include <sys/file.h>
  41 
  42 #include <sys/ib/adapters/hermon/hermon.h>
  43 
  44 /* Hemron HCA state pointer (extern) */
  45 extern void     *hermon_statep;
  46 extern int      hermon_verbose;
  47 
  48 #define DO_WRCONF       1
  49 static int do_bar0 = 1;
  50 
  51 /*
  52  * The ioctl declarations (for firmware flash burning, register read/write
  53  * (DEBUG-only), and VTS interfaces)
  54  */
  55 static int hermon_ioctl_flash_read(hermon_state_t *state, dev_t dev,
  56     intptr_t arg, int mode);
  57 static int hermon_ioctl_flash_write(hermon_state_t *state, dev_t dev,
  58     intptr_t arg, int mode);
  59 static int hermon_ioctl_flash_erase(hermon_state_t *state, dev_t dev,
  60     intptr_t arg, int mode);
  61 static int hermon_ioctl_flash_init(hermon_state_t *state, dev_t dev,
  62     intptr_t arg, int mode);
  63 static int hermon_ioctl_flash_fini(hermon_state_t *state, dev_t dev);
  64 static int hermon_ioctl_flash_cleanup(hermon_state_t *state);
  65 static int hermon_ioctl_flash_cleanup_nolock(hermon_state_t *state);
  66 #ifdef  DEBUG
  67 static int hermon_ioctl_reg_write(hermon_state_t *state, intptr_t arg,
  68     int mode);
  69 static int hermon_ioctl_reg_read(hermon_state_t *state, intptr_t arg,
  70     int mode);
  71 #endif  /* DEBUG */
  72 static int hermon_ioctl_write_boot_addr(hermon_state_t *state, dev_t dev,
  73     intptr_t arg, int mode);
  74 static int hermon_ioctl_info(hermon_state_t *state, dev_t dev,
  75     intptr_t arg, int mode);
  76 static int hermon_ioctl_ports(hermon_state_t *state, intptr_t arg,
  77     int mode);
  78 static int hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg,
  79     int mode);
  80 
  81 /* Hemron Flash Functions */
  82 static void hermon_flash_spi_exec_command(hermon_state_t *state,
  83     ddi_acc_handle_t hdl, uint32_t cmd);
  84 static int hermon_flash_read_sector(hermon_state_t *state,
  85     uint32_t sector_num);
  86 static int hermon_flash_read_quadlet(hermon_state_t *state, uint32_t *data,
  87     uint32_t addr);
  88 static int hermon_flash_write_sector(hermon_state_t *state,
  89     uint32_t sector_num);
  90 static int hermon_flash_spi_write_dword(hermon_state_t *state,
  91     uint32_t addr, uint32_t data);
  92 static int hermon_flash_write_byte(hermon_state_t *state, uint32_t addr,
  93     uchar_t data);
  94 static int hermon_flash_erase_sector(hermon_state_t *state,
  95     uint32_t sector_num);
  96 static int hermon_flash_erase_chip(hermon_state_t *state);
  97 static int hermon_flash_bank(hermon_state_t *state, uint32_t addr);
  98 static uint32_t hermon_flash_read(hermon_state_t *state, uint32_t addr,
  99     int *err);
 100 static void hermon_flash_write(hermon_state_t *state, uint32_t addr,
 101     uchar_t data, int *err);
 102 static int hermon_flash_spi_wait_wip(hermon_state_t *state);
 103 static void hermon_flash_spi_write_enable(hermon_state_t *state);
 104 static int hermon_flash_init(hermon_state_t *state);
 105 static int hermon_flash_cfi_init(hermon_state_t *state, uint32_t *cfi_info,
 106     int *intel_xcmd);
 107 static int hermon_flash_fini(hermon_state_t *state);
 108 static int hermon_flash_reset(hermon_state_t *state);
 109 static uint32_t hermon_flash_read_cfg(hermon_state_t *state,
 110     ddi_acc_handle_t pci_config_hdl, uint32_t addr);
 111 #ifdef DO_WRCONF
 112 static void hermon_flash_write_cfg(hermon_state_t *state,
 113     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data);
 114 static void hermon_flash_write_cfg_helper(hermon_state_t *state,
 115     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data);
 116 static void hermon_flash_write_confirm(hermon_state_t *state,
 117     ddi_acc_handle_t pci_config_hdl);
 118 #endif
 119 static void hermon_flash_cfi_byte(uint8_t *ch, uint32_t dword, int i);
 120 static void hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i);
 121 
 122 /* Hemron loopback test functions */
 123 static void hermon_loopback_free_qps(hermon_loopback_state_t *lstate);
 124 static void hermon_loopback_free_state(hermon_loopback_state_t *lstate);
 125 static int hermon_loopback_init(hermon_state_t *state,
 126     hermon_loopback_state_t *lstate);
 127 static void hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
 128     hermon_loopback_comm_t *comm);
 129 static int hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
 130     hermon_loopback_comm_t *comm, int sz);
 131 static int hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
 132     hermon_loopback_comm_t *comm);
 133 static int hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
 134     hermon_loopback_comm_t *comm, uint_t qp_num);
 135 static int hermon_loopback_copyout(hermon_loopback_ioctl_t *lb,
 136     intptr_t arg, int mode);
 137 static int hermon_loopback_post_send(hermon_loopback_state_t *lstate,
 138     hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx);
 139 static int hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
 140     hermon_loopback_comm_t *comm);
 141 
 142 /* Patchable timeout values for flash operations */
 143 int hermon_hw_flash_timeout_gpio_sema = HERMON_HW_FLASH_TIMEOUT_GPIO_SEMA;
 144 int hermon_hw_flash_timeout_config = HERMON_HW_FLASH_TIMEOUT_CONFIG;
 145 int hermon_hw_flash_timeout_write = HERMON_HW_FLASH_TIMEOUT_WRITE;
 146 int hermon_hw_flash_timeout_erase = HERMON_HW_FLASH_TIMEOUT_ERASE;
 147 
 148 /*
 149  * hermon_ioctl()
 150  */
 151 /* ARGSUSED */
 152 int
 153 hermon_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
 154     int *rvalp)
 155 {
 156         hermon_state_t  *state;
 157         minor_t         instance;
 158         int             status;
 159 
 160         if (drv_priv(credp) != 0) {
 161                 return (EPERM);
 162         }
 163 
 164         instance = HERMON_DEV_INSTANCE(dev);
 165         if (instance == (minor_t)-1) {
 166                 return (EBADF);
 167         }
 168 
 169         state = ddi_get_soft_state(hermon_statep, instance);
 170         if (state == NULL) {
 171                 return (EBADF);
 172         }
 173 
 174         status = 0;
 175 
 176         switch (cmd) {
 177         case HERMON_IOCTL_FLASH_READ:
 178                 status = hermon_ioctl_flash_read(state, dev, arg, mode);
 179                 break;
 180 
 181         case HERMON_IOCTL_FLASH_WRITE:
 182                 status = hermon_ioctl_flash_write(state, dev, arg, mode);
 183                 break;
 184 
 185         case HERMON_IOCTL_FLASH_ERASE:
 186                 status = hermon_ioctl_flash_erase(state, dev, arg, mode);
 187                 break;
 188 
 189         case HERMON_IOCTL_FLASH_INIT:
 190                 status = hermon_ioctl_flash_init(state, dev, arg, mode);
 191                 break;
 192 
 193         case HERMON_IOCTL_FLASH_FINI:
 194                 status = hermon_ioctl_flash_fini(state, dev);
 195                 break;
 196 
 197         case HERMON_IOCTL_INFO:
 198                 status = hermon_ioctl_info(state, dev, arg, mode);
 199                 break;
 200 
 201         case HERMON_IOCTL_PORTS:
 202                 status = hermon_ioctl_ports(state, arg, mode);
 203                 break;
 204 
 205         case HERMON_IOCTL_LOOPBACK:
 206                 status = hermon_ioctl_loopback(state, arg, mode);
 207                 break;
 208 
 209 #ifdef  DEBUG
 210         case HERMON_IOCTL_REG_WRITE:
 211                 status = hermon_ioctl_reg_write(state, arg, mode);
 212                 break;
 213 
 214         case HERMON_IOCTL_REG_READ:
 215                 status = hermon_ioctl_reg_read(state, arg, mode);
 216                 break;
 217 #endif  /* DEBUG */
 218 
 219         case HERMON_IOCTL_DDR_READ:
 220                 /* XXX guard until the ioctl header is cleaned up */
 221                 status = ENODEV;
 222                 break;
 223 
 224         case HERMON_IOCTL_WRITE_BOOT_ADDR:
 225                 status = hermon_ioctl_write_boot_addr(state, dev, arg, mode);
 226                 break;
 227 
 228         default:
 229                 status = ENOTTY;
 230                 break;
 231         }
 232         *rvalp = status;
 233 
 234         return (status);
 235 }
 236 
 237 /*
 238  * hermon_ioctl_flash_read()
 239  */
 240 static int
 241 hermon_ioctl_flash_read(hermon_state_t *state, dev_t dev, intptr_t arg,
 242     int mode)
 243 {
 244         hermon_flash_ioctl_t ioctl_info;
 245         int status = 0;
 246 
 247         /*
 248          * Check that flash init ioctl has been called first.  And check
 249          * that the same dev_t that called init is the one calling read now.
 250          */
 251         mutex_enter(&state->hs_fw_flashlock);
 252         if ((state->hs_fw_flashdev != dev) ||
 253             (state->hs_fw_flashstarted == 0)) {
 254                 mutex_exit(&state->hs_fw_flashlock);
 255                 return (EIO);
 256         }
 257 
 258         /* copy user struct to kernel */
 259 #ifdef _MULTI_DATAMODEL
 260         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 261                 hermon_flash_ioctl32_t info32;
 262 
 263                 if (ddi_copyin((void *)arg, &info32,
 264                     sizeof (hermon_flash_ioctl32_t), mode) != 0) {
 265                         mutex_exit(&state->hs_fw_flashlock);
 266                         return (EFAULT);
 267                 }
 268                 ioctl_info.af_type = info32.af_type;
 269                 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
 270                 ioctl_info.af_sector_num = info32.af_sector_num;
 271                 ioctl_info.af_addr = info32.af_addr;
 272         } else
 273 #endif /* _MULTI_DATAMODEL */
 274         if (ddi_copyin((void *)arg, &ioctl_info, sizeof (hermon_flash_ioctl_t),
 275             mode) != 0) {
 276                 mutex_exit(&state->hs_fw_flashlock);
 277                 return (EFAULT);
 278         }
 279 
 280         /*
 281          * Determine type of READ ioctl
 282          */
 283         switch (ioctl_info.af_type) {
 284         case HERMON_FLASH_READ_SECTOR:
 285                 /* Check if sector num is too large for flash device */
 286                 if (ioctl_info.af_sector_num >=
 287                     (state->hs_fw_device_sz >> state->hs_fw_log_sector_sz)) {
 288                         mutex_exit(&state->hs_fw_flashlock);
 289                         return (EFAULT);
 290                 }
 291 
 292                 /* Perform the Sector Read */
 293                 if ((status = hermon_flash_reset(state)) != 0 ||
 294                     (status = hermon_flash_read_sector(state,
 295                     ioctl_info.af_sector_num)) != 0) {
 296                         mutex_exit(&state->hs_fw_flashlock);
 297                         return (status);
 298                 }
 299 
 300                 /* copyout the firmware sector image data */
 301                 if (ddi_copyout(&state->hs_fw_sector[0],
 302                     &ioctl_info.af_sector[0], 1 << state->hs_fw_log_sector_sz,
 303                     mode) != 0) {
 304                         mutex_exit(&state->hs_fw_flashlock);
 305                         return (EFAULT);
 306                 }
 307                 break;
 308 
 309         case HERMON_FLASH_READ_QUADLET:
 310                 /* Check if addr is too large for flash device */
 311                 if (ioctl_info.af_addr >= state->hs_fw_device_sz) {
 312                         mutex_exit(&state->hs_fw_flashlock);
 313                         return (EFAULT);
 314                 }
 315 
 316                 /* Perform the Quadlet Read */
 317                 if ((status = hermon_flash_reset(state)) != 0 ||
 318                     (status = hermon_flash_read_quadlet(state,
 319                     &ioctl_info.af_quadlet, ioctl_info.af_addr)) != 0) {
 320                         mutex_exit(&state->hs_fw_flashlock);
 321                         return (status);
 322                 }
 323                 break;
 324 
 325         default:
 326                 mutex_exit(&state->hs_fw_flashlock);
 327                 return (EINVAL);
 328         }
 329 
 330         /* copy results back to userland */
 331 #ifdef _MULTI_DATAMODEL
 332         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 333                 hermon_flash_ioctl32_t info32;
 334 
 335                 info32.af_quadlet = ioctl_info.af_quadlet;
 336                 info32.af_type = ioctl_info.af_type;
 337                 info32.af_sector_num = ioctl_info.af_sector_num;
 338                 info32.af_sector = (caddr32_t)(uintptr_t)ioctl_info.af_sector;
 339                 info32.af_addr = ioctl_info.af_addr;
 340 
 341                 if (ddi_copyout(&info32, (void *)arg,
 342                     sizeof (hermon_flash_ioctl32_t), mode) != 0) {
 343                         mutex_exit(&state->hs_fw_flashlock);
 344                         return (EFAULT);
 345                 }
 346         } else
 347 #endif /* _MULTI_DATAMODEL */
 348         if (ddi_copyout(&ioctl_info, (void *)arg,
 349             sizeof (hermon_flash_ioctl_t), mode) != 0) {
 350                 mutex_exit(&state->hs_fw_flashlock);
 351                 return (EFAULT);
 352         }
 353 
 354         mutex_exit(&state->hs_fw_flashlock);
 355         return (status);
 356 }
 357 
 358 /*
 359  * hermon_ioctl_flash_write()
 360  */
 361 static int
 362 hermon_ioctl_flash_write(hermon_state_t *state, dev_t dev, intptr_t arg,
 363     int mode)
 364 {
 365         hermon_flash_ioctl_t    ioctl_info;
 366         int status = 0;
 367 
 368         /*
 369          * Check that flash init ioctl has been called first.  And check
 370          * that the same dev_t that called init is the one calling write now.
 371          */
 372         mutex_enter(&state->hs_fw_flashlock);
 373         if ((state->hs_fw_flashdev != dev) ||
 374             (state->hs_fw_flashstarted == 0)) {
 375                 mutex_exit(&state->hs_fw_flashlock);
 376                 return (EIO);
 377         }
 378 
 379         /* copy user struct to kernel */
 380 #ifdef _MULTI_DATAMODEL
 381         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 382                 hermon_flash_ioctl32_t info32;
 383 
 384                 if (ddi_copyin((void *)arg, &info32,
 385                     sizeof (hermon_flash_ioctl32_t), mode) != 0) {
 386                         mutex_exit(&state->hs_fw_flashlock);
 387                         return (EFAULT);
 388                 }
 389                 ioctl_info.af_type = info32.af_type;
 390                 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
 391                 ioctl_info.af_sector_num = info32.af_sector_num;
 392                 ioctl_info.af_addr = info32.af_addr;
 393                 ioctl_info.af_byte = info32.af_byte;
 394         } else
 395 #endif /* _MULTI_DATAMODEL */
 396         if (ddi_copyin((void *)arg, &ioctl_info,
 397             sizeof (hermon_flash_ioctl_t), mode) != 0) {
 398                 mutex_exit(&state->hs_fw_flashlock);
 399                 return (EFAULT);
 400         }
 401 
 402         /*
 403          * Determine type of WRITE ioctl
 404          */
 405         switch (ioctl_info.af_type) {
 406         case HERMON_FLASH_WRITE_SECTOR:
 407                 /* Check if sector num is too large for flash device */
 408                 if (ioctl_info.af_sector_num >=
 409                     (state->hs_fw_device_sz >> state->hs_fw_log_sector_sz)) {
 410                         mutex_exit(&state->hs_fw_flashlock);
 411                         return (EFAULT);
 412                 }
 413 
 414                 /* copy in fw sector image data */
 415                 if (ddi_copyin(&ioctl_info.af_sector[0],
 416                     &state->hs_fw_sector[0], 1 << state->hs_fw_log_sector_sz,
 417                     mode) != 0) {
 418                         mutex_exit(&state->hs_fw_flashlock);
 419                         return (EFAULT);
 420                 }
 421 
 422                 /* Perform Write Sector */
 423                 status = hermon_flash_write_sector(state,
 424                     ioctl_info.af_sector_num);
 425                 break;
 426 
 427         case HERMON_FLASH_WRITE_BYTE:
 428                 /* Check if addr is too large for flash device */
 429                 if (ioctl_info.af_addr >= state->hs_fw_device_sz) {
 430                         mutex_exit(&state->hs_fw_flashlock);
 431                         return (EFAULT);
 432                 }
 433 
 434                 /* Perform Write Byte */
 435                 /*
 436                  * CMJ -- is a reset really needed before and after writing
 437                  * each byte?  This code came from arbel, but we should look
 438                  * into this.  Also, for SPI, no reset is actually performed.
 439                  */
 440                 if ((status = hermon_flash_bank(state,
 441                     ioctl_info.af_addr)) != 0 ||
 442                     (status = hermon_flash_reset(state)) != 0 ||
 443                     (status = hermon_flash_write_byte(state,
 444                     ioctl_info.af_addr, ioctl_info.af_byte)) != 0 ||
 445                     (status = hermon_flash_reset(state)) != 0) {
 446                         mutex_exit(&state->hs_fw_flashlock);
 447                         return (status);
 448                 }
 449                 break;
 450 
 451         default:
 452                 status = EINVAL;
 453                 break;
 454         }
 455 
 456         mutex_exit(&state->hs_fw_flashlock);
 457         return (status);
 458 }
 459 
 460 /*
 461  * hermon_ioctl_flash_erase()
 462  */
 463 static int
 464 hermon_ioctl_flash_erase(hermon_state_t *state, dev_t dev, intptr_t arg,
 465     int mode)
 466 {
 467         hermon_flash_ioctl_t    ioctl_info;
 468         int status = 0;
 469 
 470         /*
 471          * Check that flash init ioctl has been called first.  And check
 472          * that the same dev_t that called init is the one calling erase now.
 473          */
 474         mutex_enter(&state->hs_fw_flashlock);
 475         if ((state->hs_fw_flashdev != dev) ||
 476             (state->hs_fw_flashstarted == 0)) {
 477                 mutex_exit(&state->hs_fw_flashlock);
 478                 return (EIO);
 479         }
 480 
 481         /* copy user struct to kernel */
 482 #ifdef _MULTI_DATAMODEL
 483         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 484                 hermon_flash_ioctl32_t info32;
 485 
 486                 if (ddi_copyin((void *)arg, &info32,
 487                     sizeof (hermon_flash_ioctl32_t), mode) != 0) {
 488                         mutex_exit(&state->hs_fw_flashlock);
 489                         return (EFAULT);
 490                 }
 491                 ioctl_info.af_type = info32.af_type;
 492                 ioctl_info.af_sector_num = info32.af_sector_num;
 493         } else
 494 #endif /* _MULTI_DATAMODEL */
 495         if (ddi_copyin((void *)arg, &ioctl_info, sizeof (hermon_flash_ioctl_t),
 496             mode) != 0) {
 497                 mutex_exit(&state->hs_fw_flashlock);
 498                 return (EFAULT);
 499         }
 500 
 501         /*
 502          * Determine type of ERASE ioctl
 503          */
 504         switch (ioctl_info.af_type) {
 505         case HERMON_FLASH_ERASE_SECTOR:
 506                 /* Check if sector num is too large for flash device */
 507                 if (ioctl_info.af_sector_num >=
 508                     (state->hs_fw_device_sz >> state->hs_fw_log_sector_sz)) {
 509                         mutex_exit(&state->hs_fw_flashlock);
 510                         return (EFAULT);
 511                 }
 512 
 513                 /* Perform Sector Erase */
 514                 status = hermon_flash_erase_sector(state,
 515                     ioctl_info.af_sector_num);
 516                 break;
 517 
 518         case HERMON_FLASH_ERASE_CHIP:
 519                 /* Perform Chip Erase */
 520                 status = hermon_flash_erase_chip(state);
 521                 break;
 522 
 523         default:
 524                 status = EINVAL;
 525                 break;
 526         }
 527 
 528         mutex_exit(&state->hs_fw_flashlock);
 529         return (status);
 530 }
 531 
 532 /*
 533  * hermon_ioctl_flash_init()
 534  */
 535 static int
 536 hermon_ioctl_flash_init(hermon_state_t *state, dev_t dev, intptr_t arg,
 537     int mode)
 538 {
 539         hermon_flash_init_ioctl_t init_info;
 540         int ret;
 541         int intel_xcmd = 0;
 542         ddi_acc_handle_t pci_hdl = hermon_get_pcihdl(state);
 543 
 544         /* initialize the FMA retry loop */
 545         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
 546 
 547         state->hs_fw_sector = NULL;
 548 
 549         /*
 550          * init cannot be called more than once.  If we have already init'd the
 551          * flash, return directly.
 552          */
 553         mutex_enter(&state->hs_fw_flashlock);
 554         if (state->hs_fw_flashstarted == 1) {
 555                 mutex_exit(&state->hs_fw_flashlock);
 556                 return (EINVAL);
 557         }
 558 
 559         /* copyin the user struct to kernel */
 560         if (ddi_copyin((void *)arg, &init_info,
 561             sizeof (hermon_flash_init_ioctl_t), mode) != 0) {
 562                 mutex_exit(&state->hs_fw_flashlock);
 563                 return (EFAULT);
 564         }
 565 
 566         /* Init Flash */
 567         if ((ret = hermon_flash_init(state)) != 0) {
 568                 if (ret == EIO) {
 569                         goto pio_error;
 570                 }
 571                 mutex_exit(&state->hs_fw_flashlock);
 572                 return (ret);
 573         }
 574 
 575         /* Read CFI info */
 576         if ((ret = hermon_flash_cfi_init(state, &init_info.af_cfi_info[0],
 577             &intel_xcmd)) != 0) {
 578                 if (ret == EIO) {
 579                         goto pio_error;
 580                 }
 581                 mutex_exit(&state->hs_fw_flashlock);
 582                 return (ret);
 583         }
 584 
 585         /*
 586          * Return error if the command set is unknown.
 587          */
 588         if (state->hs_fw_cmdset == HERMON_FLASH_UNKNOWN_CMDSET) {
 589                 if ((ret = hermon_ioctl_flash_cleanup_nolock(state)) != 0) {
 590                         if (ret == EIO) {
 591                                 goto pio_error;
 592                         }
 593                         mutex_exit(&state->hs_fw_flashlock);
 594                         return (ret);
 595                 }
 596                 mutex_exit(&state->hs_fw_flashlock);
 597                 return (EFAULT);
 598         }
 599 
 600         /* the FMA retry loop starts. */
 601         hermon_pio_start(state, pci_hdl, pio_error,
 602             fm_loop_cnt, fm_status, fm_test);
 603 
 604         /* Read HWREV - least significant 8 bits is revision ID */
 605         init_info.af_hwrev = pci_config_get32(pci_hdl,
 606             HERMON_HW_FLASH_CFG_HWREV) & 0xFF;
 607 
 608         /* the FMA retry loop ends. */
 609         hermon_pio_end(state, pci_hdl, pio_error, fm_loop_cnt,
 610             fm_status, fm_test);
 611 
 612         /* Fill in the firmwate revision numbers */
 613         init_info.af_fwrev.afi_maj      = state->hs_fw.fw_rev_major;
 614         init_info.af_fwrev.afi_min      = state->hs_fw.fw_rev_minor;
 615         init_info.af_fwrev.afi_sub      = state->hs_fw.fw_rev_subminor;
 616 
 617         /* Alloc flash mem for one sector size */
 618         state->hs_fw_sector = (uint32_t *)kmem_zalloc(1 <<
 619             state->hs_fw_log_sector_sz, KM_SLEEP);
 620 
 621         /* Set HW part number and length */
 622         init_info.af_pn_len = state->hs_hca_pn_len;
 623         if (state->hs_hca_pn_len != 0) {
 624                 (void) memcpy(init_info.af_hwpn, state->hs_hca_pn,
 625                     state->hs_hca_pn_len);
 626         }
 627 
 628         /* Copy ioctl results back to userland */
 629         if (ddi_copyout(&init_info, (void *)arg,
 630             sizeof (hermon_flash_init_ioctl_t), mode) != 0) {
 631                 if ((ret = hermon_ioctl_flash_cleanup_nolock(state)) != 0) {
 632                         if (ret == EIO) {
 633                                 goto pio_error;
 634                         }
 635                         mutex_exit(&state->hs_fw_flashlock);
 636                         return (ret);
 637                 }
 638                 mutex_exit(&state->hs_fw_flashlock);
 639                 return (EFAULT);
 640         }
 641 
 642         /* Set flash state to started */
 643         state->hs_fw_flashstarted = 1;
 644         state->hs_fw_flashdev          = dev;
 645 
 646         mutex_exit(&state->hs_fw_flashlock);
 647 
 648         /*
 649          * If "flash init" is successful, add an "on close" callback to the
 650          * current dev node to ensure that "flash fini" gets called later
 651          * even if the userland process prematurely exits.
 652          */
 653         ret = hermon_umap_db_set_onclose_cb(dev,
 654             HERMON_ONCLOSE_FLASH_INPROGRESS,
 655             (int (*)(void *))hermon_ioctl_flash_cleanup, state);
 656         if (ret != DDI_SUCCESS) {
 657                 int status = hermon_ioctl_flash_fini(state, dev);
 658                 if (status != 0) {
 659                         if (status == EIO) {
 660                                 hermon_fm_ereport(state, HCA_SYS_ERR,
 661                                     HCA_ERR_IOCTL);
 662                                 return (EIO);
 663                         }
 664                         return (status);
 665                 }
 666         }
 667         return (0);
 668 
 669 pio_error:
 670         mutex_exit(&state->hs_fw_flashlock);
 671         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
 672         return (EIO);
 673 }
 674 
 675 /*
 676  * hermon_ioctl_flash_fini()
 677  */
 678 static int
 679 hermon_ioctl_flash_fini(hermon_state_t *state, dev_t dev)
 680 {
 681         int ret;
 682 
 683         /*
 684          * Check that flash init ioctl has been called first.  And check
 685          * that the same dev_t that called init is the one calling fini now.
 686          */
 687         mutex_enter(&state->hs_fw_flashlock);
 688         if ((state->hs_fw_flashdev != dev) ||
 689             (state->hs_fw_flashstarted == 0)) {
 690                 mutex_exit(&state->hs_fw_flashlock);
 691                 return (EINVAL);
 692         }
 693 
 694         if ((ret = hermon_ioctl_flash_cleanup_nolock(state)) != 0) {
 695                 mutex_exit(&state->hs_fw_flashlock);
 696                 if (ret == EIO) {
 697                         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
 698                 }
 699                 return (ret);
 700         }
 701         mutex_exit(&state->hs_fw_flashlock);
 702 
 703         /*
 704          * If "flash fini" is successful, remove the "on close" callback
 705          * that was setup during "flash init".
 706          */
 707         ret = hermon_umap_db_clear_onclose_cb(dev,
 708             HERMON_ONCLOSE_FLASH_INPROGRESS);
 709         if (ret != DDI_SUCCESS) {
 710                 return (EFAULT);
 711         }
 712         return (0);
 713 }
 714 
 715 
 716 /*
 717  * hermon_ioctl_flash_cleanup()
 718  */
 719 static int
 720 hermon_ioctl_flash_cleanup(hermon_state_t *state)
 721 {
 722         int status;
 723 
 724         mutex_enter(&state->hs_fw_flashlock);
 725         status = hermon_ioctl_flash_cleanup_nolock(state);
 726         mutex_exit(&state->hs_fw_flashlock);
 727 
 728         return (status);
 729 }
 730 
 731 
 732 /*
 733  * hermon_ioctl_flash_cleanup_nolock()
 734  */
 735 static int
 736 hermon_ioctl_flash_cleanup_nolock(hermon_state_t *state)
 737 {
 738         int status;
 739         ASSERT(MUTEX_HELD(&state->hs_fw_flashlock));
 740 
 741         /* free flash mem */
 742         if (state->hs_fw_sector) {
 743                 kmem_free(state->hs_fw_sector, 1 << state->hs_fw_log_sector_sz);
 744         }
 745 
 746         /* Fini the Flash */
 747         if ((status = hermon_flash_fini(state)) != 0)
 748                 return (status);
 749 
 750         /* Set flash state to fini */
 751         state->hs_fw_flashstarted = 0;
 752         state->hs_fw_flashdev          = 0;
 753         return (0);
 754 }
 755 
 756 
 757 /*
 758  * hermon_ioctl_info()
 759  */
 760 static int
 761 hermon_ioctl_info(hermon_state_t *state, dev_t dev, intptr_t arg, int mode)
 762 {
 763         hermon_info_ioctl_t      info;
 764         hermon_flash_init_ioctl_t init_info;
 765 
 766         /*
 767          * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
 768          */
 769         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
 770                 return (EFAULT);
 771         }
 772 
 773         /* copyin the user struct to kernel */
 774         if (ddi_copyin((void *)arg, &info, sizeof (hermon_info_ioctl_t),
 775             mode) != 0) {
 776                 return (EFAULT);
 777         }
 778 
 779         /*
 780          * Check ioctl revision
 781          */
 782         if (info.ai_revision != HERMON_VTS_IOCTL_REVISION) {
 783                 return (EINVAL);
 784         }
 785 
 786         /*
 787          * If the 'fw_device_sz' has not been initialized yet, we initialize it
 788          * here.  This is done by leveraging the
 789          * hermon_ioctl_flash_init()/fini() calls.  We also hold our own mutex
 790          * around this operation in case we have multiple VTS threads in
 791          * process at the same time.
 792          */
 793         mutex_enter(&state->hs_info_lock);
 794         if (state->hs_fw_device_sz == 0) {
 795                 if (hermon_ioctl_flash_init(state, dev, (intptr_t)&init_info,
 796                     (FKIOCTL | mode)) != 0) {
 797                         mutex_exit(&state->hs_info_lock);
 798                         return (EFAULT);
 799                 }
 800                 (void) hermon_ioctl_flash_fini(state, dev);
 801         }
 802         mutex_exit(&state->hs_info_lock);
 803 
 804         info.ai_hw_rev           = state->hs_revision_id;
 805         info.ai_flash_sz         = state->hs_fw_device_sz;
 806         info.ai_fw_rev.afi_maj   = state->hs_fw.fw_rev_major;
 807         info.ai_fw_rev.afi_min   = state->hs_fw.fw_rev_minor;
 808         info.ai_fw_rev.afi_sub   = state->hs_fw.fw_rev_subminor;
 809 
 810         /* Copy ioctl results back to user struct */
 811         if (ddi_copyout(&info, (void *)arg, sizeof (hermon_info_ioctl_t),
 812             mode) != 0) {
 813                 return (EFAULT);
 814         }
 815 
 816         return (0);
 817 }
 818 
 819 /*
 820  * hermon_ioctl_ports()
 821  */
 822 static int
 823 hermon_ioctl_ports(hermon_state_t *state, intptr_t arg, int mode)
 824 {
 825         hermon_ports_ioctl_t    info;
 826         hermon_stat_port_ioctl_t        portstat;
 827         ibt_hca_portinfo_t      pi;
 828         uint_t                  tbl_size;
 829         ib_gid_t                *sgid_tbl;
 830         ib_pkey_t               *pkey_tbl;
 831         int                     i;
 832 
 833         /*
 834          * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
 835          */
 836         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
 837                 return (EFAULT);
 838         }
 839 
 840         /* copyin the user struct to kernel */
 841 #ifdef _MULTI_DATAMODEL
 842         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 843                 hermon_ports_ioctl32_t info32;
 844 
 845                 if (ddi_copyin((void *)arg, &info32,
 846                     sizeof (hermon_ports_ioctl32_t), mode) != 0) {
 847                         return (EFAULT);
 848                 }
 849                 info.ap_revision  = info32.ap_revision;
 850                 info.ap_ports     =
 851                     (hermon_stat_port_ioctl_t *)(uintptr_t)info32.ap_ports;
 852                 info.ap_num_ports = info32.ap_num_ports;
 853 
 854         } else
 855 #endif /* _MULTI_DATAMODEL */
 856         if (ddi_copyin((void *)arg, &info, sizeof (hermon_ports_ioctl_t),
 857             mode) != 0) {
 858                 return (EFAULT);
 859         }
 860 
 861         /*
 862          * Check ioctl revision
 863          */
 864         if (info.ap_revision != HERMON_VTS_IOCTL_REVISION) {
 865                 return (EINVAL);
 866         }
 867 
 868         /* Allocate space for temporary GID table/PKey table */
 869         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
 870         sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
 871             KM_SLEEP);
 872         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
 873         pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
 874             KM_SLEEP);
 875 
 876         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sgid_tbl, *pkey_tbl))
 877 
 878         /*
 879          * Setup the number of ports, then loop through all ports and
 880          * query properties of each.
 881          */
 882         info.ap_num_ports = (uint8_t)state->hs_cfg_profile->cp_num_ports;
 883         for (i = 0; i < info.ap_num_ports; i++) {
 884                 /*
 885                  * Get portstate information from the device.  If
 886                  * hermon_port_query() fails, leave zeroes in user
 887                  * struct port entry and continue.
 888                  */
 889                 bzero(&pi, sizeof (ibt_hca_portinfo_t));
 890                 pi.p_sgid_tbl = sgid_tbl;
 891                 pi.p_pkey_tbl = pkey_tbl;
 892                 (void) hermon_port_query(state, i + 1, &pi);
 893 
 894                 portstat.asp_port_num   = pi.p_port_num;
 895                 portstat.asp_state      = pi.p_linkstate;
 896                 portstat.asp_guid       = pi.p_sgid_tbl[0].gid_guid;
 897 
 898                 /*
 899                  * Copy queried port results back to user struct.  If
 900                  * this fails, then break out of loop, attempt to copy
 901                  * out remaining info to user struct, and return (without
 902                  * error).
 903                  */
 904                 if (ddi_copyout(&portstat,
 905                     &(((hermon_stat_port_ioctl_t *)info.ap_ports)[i]),
 906                     sizeof (hermon_stat_port_ioctl_t), mode) != 0) {
 907                         break;
 908                 }
 909         }
 910 
 911         /* Free the temporary space used for GID table/PKey table */
 912         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
 913         kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
 914         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
 915         kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
 916 
 917         /* Copy ioctl results back to user struct */
 918 #ifdef _MULTI_DATAMODEL
 919         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 920                 hermon_ports_ioctl32_t info32;
 921 
 922                 info32.ap_revision  = info.ap_revision;
 923                 info32.ap_ports     = (caddr32_t)(uintptr_t)info.ap_ports;
 924                 info32.ap_num_ports = info.ap_num_ports;
 925 
 926                 if (ddi_copyout(&info32, (void *)arg,
 927                     sizeof (hermon_ports_ioctl32_t), mode) != 0) {
 928                         return (EFAULT);
 929                 }
 930         } else
 931 #endif /* _MULTI_DATAMODEL */
 932         if (ddi_copyout(&info, (void *)arg, sizeof (hermon_ports_ioctl_t),
 933             mode) != 0) {
 934                 return (EFAULT);
 935         }
 936 
 937         return (0);
 938 }
 939 
 940 /*
 941  * hermon_ioctl_loopback()
 942  */
 943 static int
 944 hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg, int mode)
 945 {
 946         hermon_loopback_ioctl_t lb;
 947         hermon_loopback_state_t lstate;
 948         ibt_hca_portinfo_t      pi;
 949         uint_t                  tbl_size, loopmax, max_usec;
 950         ib_gid_t                *sgid_tbl;
 951         ib_pkey_t               *pkey_tbl;
 952         int                     j, iter, ret;
 953 
 954         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(lstate))
 955 
 956         /*
 957          * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
 958          */
 959         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
 960                 return (EFAULT);
 961         }
 962 
 963         /* copyin the user struct to kernel */
 964 #ifdef _MULTI_DATAMODEL
 965         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 966                 hermon_loopback_ioctl32_t lb32;
 967 
 968                 if (ddi_copyin((void *)arg, &lb32,
 969                     sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
 970                         return (EFAULT);
 971                 }
 972                 lb.alb_revision     = lb32.alb_revision;
 973                 lb.alb_send_buf     = (caddr_t)(uintptr_t)lb32.alb_send_buf;
 974                 lb.alb_fail_buf     = (caddr_t)(uintptr_t)lb32.alb_fail_buf;
 975                 lb.alb_buf_sz       = lb32.alb_buf_sz;
 976                 lb.alb_num_iter     = lb32.alb_num_iter;
 977                 lb.alb_pass_done    = lb32.alb_pass_done;
 978                 lb.alb_timeout      = lb32.alb_timeout;
 979                 lb.alb_error_type   = lb32.alb_error_type;
 980                 lb.alb_port_num     = lb32.alb_port_num;
 981                 lb.alb_num_retry    = lb32.alb_num_retry;
 982         } else
 983 #endif /* _MULTI_DATAMODEL */
 984         if (ddi_copyin((void *)arg, &lb, sizeof (hermon_loopback_ioctl_t),
 985             mode) != 0) {
 986                 return (EFAULT);
 987         }
 988 
 989         /* Initialize the internal loopback test state structure */
 990         bzero(&lstate, sizeof (hermon_loopback_state_t));
 991 
 992         /*
 993          * Check ioctl revision
 994          */
 995         if (lb.alb_revision != HERMON_VTS_IOCTL_REVISION) {
 996                 lb.alb_error_type = HERMON_LOOPBACK_INVALID_REVISION;
 997                 (void) hermon_loopback_copyout(&lb, arg, mode);
 998                 return (EINVAL);
 999         }
1000 
1001         /* Validate that specified port number is legal */
1002         if (!hermon_portnum_is_valid(state, lb.alb_port_num)) {
1003                 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1004                 (void) hermon_loopback_copyout(&lb, arg, mode);
1005                 return (EINVAL);
1006         }
1007 
1008         /* Allocate space for temporary GID table/PKey table */
1009         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1010         sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
1011             KM_SLEEP);
1012         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1013         pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
1014             KM_SLEEP);
1015 
1016         /*
1017          * Get portstate information from specific port on device
1018          */
1019         bzero(&pi, sizeof (ibt_hca_portinfo_t));
1020         pi.p_sgid_tbl = sgid_tbl;
1021         pi.p_pkey_tbl = pkey_tbl;
1022         if (hermon_port_query(state, lb.alb_port_num, &pi) != 0) {
1023                 /* Free the temporary space used for GID table/PKey table */
1024                 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1025                 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1026                 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1027                 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1028 
1029                 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1030                 (void) hermon_loopback_copyout(&lb, arg, mode);
1031                 hermon_loopback_free_state(&lstate);
1032                 return (EINVAL);
1033         }
1034 
1035         lstate.hls_port    = pi.p_port_num;
1036         lstate.hls_lid     = pi.p_base_lid;
1037         lstate.hls_pkey_ix = (pi.p_linkstate == HERMON_PORT_LINK_ACTIVE) ?
1038             1 : 0;      /* XXX bogus assumption of a SUN subnet manager */
1039         lstate.hls_state   = state;
1040         lstate.hls_retry   = lb.alb_num_retry;
1041 
1042         /* Free the temporary space used for GID table/PKey table */
1043         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1044         kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1045         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1046         kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1047 
1048         /*
1049          * Compute the timeout duration in usec per the formula:
1050          *    to_usec_per_retry = 4.096us * (2 ^ supplied_timeout)
1051          * (plus we add a little fudge-factor here too)
1052          */
1053         lstate.hls_timeout = lb.alb_timeout;
1054         max_usec = (4096 * (1 << lstate.hls_timeout)) / 1000;
1055         max_usec = max_usec * (lstate.hls_retry + 1);
1056         max_usec = max_usec + 10000;
1057 
1058         /*
1059          * Determine how many times we should loop before declaring a
1060          * timeout failure.
1061          */
1062         loopmax  = max_usec/HERMON_VTS_LOOPBACK_MIN_WAIT_DUR;
1063         if ((max_usec % HERMON_VTS_LOOPBACK_MIN_WAIT_DUR) != 0) {
1064                 loopmax++;
1065         }
1066 
1067         if (lb.alb_send_buf == NULL || lb.alb_buf_sz == 0) {
1068                 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_INVALID;
1069                 (void) hermon_loopback_copyout(&lb, arg, mode);
1070                 hermon_loopback_free_state(&lstate);
1071                 return (EINVAL);
1072         }
1073 
1074         /* Allocate protection domain (PD) */
1075         if (hermon_loopback_init(state, &lstate) != 0) {
1076                 lb.alb_error_type = lstate.hls_err;
1077                 (void) hermon_loopback_copyout(&lb, arg, mode);
1078                 hermon_loopback_free_state(&lstate);
1079                 return (EFAULT);
1080         }
1081 
1082         /* Allocate and register a TX buffer */
1083         if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_tx,
1084             lb.alb_buf_sz) != 0) {
1085                 lb.alb_error_type =
1086                     HERMON_LOOPBACK_SEND_BUF_MEM_REGION_ALLOC_FAIL;
1087                 (void) hermon_loopback_copyout(&lb, arg, mode);
1088                 hermon_loopback_free_state(&lstate);
1089                 return (EFAULT);
1090         }
1091 
1092         /* Allocate and register an RX buffer */
1093         if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_rx,
1094             lb.alb_buf_sz) != 0) {
1095                 lb.alb_error_type =
1096                     HERMON_LOOPBACK_RECV_BUF_MEM_REGION_ALLOC_FAIL;
1097                 (void) hermon_loopback_copyout(&lb, arg, mode);
1098                 hermon_loopback_free_state(&lstate);
1099                 return (EFAULT);
1100         }
1101 
1102         /* Copy in the transmit buffer data */
1103         if (ddi_copyin((void *)lb.alb_send_buf, lstate.hls_tx.hlc_buf,
1104             lb.alb_buf_sz, mode) != 0) {
1105                 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_COPY_FAIL;
1106                 (void) hermon_loopback_copyout(&lb, arg, mode);
1107                 hermon_loopback_free_state(&lstate);
1108                 return (EFAULT);
1109         }
1110 
1111         /* Allocate the transmit QP and CQs */
1112         lstate.hls_err = HERMON_LOOPBACK_XMIT_SEND_CQ_ALLOC_FAIL;
1113         if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_tx) != 0) {
1114                 lb.alb_error_type = lstate.hls_err;
1115                 (void) hermon_loopback_copyout(&lb, arg, mode);
1116                 hermon_loopback_free_state(&lstate);
1117                 return (EFAULT);
1118         }
1119 
1120         /* Allocate the receive QP and CQs */
1121         lstate.hls_err = HERMON_LOOPBACK_RECV_SEND_CQ_ALLOC_FAIL;
1122         if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_rx) != 0) {
1123                 lb.alb_error_type = lstate.hls_err;
1124                 (void) hermon_loopback_copyout(&lb, arg, mode);
1125                 hermon_loopback_free_state(&lstate);
1126                 return (EFAULT);
1127         }
1128 
1129         /* Activate the TX QP (connect to RX QP) */
1130         lstate.hls_err = HERMON_LOOPBACK_XMIT_QP_INIT_FAIL;
1131         if (hermon_loopback_modify_qp(&lstate, &lstate.hls_tx,
1132             lstate.hls_rx.hlc_qp_num) != 0) {
1133                 lb.alb_error_type = lstate.hls_err;
1134                 (void) hermon_loopback_copyout(&lb, arg, mode);
1135                 hermon_loopback_free_state(&lstate);
1136                 return (EFAULT);
1137         }
1138 
1139         /* Activate the RX QP (connect to TX QP) */
1140         lstate.hls_err = HERMON_LOOPBACK_RECV_QP_INIT_FAIL;
1141         if (hermon_loopback_modify_qp(&lstate, &lstate.hls_rx,
1142             lstate.hls_tx.hlc_qp_num) != 0) {
1143                 lb.alb_error_type = lstate.hls_err;
1144                 (void) hermon_loopback_copyout(&lb, arg, mode);
1145                 hermon_loopback_free_state(&lstate);
1146                 return (EFAULT);
1147         }
1148 
1149         /* Run the loopback test (for specified number of iterations) */
1150         lb.alb_pass_done = 0;
1151         for (iter = 0; iter < lb.alb_num_iter; iter++) {
1152                 lstate.hls_err = 0;
1153                 bzero(lstate.hls_rx.hlc_buf, lb.alb_buf_sz);
1154 
1155                 /* Post RDMA Write work request */
1156                 if (hermon_loopback_post_send(&lstate, &lstate.hls_tx,
1157                     &lstate.hls_rx) != IBT_SUCCESS) {
1158                         lb.alb_error_type = HERMON_LOOPBACK_WQE_POST_FAIL;
1159                         (void) hermon_loopback_copyout(&lb, arg, mode);
1160                         hermon_loopback_free_state(&lstate);
1161                         return (EFAULT);
1162                 }
1163 
1164                 /* Poll the TX CQ for a completion every few ticks */
1165                 for (j = 0; j < loopmax; j++) {
1166                         delay(drv_usectohz(HERMON_VTS_LOOPBACK_MIN_WAIT_DUR));
1167 
1168                         ret = hermon_loopback_poll_cq(&lstate, &lstate.hls_tx);
1169                         if (((ret != IBT_SUCCESS) && (ret != IBT_CQ_EMPTY)) ||
1170                             ((ret == IBT_CQ_EMPTY) && (j == loopmax - 1))) {
1171                                 lb.alb_error_type =
1172                                     HERMON_LOOPBACK_CQ_POLL_FAIL;
1173                                 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1174                                     lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1175                                     mode) != 0) {
1176                                         return (EFAULT);
1177                                 }
1178                                 (void) hermon_loopback_copyout(&lb, arg, mode);
1179                                 hermon_loopback_free_state(&lstate);
1180                                 return (EFAULT);
1181                         } else if (ret == IBT_CQ_EMPTY) {
1182                                 continue;
1183                         }
1184 
1185                         /* Compare the data buffers */
1186                         if (bcmp(lstate.hls_tx.hlc_buf, lstate.hls_rx.hlc_buf,
1187                             lb.alb_buf_sz) == 0) {
1188                                 break;
1189                         } else {
1190                                 lb.alb_error_type =
1191                                     HERMON_LOOPBACK_SEND_RECV_COMPARE_FAIL;
1192                                 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1193                                     lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1194                                     mode) != 0) {
1195                                         return (EFAULT);
1196                                 }
1197                                 (void) hermon_loopback_copyout(&lb, arg, mode);
1198                                 hermon_loopback_free_state(&lstate);
1199                                 return (EFAULT);
1200                         }
1201                 }
1202 
1203                 lstate.hls_err   = HERMON_LOOPBACK_SUCCESS;
1204                 lb.alb_pass_done = iter + 1;
1205         }
1206 
1207         lb.alb_error_type = HERMON_LOOPBACK_SUCCESS;
1208 
1209         /* Copy ioctl results back to user struct */
1210         ret = hermon_loopback_copyout(&lb, arg, mode);
1211 
1212         /* Free up everything and release all consumed resources */
1213         hermon_loopback_free_state(&lstate);
1214 
1215         return (ret);
1216 }
1217 
1218 #ifdef  DEBUG
1219 /*
1220  * hermon_ioctl_reg_read()
1221  */
1222 static int
1223 hermon_ioctl_reg_read(hermon_state_t *state, intptr_t arg, int mode)
1224 {
1225         hermon_reg_ioctl_t      rdreg;
1226         uint32_t                *addr;
1227         uintptr_t               baseaddr;
1228         int                     status;
1229         ddi_acc_handle_t        handle;
1230 
1231         /* initialize the FMA retry loop */
1232         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1233 
1234         /*
1235          * Access to Hemron registers is not allowed in "maintenance mode".
1236          * This is primarily because the device may not have BARs to access
1237          */
1238         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1239                 return (EFAULT);
1240         }
1241 
1242         /* Copy in the hermon_reg_ioctl_t structure */
1243         status = ddi_copyin((void *)arg, &rdreg, sizeof (hermon_reg_ioctl_t),
1244             mode);
1245         if (status != 0) {
1246                 return (EFAULT);
1247         }
1248 
1249         /* Determine base address for requested register set */
1250         switch (rdreg.arg_reg_set) {
1251         case HERMON_CMD_BAR:
1252                 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1253                 handle = hermon_get_cmdhdl(state);
1254                 break;
1255 
1256         case HERMON_UAR_BAR:
1257                 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1258                 handle = hermon_get_uarhdl(state);
1259                 break;
1260 
1261 
1262         default:
1263                 return (EINVAL);
1264         }
1265 
1266         /* Ensure that address is properly-aligned */
1267         addr = (uint32_t *)((baseaddr + rdreg.arg_offset) & ~0x3);
1268 
1269         /* the FMA retry loop starts. */
1270         hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1271             fm_status, fm_test);
1272 
1273         /* Read the register pointed to by addr */
1274         rdreg.arg_data = ddi_get32(handle, addr);
1275 
1276         /* the FMA retry loop ends. */
1277         hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1278             fm_test);
1279 
1280         /* Copy in the result into the hermon_reg_ioctl_t structure */
1281         status = ddi_copyout(&rdreg, (void *)arg, sizeof (hermon_reg_ioctl_t),
1282             mode);
1283         if (status != 0) {
1284                 return (EFAULT);
1285         }
1286         return (0);
1287 
1288 pio_error:
1289         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1290         return (EIO);
1291 }
1292 
1293 
1294 /*
1295  * hermon_ioctl_reg_write()
1296  */
1297 static int
1298 hermon_ioctl_reg_write(hermon_state_t *state, intptr_t arg, int mode)
1299 {
1300         hermon_reg_ioctl_t      wrreg;
1301         uint32_t                *addr;
1302         uintptr_t               baseaddr;
1303         int                     status;
1304         ddi_acc_handle_t        handle;
1305 
1306         /* initialize the FMA retry loop */
1307         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1308 
1309         /*
1310          * Access to Hermon registers is not allowed in "maintenance mode".
1311          * This is primarily because the device may not have BARs to access
1312          */
1313         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1314                 return (EFAULT);
1315         }
1316 
1317         /* Copy in the hermon_reg_ioctl_t structure */
1318         status = ddi_copyin((void *)arg, &wrreg, sizeof (hermon_reg_ioctl_t),
1319             mode);
1320         if (status != 0) {
1321                 return (EFAULT);
1322         }
1323 
1324         /* Determine base address for requested register set */
1325         switch (wrreg.arg_reg_set) {
1326         case HERMON_CMD_BAR:
1327                 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1328                 handle = hermon_get_cmdhdl(state);
1329                 break;
1330 
1331         case HERMON_UAR_BAR:
1332                 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1333                 handle = hermon_get_uarhdl(state);
1334                 break;
1335 
1336         default:
1337                 return (EINVAL);
1338         }
1339 
1340         /* Ensure that address is properly-aligned */
1341         addr = (uint32_t *)((baseaddr + wrreg.arg_offset) & ~0x3);
1342 
1343         /* the FMA retry loop starts. */
1344         hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1345             fm_status, fm_test);
1346 
1347         /* Write the data to the register pointed to by addr */
1348         ddi_put32(handle, addr, wrreg.arg_data);
1349 
1350         /* the FMA retry loop ends. */
1351         hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1352             fm_test);
1353         return (0);
1354 
1355 pio_error:
1356         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1357         return (EIO);
1358 }
1359 #endif  /* DEBUG */
1360 
1361 static int
1362 hermon_ioctl_write_boot_addr(hermon_state_t *state, dev_t dev, intptr_t arg,
1363     int mode)
1364 {
1365         hermon_flash_ioctl_t    ioctl_info;
1366 
1367         /* initialize the FMA retry loop */
1368         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1369 
1370         /*
1371          * Check that flash init ioctl has been called first.  And check
1372          * that the same dev_t that called init is the one calling write now.
1373          */
1374         mutex_enter(&state->hs_fw_flashlock);
1375         if ((state->hs_fw_flashdev != dev) ||
1376             (state->hs_fw_flashstarted == 0)) {
1377                 mutex_exit(&state->hs_fw_flashlock);
1378                 return (EIO);
1379         }
1380 
1381         /* copy user struct to kernel */
1382 #ifdef _MULTI_DATAMODEL
1383         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
1384                 hermon_flash_ioctl32_t info32;
1385 
1386                 if (ddi_copyin((void *)arg, &info32,
1387                     sizeof (hermon_flash_ioctl32_t), mode) != 0) {
1388                         mutex_exit(&state->hs_fw_flashlock);
1389                         return (EFAULT);
1390                 }
1391                 ioctl_info.af_type = info32.af_type;
1392                 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
1393                 ioctl_info.af_sector_num = info32.af_sector_num;
1394                 ioctl_info.af_addr = info32.af_addr;
1395                 ioctl_info.af_byte = info32.af_byte;
1396         } else
1397 #endif /* _MULTI_DATAMODEL */
1398         if (ddi_copyin((void *)arg, &ioctl_info,
1399             sizeof (hermon_flash_ioctl_t), mode) != 0) {
1400                 mutex_exit(&state->hs_fw_flashlock);
1401                 return (EFAULT);
1402         }
1403 
1404         switch (state->hs_fw_cmdset) {
1405         case HERMON_FLASH_AMD_CMDSET:
1406         case HERMON_FLASH_INTEL_CMDSET:
1407                 break;
1408 
1409         case HERMON_FLASH_SPI_CMDSET:
1410         {
1411                 ddi_acc_handle_t pci_hdl = hermon_get_pcihdl(state);
1412 
1413                 /* the FMA retry loop starts. */
1414                 hermon_pio_start(state, pci_hdl, pio_error,
1415                     fm_loop_cnt, fm_status, fm_test);
1416 
1417                 hermon_flash_write_cfg(state, pci_hdl,
1418                     HERMON_HW_FLASH_SPI_BOOT_ADDR_REG,
1419                     (ioctl_info.af_addr << 8) | 0x06);
1420 
1421                 /* the FMA retry loop ends. */
1422                 hermon_pio_end(state, pci_hdl, pio_error,
1423                     fm_loop_cnt, fm_status, fm_test);
1424                 break;
1425         }
1426 
1427         case HERMON_FLASH_UNKNOWN_CMDSET:
1428         default:
1429                 mutex_exit(&state->hs_fw_flashlock);
1430                 return (EINVAL);
1431         }
1432         mutex_exit(&state->hs_fw_flashlock);
1433         return (0);
1434 
1435 pio_error:
1436         mutex_exit(&state->hs_fw_flashlock);
1437         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1438         return (EIO);
1439 }
1440 
1441 /*
1442  * hermon_flash_reset()
1443  */
1444 static int
1445 hermon_flash_reset(hermon_state_t *state)
1446 {
1447         int status;
1448 
1449         /*
1450          * Performs a reset to the flash device.  After a reset the flash will
1451          * be operating in normal mode (capable of read/write, etc.).
1452          */
1453         switch (state->hs_fw_cmdset) {
1454         case HERMON_FLASH_AMD_CMDSET:
1455                 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_AMD,
1456                     &status);
1457                 if (status != 0) {
1458                         return (status);
1459                 }
1460                 break;
1461 
1462         case HERMON_FLASH_INTEL_CMDSET:
1463                 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_INTEL,
1464                     &status);
1465                 if (status != 0) {
1466                         return (status);
1467                 }
1468                 break;
1469 
1470         /* It appears no reset is needed for SPI */
1471         case HERMON_FLASH_SPI_CMDSET:
1472                 status = 0;
1473                 break;
1474 
1475         case HERMON_FLASH_UNKNOWN_CMDSET:
1476         default:
1477                 status = EINVAL;
1478                 break;
1479         }
1480         return (status);
1481 }
1482 
1483 /*
1484  * hermon_flash_read_sector()
1485  */
1486 static int
1487 hermon_flash_read_sector(hermon_state_t *state, uint32_t sector_num)
1488 {
1489         uint32_t addr;
1490         uint32_t end_addr;
1491         uint32_t *image;
1492         int i, status;
1493 
1494         image = (uint32_t *)&state->hs_fw_sector[0];
1495 
1496         /*
1497          * Calculate the start and end address of the sector, based on the
1498          * sector number passed in.
1499          */
1500         addr = sector_num << state->hs_fw_log_sector_sz;
1501         end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1502 
1503         /* Set the flash bank correctly for the given address */
1504         if ((status = hermon_flash_bank(state, addr)) != 0)
1505                 return (status);
1506 
1507         /* Read the entire sector, one quadlet at a time */
1508         for (i = 0; addr < end_addr; i++, addr += 4) {
1509                 image[i] = hermon_flash_read(state, addr, &status);
1510                 if (status != 0) {
1511                         return (status);
1512                 }
1513         }
1514         return (0);
1515 }
1516 
1517 /*
1518  * hermon_flash_read_quadlet()
1519  */
1520 static int
1521 hermon_flash_read_quadlet(hermon_state_t *state, uint32_t *data,
1522     uint32_t addr)
1523 {
1524         int status;
1525 
1526         /* Set the flash bank correctly for the given address */
1527         if ((status = hermon_flash_bank(state, addr)) != 0) {
1528                 return (status);
1529         }
1530 
1531         /* Read one quadlet of data */
1532         *data = hermon_flash_read(state, addr, &status);
1533         if (status != 0) {
1534                 return (EIO);
1535         }
1536 
1537         return (0);
1538 }
1539 
1540 /*
1541  * hermon_flash_write_sector()
1542  */
1543 static int
1544 hermon_flash_write_sector(hermon_state_t *state, uint32_t sector_num)
1545 {
1546         uint32_t        addr;
1547         uint32_t        end_addr;
1548         uint32_t        *databuf;
1549         uchar_t         *sector;
1550         int             status = 0;
1551         int             i;
1552 
1553         sector = (uchar_t *)&state->hs_fw_sector[0];
1554 
1555         /*
1556          * Calculate the start and end address of the sector, based on the
1557          * sector number passed in.
1558          */
1559         addr = sector_num << state->hs_fw_log_sector_sz;
1560         end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1561 
1562         /* Set the flash bank correctly for the given address */
1563         if ((status = hermon_flash_bank(state, addr)) != 0 ||
1564             (status = hermon_flash_reset(state)) != 0) {
1565                 return (status);
1566         }
1567 
1568         /* Erase the sector before writing */
1569         status = hermon_flash_erase_sector(state, sector_num);
1570         if (status != 0) {
1571                 return (status);
1572         }
1573 
1574         switch (state->hs_fw_cmdset) {
1575         case HERMON_FLASH_SPI_CMDSET:
1576                 databuf = (uint32_t *)(void *)sector;
1577                 /* Write the sector, one dword at a time */
1578                 for (i = 0; addr < end_addr; i++, addr += 4) {
1579                         if ((status = hermon_flash_spi_write_dword(state, addr,
1580                             htonl(databuf[i]))) != 0) {
1581                                 return (status);
1582                         }
1583                 }
1584                 status = hermon_flash_reset(state);
1585                 break;
1586 
1587         case HERMON_FLASH_INTEL_CMDSET:
1588         case HERMON_FLASH_AMD_CMDSET:
1589                 /* Write the sector, one byte at a time */
1590                 for (i = 0; addr < end_addr; i++, addr++) {
1591                         status = hermon_flash_write_byte(state, addr,
1592                             sector[i]);
1593                         if (status != 0) {
1594                                 break;
1595                         }
1596                 }
1597                 status = hermon_flash_reset(state);
1598                 break;
1599 
1600         case HERMON_FLASH_UNKNOWN_CMDSET:
1601         default:
1602                 status = EINVAL;
1603                 break;
1604         }
1605 
1606         return (status);
1607 }
1608 
1609 /*
1610  * hermon_flash_spi_write_dword()
1611  *
1612  * NOTE: This function assumes that "data" is in network byte order.
1613  *
1614  */
1615 static int
1616 hermon_flash_spi_write_dword(hermon_state_t *state, uint32_t addr,
1617     uint32_t data)
1618 {
1619         int status;
1620         ddi_acc_handle_t        hdl;
1621 
1622         /* initialize the FMA retry loop */
1623         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1624 
1625         hdl = hermon_get_pcihdl(state);
1626 
1627         /* the FMA retry loop starts. */
1628         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1629             fm_test);
1630 
1631         /* Issue Write Enable */
1632         hermon_flash_spi_write_enable(state);
1633 
1634         /* Set the Address */
1635         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1636             addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1637 
1638         /* Set the Data */
1639         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_DATA, data);
1640 
1641         /* Set the Page Program and execute */
1642         hermon_flash_spi_exec_command(state, hdl,
1643             HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1644             HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1645             HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
1646             HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
1647             (HERMON_HW_FLASH_SPI_PAGE_PROGRAM <<
1648             HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1649 
1650         /* Wait for write to complete */
1651         if ((status = hermon_flash_spi_wait_wip(state)) != 0) {
1652                 return (status);
1653         }
1654 
1655         /* the FMA retry loop ends. */
1656         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
1657         return (0);
1658 
1659 pio_error:
1660         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1661         return (EIO);
1662 }
1663 
1664 /*
1665  * hermon_flash_write_byte()
1666  */
1667 static int
1668 hermon_flash_write_byte(hermon_state_t *state, uint32_t addr, uchar_t data)
1669 {
1670         uint32_t stat;
1671         int status = 0;
1672         int dword_addr;
1673         int byte_offset;
1674         int i;
1675         union {
1676                 uint8_t         bytes[4];
1677                 uint32_t        dword;
1678         } dword;
1679 
1680         switch (state->hs_fw_cmdset) {
1681         case HERMON_FLASH_AMD_CMDSET:
1682                 /* Issue Flash Byte program command */
1683                 hermon_flash_write(state, addr, 0xAA, &status);
1684                 if (status != 0) {
1685                         return (status);
1686                 }
1687 
1688                 hermon_flash_write(state, addr, 0x55, &status);
1689                 if (status != 0) {
1690                         return (status);
1691                 }
1692 
1693                 hermon_flash_write(state, addr, 0xA0, &status);
1694                 if (status != 0) {
1695                         return (status);
1696                 }
1697 
1698                 hermon_flash_write(state, addr, data, &status);
1699                 if (status != 0) {
1700                         return (status);
1701                 }
1702 
1703                 /* Wait for Write Byte to Complete */
1704                 i = 0;
1705                 do {
1706                         drv_usecwait(1);
1707                         stat = hermon_flash_read(state, addr & ~3, &status);
1708                         if (status != 0) {
1709                                 return (status);
1710                         }
1711 
1712                         if (i == hermon_hw_flash_timeout_write) {
1713                                 cmn_err(CE_WARN,
1714                                     "hermon_flash_write_byte: ACS write "
1715                                     "timeout: addr: 0x%x, data: 0x%x\n",
1716                                     addr, data);
1717                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1718                                     HCA_ERR_IOCTL);
1719                                 return (EIO);
1720                         }
1721                         i++;
1722                 } while (data != ((stat >> ((3 - (addr & 3)) << 3)) & 0xFF));
1723 
1724                 break;
1725 
1726         case HERMON_FLASH_INTEL_CMDSET:
1727                 /* Issue Flash Byte program command */
1728                 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_WRITE,
1729                     &status);
1730                 if (status != 0) {
1731                         return (status);
1732                 }
1733                 hermon_flash_write(state, addr, data, &status);
1734                 if (status != 0) {
1735                         return (status);
1736                 }
1737 
1738                 /* Wait for Write Byte to Complete */
1739                 i = 0;
1740                 do {
1741                         drv_usecwait(1);
1742                         stat = hermon_flash_read(state, addr & ~3, &status);
1743                         if (status != 0) {
1744                                 return (status);
1745                         }
1746 
1747                         if (i == hermon_hw_flash_timeout_write) {
1748                                 cmn_err(CE_WARN,
1749                                     "hermon_flash_write_byte: ICS write "
1750                                     "timeout: addr: %x, data: %x\n",
1751                                     addr, data);
1752                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1753                                     HCA_ERR_IOCTL);
1754                                 return (EIO);
1755                         }
1756                         i++;
1757                 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1758 
1759                 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1760                         cmn_err(CE_WARN,
1761                             "hermon_flash_write_byte: ICS write cmd error: "
1762                             "addr: %x, data: %x\n",
1763                             addr, data);
1764                         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1765                         return (EIO);
1766                 }
1767                 break;
1768 
1769         case HERMON_FLASH_SPI_CMDSET:
1770                 /*
1771                  * Our lowest write granularity on SPI is a dword.
1772                  * To support this ioctl option, we can read in the
1773                  * dword that contains this byte, modify this byte,
1774                  * and write the dword back out.
1775                  */
1776 
1777                 /* Determine dword offset and byte offset within the dword */
1778                 byte_offset = addr & 3;
1779                 dword_addr = addr - byte_offset;
1780 #ifdef _LITTLE_ENDIAN
1781                 byte_offset = 3 - byte_offset;
1782 #endif
1783 
1784                 /* Read in dword */
1785                 if ((status = hermon_flash_read_quadlet(state, &dword.dword,
1786                     dword_addr)) != 0)
1787                         break;
1788 
1789                 /* Set "data" to the appopriate byte */
1790                 dword.bytes[byte_offset] = data;
1791 
1792                 /* Write modified dword back out */
1793                 status = hermon_flash_spi_write_dword(state, dword_addr,
1794                     dword.dword);
1795 
1796                 break;
1797 
1798         case HERMON_FLASH_UNKNOWN_CMDSET:
1799         default:
1800                 cmn_err(CE_WARN,
1801                     "hermon_flash_write_byte: unknown cmd set: 0x%x\n",
1802                     state->hs_fw_cmdset);
1803                 status = EINVAL;
1804                 break;
1805         }
1806 
1807         return (status);
1808 }
1809 
1810 /*
1811  * hermon_flash_erase_sector()
1812  */
1813 static int
1814 hermon_flash_erase_sector(hermon_state_t *state, uint32_t sector_num)
1815 {
1816         ddi_acc_handle_t        hdl;
1817         uint32_t addr;
1818         uint32_t stat;
1819         int status = 0;
1820         int i;
1821 
1822         /* initialize the FMA retry loop */
1823         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1824 
1825         /* Get address from sector num */
1826         addr = sector_num << state->hs_fw_log_sector_sz;
1827 
1828         switch (state->hs_fw_cmdset) {
1829         case HERMON_FLASH_AMD_CMDSET:
1830                 /* Issue Flash Sector Erase Command */
1831                 hermon_flash_write(state, addr, 0xAA, &status);
1832                 if (status != 0) {
1833                         return (status);
1834                 }
1835 
1836                 hermon_flash_write(state, addr, 0x55, &status);
1837                 if (status != 0) {
1838                         return (status);
1839                 }
1840 
1841                 hermon_flash_write(state, addr, 0x80, &status);
1842                 if (status != 0) {
1843                         return (status);
1844                 }
1845 
1846                 hermon_flash_write(state, addr, 0xAA, &status);
1847                 if (status != 0) {
1848                         return (status);
1849                 }
1850 
1851                 hermon_flash_write(state, addr, 0x55, &status);
1852                 if (status != 0) {
1853                         return (status);
1854                 }
1855 
1856                 hermon_flash_write(state, addr, 0x30, &status);
1857                 if (status != 0) {
1858                         return (status);
1859                 }
1860 
1861                 /* Wait for Sector Erase to complete */
1862                 i = 0;
1863                 do {
1864                         drv_usecwait(1);
1865                         stat = hermon_flash_read(state, addr, &status);
1866                         if (status != 0) {
1867                                 return (status);
1868                         }
1869 
1870                         if (i == hermon_hw_flash_timeout_erase) {
1871                                 cmn_err(CE_WARN,
1872                                     "hermon_flash_erase_sector: "
1873                                     "ACS erase timeout\n");
1874                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1875                                     HCA_ERR_IOCTL);
1876                                 return (EIO);
1877                         }
1878                         i++;
1879                 } while (stat != 0xFFFFFFFF);
1880                 break;
1881 
1882         case HERMON_FLASH_INTEL_CMDSET:
1883                 /* Issue Flash Sector Erase Command */
1884                 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_ERASE,
1885                     &status);
1886                 if (status != 0) {
1887                         return (status);
1888                 }
1889 
1890                 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_CONFIRM,
1891                     &status);
1892                 if (status != 0) {
1893                         return (status);
1894                 }
1895 
1896                 /* Wait for Sector Erase to complete */
1897                 i = 0;
1898                 do {
1899                         drv_usecwait(1);
1900                         stat = hermon_flash_read(state, addr & ~3, &status);
1901                         if (status != 0) {
1902                                 return (status);
1903                         }
1904 
1905                         if (i == hermon_hw_flash_timeout_erase) {
1906                                 cmn_err(CE_WARN,
1907                                     "hermon_flash_erase_sector: "
1908                                     "ICS erase timeout\n");
1909                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1910                                     HCA_ERR_IOCTL);
1911                                 return (EIO);
1912                         }
1913                         i++;
1914                 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1915 
1916                 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1917                         cmn_err(CE_WARN,
1918                             "hermon_flash_erase_sector: "
1919                             "ICS erase cmd error\n");
1920                         hermon_fm_ereport(state, HCA_SYS_ERR,
1921                             HCA_ERR_IOCTL);
1922                         return (EIO);
1923                 }
1924                 break;
1925 
1926         case HERMON_FLASH_SPI_CMDSET:
1927                 hdl = hermon_get_pcihdl(state);
1928 
1929                 /* the FMA retry loop starts. */
1930                 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1931                     fm_test);
1932 
1933                 /* Issue Write Enable */
1934                 hermon_flash_spi_write_enable(state);
1935 
1936                 /* Set the Address */
1937                 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1938                     addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1939 
1940                 /* Issue Flash Sector Erase */
1941                 hermon_flash_spi_exec_command(state, hdl,
1942                     HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1943                     HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1944                     ((uint32_t)(HERMON_HW_FLASH_SPI_SECTOR_ERASE) <<
1945                     HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1946 
1947                 /* the FMA retry loop ends. */
1948                 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status,
1949                     fm_test);
1950 
1951                 /* Wait for Sector Erase to complete */
1952                 status = hermon_flash_spi_wait_wip(state);
1953                 break;
1954 
1955         case HERMON_FLASH_UNKNOWN_CMDSET:
1956         default:
1957                 cmn_err(CE_WARN,
1958                     "hermon_flash_erase_sector: unknown cmd set: 0x%x\n",
1959                     state->hs_fw_cmdset);
1960                 status = EINVAL;
1961                 break;
1962         }
1963 
1964         /* Reset the flash device */
1965         if (status == 0) {
1966                 status = hermon_flash_reset(state);
1967         }
1968         return (status);
1969 
1970 pio_error:
1971         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1972         return (EIO);
1973 }
1974 
1975 /*
1976  * hermon_flash_erase_chip()
1977  */
1978 static int
1979 hermon_flash_erase_chip(hermon_state_t *state)
1980 {
1981         uint32_t stat;
1982         uint_t size;
1983         int status = 0;
1984         int i;
1985         int num_sect;
1986 
1987         switch (state->hs_fw_cmdset) {
1988         case HERMON_FLASH_AMD_CMDSET:
1989                 /* Issue Flash Chip Erase Command */
1990                 hermon_flash_write(state, 0, 0xAA, &status);
1991                 if (status != 0) {
1992                         return (status);
1993                 }
1994 
1995                 hermon_flash_write(state, 0, 0x55, &status);
1996                 if (status != 0) {
1997                         return (status);
1998                 }
1999 
2000                 hermon_flash_write(state, 0, 0x80, &status);
2001                 if (status != 0) {
2002                         return (status);
2003                 }
2004 
2005                 hermon_flash_write(state, 0, 0xAA, &status);
2006                 if (status != 0) {
2007                         return (status);
2008                 }
2009 
2010                 hermon_flash_write(state, 0, 0x55, &status);
2011                 if (status != 0) {
2012                         return (status);
2013                 }
2014 
2015                 hermon_flash_write(state, 0, 0x10, &status);
2016                 if (status != 0) {
2017                         return (status);
2018                 }
2019 
2020                 /* Wait for Chip Erase to Complete */
2021                 i = 0;
2022                 do {
2023                         drv_usecwait(1);
2024                         stat = hermon_flash_read(state, 0, &status);
2025                         if (status != 0) {
2026                                 return (status);
2027                         }
2028 
2029                         if (i == hermon_hw_flash_timeout_erase) {
2030                                 cmn_err(CE_WARN,
2031                                     "hermon_flash_erase_chip: erase timeout\n");
2032                                 hermon_fm_ereport(state, HCA_SYS_ERR,
2033                                     HCA_ERR_IOCTL);
2034                                 return (EIO);
2035                         }
2036                         i++;
2037                 } while (stat != 0xFFFFFFFF);
2038                 break;
2039 
2040         case HERMON_FLASH_INTEL_CMDSET:
2041         case HERMON_FLASH_SPI_CMDSET:
2042                 /*
2043                  * These chips don't have a chip erase command, so erase
2044                  * all blocks one at a time.
2045                  */
2046                 size = (0x1 << state->hs_fw_log_sector_sz);
2047                 num_sect = state->hs_fw_device_sz / size;
2048 
2049                 for (i = 0; i < num_sect; i++) {
2050                         status = hermon_flash_erase_sector(state, i);
2051                         if (status != 0) {
2052                                 cmn_err(CE_WARN,
2053                                     "hermon_flash_erase_chip: "
2054                                     "sector %d erase error\n", i);
2055                                 return (status);
2056                         }
2057                 }
2058                 break;
2059 
2060         case HERMON_FLASH_UNKNOWN_CMDSET:
2061         default:
2062                 cmn_err(CE_WARN, "hermon_flash_erase_chip: "
2063                     "unknown cmd set: 0x%x\n", state->hs_fw_cmdset);
2064                 status = EINVAL;
2065                 break;
2066         }
2067 
2068         return (status);
2069 }
2070 
2071 /*
2072  * hermon_flash_spi_write_enable()
2073  */
2074 static void
2075 hermon_flash_spi_write_enable(hermon_state_t *state)
2076 {
2077         ddi_acc_handle_t        hdl;
2078 
2079         hdl = hermon_get_pcihdl(state);
2080 
2081         hermon_flash_spi_exec_command(state, hdl,
2082             HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2083             (HERMON_HW_FLASH_SPI_WRITE_ENABLE <<
2084             HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2085 }
2086 
2087 /*
2088  * hermon_flash_spi_wait_wip()
2089  */
2090 static int
2091 hermon_flash_spi_wait_wip(hermon_state_t *state)
2092 {
2093         ddi_acc_handle_t        hdl;
2094         uint32_t                status;
2095 
2096         /* initialize the FMA retry loop */
2097         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2098 
2099         hdl = hermon_get_pcihdl(state);
2100 
2101         /* the FMA retry loop starts. */
2102         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2103             fm_test);
2104 
2105         /* wait on the gateway to clear busy */
2106         do {
2107                 status = hermon_flash_read_cfg(state, hdl,
2108                     HERMON_HW_FLASH_SPI_GW);
2109         } while (status & HERMON_HW_FLASH_SPI_BUSY);
2110 
2111         /* now, get the status and check for WIP to clear */
2112         do {
2113                 hermon_flash_spi_exec_command(state, hdl,
2114                     HERMON_HW_FLASH_SPI_READ_OP |
2115                     HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2116                     HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2117                     HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2118                     (HERMON_HW_FLASH_SPI_READ_STATUS_REG <<
2119                     HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2120 
2121                 status = hermon_flash_read_cfg(state, hdl,
2122                     HERMON_HW_FLASH_SPI_DATA);
2123         } while (status & HERMON_HW_FLASH_SPI_WIP);
2124 
2125         /* the FMA retry loop ends. */
2126         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2127         return (0);
2128 
2129 pio_error:
2130         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2131         return (EIO);
2132 }
2133 
2134 /*
2135  * hermon_flash_bank()
2136  */
2137 static int
2138 hermon_flash_bank(hermon_state_t *state, uint32_t addr)
2139 {
2140         ddi_acc_handle_t        hdl;
2141         uint32_t                bank;
2142 
2143         /* initialize the FMA retry loop */
2144         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2145 
2146         /* Set handle */
2147         hdl = hermon_get_pcihdl(state);
2148 
2149         /* Determine the bank setting from the address */
2150         bank = addr & HERMON_HW_FLASH_BANK_MASK;
2151 
2152         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(state->hs_fw_flashbank))
2153 
2154         /*
2155          * If the bank is different from the currently set bank, we need to
2156          * change it.  Also, if an 'addr' of 0 is given, this allows the
2157          * capability to force the flash bank to 0.  This is useful at init
2158          * time to initially set the bank value
2159          */
2160         if (state->hs_fw_flashbank != bank || addr == 0) {
2161                 switch (state->hs_fw_cmdset) {
2162                 case HERMON_FLASH_SPI_CMDSET:
2163                         /* CMJ: not needed for hermon */
2164                         break;
2165 
2166                 case HERMON_FLASH_INTEL_CMDSET:
2167                 case HERMON_FLASH_AMD_CMDSET:
2168                         /* the FMA retry loop starts. */
2169                         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt,
2170                             fm_status, fm_test);
2171 
2172                         hermon_flash_write_cfg(state, hdl,
2173                             HERMON_HW_FLASH_GPIO_DATACLEAR, 0x70);
2174                         hermon_flash_write_cfg(state, hdl,
2175                             HERMON_HW_FLASH_GPIO_DATASET, (bank >> 15) & 0x70);
2176 
2177                         /* the FMA retry loop ends. */
2178                         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt,
2179                             fm_status, fm_test);
2180                         break;
2181 
2182                 case HERMON_FLASH_UNKNOWN_CMDSET:
2183                 default:
2184                         return (EINVAL);
2185                 }
2186 
2187                 state->hs_fw_flashbank = bank;
2188         }
2189         return (0);
2190 
2191 pio_error:
2192         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2193         return (EIO);
2194 }
2195 
2196 /*
2197  * hermon_flash_spi_exec_command()
2198  */
2199 static void
2200 hermon_flash_spi_exec_command(hermon_state_t *state, ddi_acc_handle_t hdl,
2201     uint32_t cmd)
2202 {
2203         uint32_t data;
2204         int timeout = 0;
2205 
2206         cmd |= HERMON_HW_FLASH_SPI_BUSY | HERMON_HW_FLASH_SPI_ENABLE_OFF;
2207 
2208         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_GW, cmd);
2209 
2210         do {
2211                 data = hermon_flash_read_cfg(state, hdl,
2212                     HERMON_HW_FLASH_SPI_GW);
2213                 timeout++;
2214         } while ((data & HERMON_HW_FLASH_SPI_BUSY) &&
2215             (timeout < hermon_hw_flash_timeout_config));
2216 }
2217 
2218 /*
2219  * hermon_flash_read()
2220  */
2221 static uint32_t
2222 hermon_flash_read(hermon_state_t *state, uint32_t addr, int *err)
2223 {
2224         ddi_acc_handle_t        hdl;
2225         uint32_t                data = 0;
2226         int                     timeout, status = 0;
2227 
2228         /* initialize the FMA retry loop */
2229         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2230 
2231         hdl = hermon_get_pcihdl(state);
2232 
2233         /* the FMA retry loop starts. */
2234         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2235             fm_test);
2236 
2237         switch (state->hs_fw_cmdset) {
2238         case HERMON_FLASH_SPI_CMDSET:
2239                 /* Set the transaction address */
2240                 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
2241                     (addr & HERMON_HW_FLASH_SPI_ADDR_MASK));
2242 
2243                 hermon_flash_spi_exec_command(state, hdl,
2244                     HERMON_HW_FLASH_SPI_READ_OP |
2245                     HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2246                     HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
2247                     HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2248                     HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2249                     (HERMON_HW_FLASH_SPI_READ <<
2250                     HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2251 
2252                 data = hermon_flash_read_cfg(state, hdl,
2253                     HERMON_HW_FLASH_SPI_DATA);
2254                 break;
2255 
2256         case HERMON_FLASH_INTEL_CMDSET:
2257         case HERMON_FLASH_AMD_CMDSET:
2258                 /*
2259                  * The Read operation does the following:
2260                  *   1) Write the masked address to the HERMON_FLASH_ADDR
2261                  *      register. Only the least significant 19 bits are valid.
2262                  *   2) Read back the register until the command has completed.
2263                  *   3) Read the data retrieved from the address at the
2264                  *      HERMON_FLASH_DATA register.
2265                  */
2266                 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2267                     (addr & HERMON_HW_FLASH_ADDR_MASK) | (1 << 29));
2268 
2269                 timeout = 0;
2270                 do {
2271                         data = hermon_flash_read_cfg(state, hdl,
2272                             HERMON_HW_FLASH_ADDR);
2273                         timeout++;
2274                 } while ((data & HERMON_HW_FLASH_CMD_MASK) &&
2275                     (timeout < hermon_hw_flash_timeout_config));
2276 
2277                 if (timeout == hermon_hw_flash_timeout_config) {
2278                         cmn_err(CE_WARN, "hermon_flash_read: command timed "
2279                             "out.\n");
2280                         *err = EIO;
2281                         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2282                         return (data);
2283                 }
2284 
2285                 data = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_DATA);
2286                 break;
2287 
2288         case HERMON_FLASH_UNKNOWN_CMDSET:
2289         default:
2290                 cmn_err(CE_CONT, "hermon_flash_read: unknown cmdset: 0x%x\n",
2291                     state->hs_fw_cmdset);
2292                 status = EINVAL;
2293                 break;
2294         }
2295 
2296 
2297         /* the FMA retry loop ends. */
2298         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2299         *err = status;
2300         return (data);
2301 
2302 pio_error:
2303         *err = EIO;
2304         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2305         return (data);
2306 }
2307 
2308 /*
2309  * hermon_flash_write()
2310  */
2311 static void
2312 hermon_flash_write(hermon_state_t *state, uint32_t addr, uchar_t data, int *err)
2313 {
2314         ddi_acc_handle_t        hdl;
2315         int                     cmd;
2316         int                     timeout;
2317 
2318         /* initialize the FMA retry loop */
2319         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2320 
2321         hdl = hermon_get_pcihdl(state);
2322 
2323         /* the FMA retry loop starts. */
2324         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2325             fm_test);
2326 
2327         /*
2328          * The Write operation does the following:
2329          *   1) Write the data to be written to the HERMON_FLASH_DATA offset.
2330          *   2) Write the address to write the data to to the HERMON_FLASH_ADDR
2331          *      offset.
2332          *   3) Wait until the write completes.
2333          */
2334 
2335         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_DATA, data << 24);
2336         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2337             (addr & 0x7FFFF) | (2 << 29));
2338 
2339         timeout = 0;
2340         do {
2341                 cmd = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_ADDR);
2342                 timeout++;
2343         } while ((cmd & HERMON_HW_FLASH_CMD_MASK) &&
2344             (timeout < hermon_hw_flash_timeout_config));
2345 
2346         if (timeout == hermon_hw_flash_timeout_config) {
2347                 cmn_err(CE_WARN, "hermon_flash_write: config cmd timeout.\n");
2348                 *err = EIO;
2349                 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2350                 return;
2351         }
2352 
2353         /* the FMA retry loop ends. */
2354         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2355         *err = 0;
2356         return;
2357 
2358 pio_error:
2359         *err = EIO;
2360         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2361 }
2362 
2363 /*
2364  * hermon_flash_init()
2365  */
2366 static int
2367 hermon_flash_init(hermon_state_t *state)
2368 {
2369         uint32_t                word;
2370         ddi_acc_handle_t        hdl;
2371         int                     sema_cnt;
2372         int                     gpio;
2373 
2374         /* initialize the FMA retry loop */
2375         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2376 
2377         /* Set handle */
2378         hdl = hermon_get_pcihdl(state);
2379 
2380         /* the FMA retry loop starts. */
2381         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2382             fm_test);
2383 
2384         /* Init the flash */
2385 
2386 #ifdef DO_WRCONF
2387         /*
2388          * Grab the WRCONF semaphore.
2389          */
2390         word = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_WRCONF_SEMA);
2391 #endif
2392 
2393         /*
2394          * Grab the GPIO semaphore.  This allows us exclusive access to the
2395          * GPIO settings on the Hermon for the duration of the flash burning
2396          * procedure.
2397          */
2398         sema_cnt = 0;
2399         do {
2400                 word = hermon_flash_read_cfg(state, hdl,
2401                     HERMON_HW_FLASH_GPIO_SEMA);
2402                 if (word == 0) {
2403                         break;
2404                 }
2405 
2406                 sema_cnt++;
2407                 drv_usecwait(1);
2408 
2409         } while (sema_cnt < hermon_hw_flash_timeout_gpio_sema);
2410 
2411         /*
2412          * Determine if we timed out trying to grab the GPIO semaphore
2413          */
2414         if (sema_cnt == hermon_hw_flash_timeout_gpio_sema) {
2415                 cmn_err(CE_WARN, "hermon_flash_init: GPIO SEMA timeout\n");
2416                 cmn_err(CE_WARN, "GPIO_SEMA value: 0x%x\n", word);
2417                 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2418                 return (EIO);
2419         }
2420 
2421         /* Save away original GPIO Values */
2422         state->hs_fw_gpio[0] = hermon_flash_read_cfg(state, hdl,
2423             HERMON_HW_FLASH_GPIO_DATA);
2424 
2425         /* Set new GPIO value */
2426         gpio = state->hs_fw_gpio[0] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2427         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA, gpio);
2428 
2429         /* Save away original GPIO Values */
2430         state->hs_fw_gpio[1] = hermon_flash_read_cfg(state, hdl,
2431             HERMON_HW_FLASH_GPIO_MOD0);
2432         state->hs_fw_gpio[2] = hermon_flash_read_cfg(state, hdl,
2433             HERMON_HW_FLASH_GPIO_MOD1);
2434 
2435         /* unlock GPIO */
2436         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2437             HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2438 
2439         /*
2440          * Set new GPIO values
2441          */
2442         gpio = state->hs_fw_gpio[1] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2443         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0, gpio);
2444 
2445         gpio = state->hs_fw_gpio[2] & ~HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2446         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1, gpio);
2447 
2448         /* re-lock GPIO */
2449         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2450 
2451         /* Set CPUMODE to enable hermon to access the flash device */
2452         /* CMJ This code came from arbel.  Hermon doesn't seem to need it. */
2453         /*
2454          *      hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_CPUMODE,
2455          *          1 << HERMON_HW_FLASH_CPU_SHIFT);
2456          */
2457 
2458         /* the FMA retry loop ends. */
2459         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2460         return (0);
2461 
2462 pio_error:
2463         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2464         return (EIO);
2465 }
2466 
2467 /*
2468  * hermon_flash_cfi_init
2469  *   Implements access to the CFI (Common Flash Interface) data
2470  */
2471 static int
2472 hermon_flash_cfi_init(hermon_state_t *state, uint32_t *cfi_info,
2473     int *intel_xcmd)
2474 {
2475         uint32_t        data;
2476         uint32_t        sector_sz_bytes;
2477         uint32_t        bit_count;
2478         uint8_t         cfi_ch_info[HERMON_CFI_INFO_SIZE];
2479         uint32_t        cfi_dw_info[HERMON_CFI_INFO_QSIZE];
2480         int             i;
2481         int             status;
2482 
2483         /* Right now, all hermon cards use SPI. */
2484         if (hermon_device_mode(state)) {
2485                 /*
2486                  * Don't use CFI for SPI part. Just fill in what we need
2487                  * and return.
2488                  */
2489                 state->hs_fw_cmdset = HERMON_FLASH_SPI_CMDSET;
2490                 state->hs_fw_log_sector_sz = HERMON_FLASH_SPI_LOG_SECTOR_SIZE;
2491                 state->hs_fw_device_sz = HERMON_FLASH_SPI_DEVICE_SIZE;
2492 
2493                 /*
2494                  * set this to inform caller of cmdset type.
2495                  */
2496                 cfi_ch_info[0x13] = HERMON_FLASH_SPI_CMDSET;
2497                 hermon_flash_cfi_dword(&cfi_info[4], cfi_ch_info, 0x10);
2498                 return (0);
2499         }
2500 
2501         /*
2502          * Determine if the user command supports the Intel Extended
2503          * Command Set. The query string is contained in the fourth
2504          * quad word.
2505          */
2506         hermon_flash_cfi_byte(cfi_ch_info, cfi_info[0x04], 0x10);
2507         if (cfi_ch_info[0x10] == 'M' &&
2508             cfi_ch_info[0x11] == 'X' &&
2509             cfi_ch_info[0x12] == '2') {
2510                 *intel_xcmd = 1; /* support is there */
2511                 if (hermon_verbose) {
2512                         IBTF_DPRINTF_L2("hermon",
2513                             "Support for Intel X is present\n");
2514                 }
2515         }
2516 
2517         /* CFI QUERY */
2518         hermon_flash_write(state, 0x55, HERMON_FLASH_CFI_INIT, &status);
2519         if (status != 0) {
2520                 return (status);
2521         }
2522 
2523         /* temporarily set the cmdset in order to do the initial read */
2524         state->hs_fw_cmdset = HERMON_FLASH_INTEL_CMDSET;
2525 
2526         /* Read in CFI data */
2527         for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 4) {
2528                 data = hermon_flash_read(state, i, &status);
2529                 if (status != 0) {
2530                         return (status);
2531                 }
2532                 cfi_dw_info[i >> 2] = data;
2533                 hermon_flash_cfi_byte(cfi_ch_info, data, i);
2534         }
2535 
2536         /* Determine chip set */
2537         state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2538         if (cfi_ch_info[0x20] == 'Q' &&
2539             cfi_ch_info[0x22] == 'R' &&
2540             cfi_ch_info[0x24] == 'Y') {
2541                 /*
2542                  * Mode: x16 working in x8 mode (Intel).
2543                  * Pack data - skip spacing bytes.
2544                  */
2545                 if (hermon_verbose) {
2546                         IBTF_DPRINTF_L2("hermon",
2547                             "x16 working in x8 mode (Intel)\n");
2548                 }
2549                 for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 2) {
2550                         cfi_ch_info[i/2] = cfi_ch_info[i];
2551                 }
2552         }
2553         state->hs_fw_cmdset = cfi_ch_info[0x13];
2554 
2555         if (state->hs_fw_cmdset != HERMON_FLASH_INTEL_CMDSET &&
2556             state->hs_fw_cmdset != HERMON_FLASH_AMD_CMDSET) {
2557                 cmn_err(CE_WARN,
2558                     "hermon_flash_cfi_init: UNKNOWN chip cmd set 0x%04x\n",
2559                     state->hs_fw_cmdset);
2560                 state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2561                 return (0);
2562         }
2563 
2564         /* Determine total bytes in one sector size */
2565         sector_sz_bytes = ((cfi_ch_info[0x30] << 8) | cfi_ch_info[0x2F]) << 8;
2566 
2567         /* Calculate equivalent of log2 (n) */
2568         for (bit_count = 0; sector_sz_bytes > 1; bit_count++) {
2569                 sector_sz_bytes >>= 1;
2570         }
2571 
2572         /* Set sector size */
2573         state->hs_fw_log_sector_sz = bit_count;
2574 
2575         /* Set flash size */
2576         state->hs_fw_device_sz = 0x1 << cfi_ch_info[0x27];
2577 
2578         /* Reset to turn off CFI mode */
2579         if ((status = hermon_flash_reset(state)) != 0)
2580                 goto out;
2581 
2582         /* Pass CFI data back to user command. */
2583         for (i = 0; i < HERMON_FLASH_CFI_SIZE_QUADLET; i++) {
2584                 hermon_flash_cfi_dword(&cfi_info[i], cfi_ch_info, i << 2);
2585         }
2586 
2587         if (*intel_xcmd == 1) {
2588                 /*
2589                  * Inform the user cmd that this driver does support the
2590                  * Intel Extended Command Set.
2591                  */
2592                 cfi_ch_info[0x10] = 'M';
2593                 cfi_ch_info[0x11] = 'X';
2594                 cfi_ch_info[0x12] = '2';
2595         } else {
2596                 cfi_ch_info[0x10] = 'Q';
2597                 cfi_ch_info[0x11] = 'R';
2598                 cfi_ch_info[0x12] = 'Y';
2599         }
2600         cfi_ch_info[0x13] = state->hs_fw_cmdset;
2601         hermon_flash_cfi_dword(&cfi_info[0x4], cfi_ch_info, 0x10);
2602 out:
2603         return (status);
2604 }
2605 
2606 /*
2607  * hermon_flash_fini()
2608  */
2609 static int
2610 hermon_flash_fini(hermon_state_t *state)
2611 {
2612         int status;
2613         ddi_acc_handle_t hdl;
2614 
2615         /* initialize the FMA retry loop */
2616         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2617 
2618         /* Set handle */
2619         hdl = hermon_get_pcihdl(state);
2620 
2621         if ((status = hermon_flash_bank(state, 0)) != 0)
2622                 return (status);
2623 
2624         /* the FMA retry loop starts. */
2625         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2626             fm_test);
2627 
2628         /*
2629          * Restore original GPIO Values
2630          */
2631         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA,
2632             state->hs_fw_gpio[0]);
2633 
2634         /* unlock GPIOs */
2635         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2636             HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2637 
2638         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0,
2639             state->hs_fw_gpio[1]);
2640         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1,
2641             state->hs_fw_gpio[2]);
2642 
2643         /* re-lock GPIOs */
2644         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2645 
2646         /* Give up gpio semaphore */
2647         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_SEMA, 0);
2648 
2649         /* the FMA retry loop ends. */
2650         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2651         return (0);
2652 
2653 pio_error:
2654         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2655         return (EIO);
2656 }
2657 
2658 /*
2659  * hermon_flash_read_cfg
2660  */
2661 static uint32_t
2662 hermon_flash_read_cfg(hermon_state_t *state, ddi_acc_handle_t pci_config_hdl,
2663     uint32_t addr)
2664 {
2665         uint32_t        read;
2666 
2667         if (do_bar0) {
2668                 read = ddi_get32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2669                     (state->hs_reg_cmd_baseaddr + addr));
2670         } else {
2671                 /*
2672                  * Perform flash read operation:
2673                  *   1) Place addr to read from on the HERMON_HW_FLASH_CFG_ADDR
2674                  *      register
2675                  *   2) Read data at that addr from the HERMON_HW_FLASH_CFG_DATA
2676                  *       register
2677                  */
2678                 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2679                     addr);
2680                 read = pci_config_get32(pci_config_hdl,
2681                     HERMON_HW_FLASH_CFG_DATA);
2682         }
2683 
2684         return (read);
2685 }
2686 
2687 #ifdef DO_WRCONF
2688 static void
2689 hermon_flash_write_cfg(hermon_state_t *state,
2690     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2691 {
2692         hermon_flash_write_cfg_helper(state, pci_config_hdl, addr, data);
2693         hermon_flash_write_confirm(state, pci_config_hdl);
2694 }
2695 
2696 static void
2697 hermon_flash_write_confirm(hermon_state_t *state,
2698     ddi_acc_handle_t pci_config_hdl)
2699 {
2700         uint32_t        sem_value = 1;
2701 
2702         hermon_flash_write_cfg_helper(state, pci_config_hdl,
2703             HERMON_HW_FLASH_WRCONF_SEMA, 0);
2704         while (sem_value) {
2705                 sem_value = hermon_flash_read_cfg(state, pci_config_hdl,
2706                     HERMON_HW_FLASH_WRCONF_SEMA);
2707         }
2708 }
2709 #endif
2710 
2711 /*
2712  * hermon_flash_write_cfg
2713  */
2714 static void
2715 #ifdef DO_WRCONF
2716 hermon_flash_write_cfg_helper(hermon_state_t *state,
2717     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2718 #else
2719 hermon_flash_write_cfg(hermon_state_t *state,
2720     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2721 #endif
2722 {
2723         if (do_bar0) {
2724                 ddi_put32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2725                     (state->hs_reg_cmd_baseaddr + addr), data);
2726 
2727         } else {
2728 
2729                 /*
2730                  * Perform flash write operation:
2731                  *   1) Place addr to write to on the HERMON_HW_FLASH_CFG_ADDR
2732                  *      register
2733                  *   2) Place data to write on to the HERMON_HW_FLASH_CFG_DATA
2734                  *      register
2735                  */
2736                 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2737                     addr);
2738                 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_DATA,
2739                     data);
2740         }
2741 }
2742 
2743 /*
2744  * Support routines to convert Common Flash Interface (CFI) data
2745  * from a 32  bit word to a char array, and from a char array to
2746  * a 32 bit word.
2747  */
2748 static void
2749 hermon_flash_cfi_byte(uint8_t *ch, uint32_t dword, int i)
2750 {
2751         ch[i] = (uint8_t)((dword & 0xFF000000) >> 24);
2752         ch[i+1] = (uint8_t)((dword & 0x00FF0000) >> 16);
2753         ch[i+2] = (uint8_t)((dword & 0x0000FF00) >> 8);
2754         ch[i+3] = (uint8_t)((dword & 0x000000FF));
2755 }
2756 
2757 static void
2758 hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i)
2759 {
2760         *dword = (uint32_t)
2761             ((uint32_t)ch[i] << 24 |
2762             (uint32_t)ch[i+1] << 16 |
2763             (uint32_t)ch[i+2] << 8 |
2764             (uint32_t)ch[i+3]);
2765 }
2766 
2767 /*
2768  * hermon_loopback_free_qps
2769  */
2770 static void
2771 hermon_loopback_free_qps(hermon_loopback_state_t *lstate)
2772 {
2773         int i;
2774 
2775         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2776 
2777         if (lstate->hls_tx.hlc_qp_hdl != NULL) {
2778                 (void) hermon_qp_free(lstate->hls_state,
2779                     &lstate->hls_tx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2780                     HERMON_NOSLEEP);
2781         }
2782         if (lstate->hls_rx.hlc_qp_hdl != NULL) {
2783                 (void) hermon_qp_free(lstate->hls_state,
2784                     &lstate->hls_rx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2785                     HERMON_NOSLEEP);
2786         }
2787         lstate->hls_tx.hlc_qp_hdl = NULL;
2788         lstate->hls_rx.hlc_qp_hdl = NULL;
2789         for (i = 0; i < 2; i++) {
2790                 if (lstate->hls_tx.hlc_cqhdl[i] != NULL) {
2791                         (void) hermon_cq_free(lstate->hls_state,
2792                             &lstate->hls_tx.hlc_cqhdl[i], HERMON_NOSLEEP);
2793                 }
2794                 if (lstate->hls_rx.hlc_cqhdl[i] != NULL) {
2795                         (void) hermon_cq_free(lstate->hls_state,
2796                             &lstate->hls_rx.hlc_cqhdl[i], HERMON_NOSLEEP);
2797                 }
2798                 lstate->hls_tx.hlc_cqhdl[i] = NULL;
2799                 lstate->hls_rx.hlc_cqhdl[i] = NULL;
2800         }
2801 }
2802 
2803 /*
2804  * hermon_loopback_free_state
2805  */
2806 static void
2807 hermon_loopback_free_state(hermon_loopback_state_t *lstate)
2808 {
2809         hermon_loopback_free_qps(lstate);
2810         if (lstate->hls_tx.hlc_mrhdl != NULL) {
2811                 (void) hermon_mr_deregister(lstate->hls_state,
2812                     &lstate->hls_tx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2813                     HERMON_NOSLEEP);
2814         }
2815         if (lstate->hls_rx.hlc_mrhdl !=  NULL) {
2816                 (void) hermon_mr_deregister(lstate->hls_state,
2817                     &lstate->hls_rx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2818                     HERMON_NOSLEEP);
2819         }
2820         if (lstate->hls_pd_hdl != NULL) {
2821                 (void) hermon_pd_free(lstate->hls_state, &lstate->hls_pd_hdl);
2822         }
2823         if (lstate->hls_tx.hlc_buf != NULL) {
2824                 kmem_free(lstate->hls_tx.hlc_buf, lstate->hls_tx.hlc_buf_sz);
2825         }
2826         if (lstate->hls_rx.hlc_buf != NULL) {
2827                 kmem_free(lstate->hls_rx.hlc_buf, lstate->hls_rx.hlc_buf_sz);
2828         }
2829         bzero(lstate, sizeof (hermon_loopback_state_t));
2830 }
2831 
2832 /*
2833  * hermon_loopback_init
2834  */
2835 static int
2836 hermon_loopback_init(hermon_state_t *state, hermon_loopback_state_t *lstate)
2837 {
2838         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2839 
2840         lstate->hls_hca_hdl = (ibc_hca_hdl_t)state;
2841         lstate->hls_status  = hermon_pd_alloc(lstate->hls_state,
2842             &lstate->hls_pd_hdl, HERMON_NOSLEEP);
2843         if (lstate->hls_status != IBT_SUCCESS) {
2844                 lstate->hls_err = HERMON_LOOPBACK_PROT_DOMAIN_ALLOC_FAIL;
2845                 return (EFAULT);
2846         }
2847 
2848         return (0);
2849 }
2850 
2851 /*
2852  * hermon_loopback_init_qp_info
2853  */
2854 static void
2855 hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
2856     hermon_loopback_comm_t *comm)
2857 {
2858         bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2859         bzero(&comm->hlc_qp_attr, sizeof (ibt_qp_alloc_attr_t));
2860         bzero(&comm->hlc_qp_info, sizeof (ibt_qp_info_t));
2861 
2862         comm->hlc_wrid = 1;
2863         comm->hlc_cq_attr.cq_size = 128;
2864         comm->hlc_qp_attr.qp_sizes.cs_sq_sgl = 3;
2865         comm->hlc_qp_attr.qp_sizes.cs_rq_sgl = 3;
2866         comm->hlc_qp_attr.qp_sizes.cs_sq = 16;
2867         comm->hlc_qp_attr.qp_sizes.cs_rq = 16;
2868         comm->hlc_qp_attr.qp_flags = IBT_WR_SIGNALED;
2869 
2870         comm->hlc_qp_info.qp_state = IBT_STATE_RESET;
2871         comm->hlc_qp_info.qp_trans = IBT_RC_SRV;
2872         comm->hlc_qp_info.qp_flags = IBT_CEP_RDMA_RD | IBT_CEP_RDMA_WR;
2873         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
2874             lstate->hls_port;
2875         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_pkey_ix =
2876             lstate->hls_pkey_ix;
2877         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_timeout =
2878             lstate->hls_timeout;
2879         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srvl = 0;
2880         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srate =
2881             IBT_SRATE_4X;
2882         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_send_grh = 0;
2883         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid =
2884             lstate->hls_lid;
2885         comm->hlc_qp_info.qp_transport.rc.rc_retry_cnt = lstate->hls_retry;
2886         comm->hlc_qp_info.qp_transport.rc.rc_sq_psn = 0;
2887         comm->hlc_qp_info.qp_transport.rc.rc_rq_psn = 0;
2888         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_in       = 4;
2889         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_out = 4;
2890         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = 0;
2891         comm->hlc_qp_info.qp_transport.rc.rc_min_rnr_nak = IBT_RNR_NAK_655ms;
2892         comm->hlc_qp_info.qp_transport.rc.rc_path_mtu = IB_MTU_1K;
2893 }
2894 
2895 /*
2896  * hermon_loopback_alloc_mem
2897  */
2898 static int
2899 hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
2900     hermon_loopback_comm_t *comm, int sz)
2901 {
2902         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2903 
2904         /* Allocate buffer of specified size */
2905         comm->hlc_buf_sz = sz;
2906         comm->hlc_buf         = kmem_zalloc(sz, KM_NOSLEEP);
2907         if (comm->hlc_buf == NULL) {
2908                 return (EFAULT);
2909         }
2910 
2911         /* Register the buffer as a memory region */
2912         comm->hlc_memattr.mr_vaddr = (uint64_t)(uintptr_t)comm->hlc_buf;
2913         comm->hlc_memattr.mr_len   = (ib_msglen_t)sz;
2914         comm->hlc_memattr.mr_as         = NULL;
2915         comm->hlc_memattr.mr_flags = IBT_MR_NOSLEEP |
2916             IBT_MR_ENABLE_REMOTE_WRITE | IBT_MR_ENABLE_LOCAL_WRITE;
2917 
2918         comm->hlc_status = hermon_mr_register(lstate->hls_state,
2919             lstate->hls_pd_hdl, &comm->hlc_memattr, &comm->hlc_mrhdl,
2920             NULL, HERMON_MPT_DMPT);
2921 
2922         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm->hlc_mrhdl))
2923 
2924         comm->hlc_mrdesc.md_vaddr  = comm->hlc_mrhdl->mr_bindinfo.bi_addr;
2925         comm->hlc_mrdesc.md_lkey   = comm->hlc_mrhdl->mr_lkey;
2926         comm->hlc_mrdesc.md_rkey   = comm->hlc_mrhdl->mr_rkey;
2927         if (comm->hlc_status != IBT_SUCCESS) {
2928                 return (EFAULT);
2929         }
2930         return (0);
2931 }
2932 
2933 /*
2934  * hermon_loopback_alloc_qps
2935  */
2936 static int
2937 hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
2938     hermon_loopback_comm_t *comm)
2939 {
2940         uint32_t                i, real_size;
2941         hermon_qp_info_t                qpinfo;
2942 
2943         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2944         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2945 
2946         /* Allocate send and recv CQs */
2947         for (i = 0; i < 2; i++) {
2948                 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2949                 comm->hlc_cq_attr.cq_size = 128;
2950                 comm->hlc_status = hermon_cq_alloc(lstate->hls_state,
2951                     (ibt_cq_hdl_t)NULL, &comm->hlc_cq_attr, &real_size,
2952                     &comm->hlc_cqhdl[i], HERMON_NOSLEEP);
2953                 if (comm->hlc_status != IBT_SUCCESS) {
2954                         lstate->hls_err += i;
2955                         return (EFAULT);
2956                 }
2957         }
2958 
2959         /* Allocate the QP */
2960         hermon_loopback_init_qp_info(lstate, comm);
2961         comm->hlc_qp_attr.qp_pd_hdl   = (ibt_pd_hdl_t)lstate->hls_pd_hdl;
2962         comm->hlc_qp_attr.qp_scq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[0];
2963         comm->hlc_qp_attr.qp_rcq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[1];
2964         comm->hlc_qp_attr.qp_ibc_scq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[0];
2965         comm->hlc_qp_attr.qp_ibc_rcq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[1];
2966         qpinfo.qpi_attrp        = &comm->hlc_qp_attr;
2967         qpinfo.qpi_type         = IBT_RC_RQP;
2968         qpinfo.qpi_ibt_qphdl    = NULL;
2969         qpinfo.qpi_queueszp     = &comm->hlc_chan_sizes;
2970         qpinfo.qpi_qpn          = &comm->hlc_qp_num;
2971         comm->hlc_status = hermon_qp_alloc(lstate->hls_state, &qpinfo,
2972             HERMON_NOSLEEP);
2973         if (comm->hlc_status == DDI_SUCCESS) {
2974                 comm->hlc_qp_hdl = qpinfo.qpi_qphdl;
2975         }
2976 
2977         if (comm->hlc_status != IBT_SUCCESS) {
2978                 lstate->hls_err += 2;
2979                 return (EFAULT);
2980         }
2981         return (0);
2982 }
2983 
2984 /*
2985  * hermon_loopback_modify_qp
2986  */
2987 static int
2988 hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
2989     hermon_loopback_comm_t *comm, uint_t qp_num)
2990 {
2991         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2992         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2993 
2994         /* Modify QP to INIT */
2995         hermon_loopback_init_qp_info(lstate, comm);
2996         comm->hlc_qp_info.qp_state = IBT_STATE_INIT;
2997         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2998             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2999         if (comm->hlc_status != IBT_SUCCESS) {
3000                 return (EFAULT);
3001         }
3002 
3003         /*
3004          * Modify QP to RTR (set destination LID and QP number to local
3005          * LID and QP number)
3006          */
3007         comm->hlc_qp_info.qp_state = IBT_STATE_RTR;
3008         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid
3009             = lstate->hls_lid;
3010         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = qp_num;
3011         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3012             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3013         if (comm->hlc_status != IBT_SUCCESS) {
3014                 lstate->hls_err += 1;
3015                 return (EFAULT);
3016         }
3017 
3018         /* Modify QP to RTS */
3019         comm->hlc_qp_info.qp_current_state = IBT_STATE_RTR;
3020         comm->hlc_qp_info.qp_state = IBT_STATE_RTS;
3021         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3022             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3023         if (comm->hlc_status != IBT_SUCCESS) {
3024                 lstate->hls_err += 2;
3025                 return (EFAULT);
3026         }
3027         return (0);
3028 }
3029 
3030 /*
3031  * hermon_loopback_copyout
3032  */
3033 static int
3034 hermon_loopback_copyout(hermon_loopback_ioctl_t *lb, intptr_t arg, int mode)
3035 {
3036 #ifdef _MULTI_DATAMODEL
3037         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
3038                 hermon_loopback_ioctl32_t lb32;
3039 
3040                 lb32.alb_revision       = lb->alb_revision;
3041                 lb32.alb_send_buf       =
3042                     (caddr32_t)(uintptr_t)lb->alb_send_buf;
3043                 lb32.alb_fail_buf       =
3044                     (caddr32_t)(uintptr_t)lb->alb_fail_buf;
3045                 lb32.alb_buf_sz         = lb->alb_buf_sz;
3046                 lb32.alb_num_iter       = lb->alb_num_iter;
3047                 lb32.alb_pass_done      = lb->alb_pass_done;
3048                 lb32.alb_timeout        = lb->alb_timeout;
3049                 lb32.alb_error_type     = lb->alb_error_type;
3050                 lb32.alb_port_num       = lb->alb_port_num;
3051                 lb32.alb_num_retry      = lb->alb_num_retry;
3052 
3053                 if (ddi_copyout(&lb32, (void *)arg,
3054                     sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
3055                         return (EFAULT);
3056                 }
3057         } else
3058 #endif /* _MULTI_DATAMODEL */
3059         if (ddi_copyout(lb, (void *)arg, sizeof (hermon_loopback_ioctl_t),
3060             mode) != 0) {
3061                 return (EFAULT);
3062         }
3063         return (0);
3064 }
3065 
3066 /*
3067  * hermon_loopback_post_send
3068  */
3069 static int
3070 hermon_loopback_post_send(hermon_loopback_state_t *lstate,
3071     hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx)
3072 {
3073         int      ret;
3074 
3075         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tx))
3076 
3077         bzero(&tx->hlc_sgl, sizeof (ibt_wr_ds_t));
3078         bzero(&tx->hlc_wr, sizeof (ibt_send_wr_t));
3079 
3080         /* Initialize local address for TX buffer */
3081         tx->hlc_sgl.ds_va   = tx->hlc_mrdesc.md_vaddr;
3082         tx->hlc_sgl.ds_key  = tx->hlc_mrdesc.md_lkey;
3083         tx->hlc_sgl.ds_len  = tx->hlc_buf_sz;
3084 
3085         /* Initialize the remaining details of the work request */
3086         tx->hlc_wr.wr_id = tx->hlc_wrid++;
3087         tx->hlc_wr.wr_flags  = IBT_WR_SEND_SIGNAL;
3088         tx->hlc_wr.wr_nds    = 1;
3089         tx->hlc_wr.wr_sgl    = &tx->hlc_sgl;
3090         tx->hlc_wr.wr_opcode = IBT_WRC_RDMAW;
3091         tx->hlc_wr.wr_trans  = IBT_RC_SRV;
3092 
3093         /* Initialize the remote address for RX buffer */
3094         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_raddr = rx->hlc_mrdesc.md_vaddr;
3095         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_rkey  = rx->hlc_mrdesc.md_rkey;
3096         tx->hlc_complete = 0;
3097         ret = hermon_post_send(lstate->hls_state, tx->hlc_qp_hdl, &tx->hlc_wr,
3098             1, NULL);
3099         if (ret != IBT_SUCCESS) {
3100                 return (EFAULT);
3101         }
3102         return (0);
3103 }
3104 
3105 /*
3106  * hermon_loopback_poll_cq
3107  */
3108 static int
3109 hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
3110     hermon_loopback_comm_t *comm)
3111 {
3112         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
3113 
3114         comm->hlc_wc.wc_status       = 0;
3115         comm->hlc_num_polled = 0;
3116         comm->hlc_status = hermon_cq_poll(lstate->hls_state,
3117             comm->hlc_cqhdl[0], &comm->hlc_wc, 1, &comm->hlc_num_polled);
3118         if ((comm->hlc_status == IBT_SUCCESS) &&
3119             (comm->hlc_wc.wc_status != IBT_WC_SUCCESS)) {
3120                 comm->hlc_status = ibc_get_ci_failure(0);
3121         }
3122         return (comm->hlc_status);
3123 }