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         /*
 877          * Setup the number of ports, then loop through all ports and
 878          * query properties of each.
 879          */
 880         info.ap_num_ports = (uint8_t)state->hs_cfg_profile->cp_num_ports;
 881         for (i = 0; i < info.ap_num_ports; i++) {
 882                 /*
 883                  * Get portstate information from the device.  If
 884                  * hermon_port_query() fails, leave zeroes in user
 885                  * struct port entry and continue.
 886                  */
 887                 bzero(&pi, sizeof (ibt_hca_portinfo_t));
 888                 pi.p_sgid_tbl = sgid_tbl;
 889                 pi.p_pkey_tbl = pkey_tbl;
 890                 (void) hermon_port_query(state, i + 1, &pi);
 891 
 892                 portstat.asp_port_num   = pi.p_port_num;
 893                 portstat.asp_state      = pi.p_linkstate;
 894                 portstat.asp_guid       = pi.p_sgid_tbl[0].gid_guid;
 895 
 896                 /*
 897                  * Copy queried port results back to user struct.  If
 898                  * this fails, then break out of loop, attempt to copy
 899                  * out remaining info to user struct, and return (without
 900                  * error).
 901                  */
 902                 if (ddi_copyout(&portstat,
 903                     &(((hermon_stat_port_ioctl_t *)info.ap_ports)[i]),
 904                     sizeof (hermon_stat_port_ioctl_t), mode) != 0) {
 905                         break;
 906                 }
 907         }
 908 
 909         /* Free the temporary space used for GID table/PKey table */
 910         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
 911         kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
 912         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
 913         kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
 914 
 915         /* Copy ioctl results back to user struct */
 916 #ifdef _MULTI_DATAMODEL
 917         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 918                 hermon_ports_ioctl32_t info32;
 919 
 920                 info32.ap_revision  = info.ap_revision;
 921                 info32.ap_ports     = (caddr32_t)(uintptr_t)info.ap_ports;
 922                 info32.ap_num_ports = info.ap_num_ports;
 923 
 924                 if (ddi_copyout(&info32, (void *)arg,
 925                     sizeof (hermon_ports_ioctl32_t), mode) != 0) {
 926                         return (EFAULT);
 927                 }
 928         } else
 929 #endif /* _MULTI_DATAMODEL */
 930         if (ddi_copyout(&info, (void *)arg, sizeof (hermon_ports_ioctl_t),
 931             mode) != 0) {
 932                 return (EFAULT);
 933         }
 934 
 935         return (0);
 936 }
 937 
 938 /*
 939  * hermon_ioctl_loopback()
 940  */
 941 static int
 942 hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg, int mode)
 943 {
 944         hermon_loopback_ioctl_t lb;
 945         hermon_loopback_state_t lstate;
 946         ibt_hca_portinfo_t      pi;
 947         uint_t                  tbl_size, loopmax, max_usec;
 948         ib_gid_t                *sgid_tbl;
 949         ib_pkey_t               *pkey_tbl;
 950         int                     j, iter, ret;
 951 
 952         /*
 953          * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
 954          */
 955         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
 956                 return (EFAULT);
 957         }
 958 
 959         /* copyin the user struct to kernel */
 960 #ifdef _MULTI_DATAMODEL
 961         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 962                 hermon_loopback_ioctl32_t lb32;
 963 
 964                 if (ddi_copyin((void *)arg, &lb32,
 965                     sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
 966                         return (EFAULT);
 967                 }
 968                 lb.alb_revision     = lb32.alb_revision;
 969                 lb.alb_send_buf     = (caddr_t)(uintptr_t)lb32.alb_send_buf;
 970                 lb.alb_fail_buf     = (caddr_t)(uintptr_t)lb32.alb_fail_buf;
 971                 lb.alb_buf_sz       = lb32.alb_buf_sz;
 972                 lb.alb_num_iter     = lb32.alb_num_iter;
 973                 lb.alb_pass_done    = lb32.alb_pass_done;
 974                 lb.alb_timeout      = lb32.alb_timeout;
 975                 lb.alb_error_type   = lb32.alb_error_type;
 976                 lb.alb_port_num     = lb32.alb_port_num;
 977                 lb.alb_num_retry    = lb32.alb_num_retry;
 978         } else
 979 #endif /* _MULTI_DATAMODEL */
 980         if (ddi_copyin((void *)arg, &lb, sizeof (hermon_loopback_ioctl_t),
 981             mode) != 0) {
 982                 return (EFAULT);
 983         }
 984 
 985         /* Initialize the internal loopback test state structure */
 986         bzero(&lstate, sizeof (hermon_loopback_state_t));
 987 
 988         /*
 989          * Check ioctl revision
 990          */
 991         if (lb.alb_revision != HERMON_VTS_IOCTL_REVISION) {
 992                 lb.alb_error_type = HERMON_LOOPBACK_INVALID_REVISION;
 993                 (void) hermon_loopback_copyout(&lb, arg, mode);
 994                 return (EINVAL);
 995         }
 996 
 997         /* Validate that specified port number is legal */
 998         if (!hermon_portnum_is_valid(state, lb.alb_port_num)) {
 999                 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1000                 (void) hermon_loopback_copyout(&lb, arg, mode);
1001                 return (EINVAL);
1002         }
1003 
1004         /* Allocate space for temporary GID table/PKey table */
1005         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1006         sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
1007             KM_SLEEP);
1008         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1009         pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
1010             KM_SLEEP);
1011 
1012         /*
1013          * Get portstate information from specific port on device
1014          */
1015         bzero(&pi, sizeof (ibt_hca_portinfo_t));
1016         pi.p_sgid_tbl = sgid_tbl;
1017         pi.p_pkey_tbl = pkey_tbl;
1018         if (hermon_port_query(state, lb.alb_port_num, &pi) != 0) {
1019                 /* Free the temporary space used for GID table/PKey table */
1020                 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1021                 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1022                 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1023                 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1024 
1025                 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1026                 (void) hermon_loopback_copyout(&lb, arg, mode);
1027                 hermon_loopback_free_state(&lstate);
1028                 return (EINVAL);
1029         }
1030 
1031         lstate.hls_port    = pi.p_port_num;
1032         lstate.hls_lid     = pi.p_base_lid;
1033         lstate.hls_pkey_ix = (pi.p_linkstate == HERMON_PORT_LINK_ACTIVE) ?
1034             1 : 0;      /* XXX bogus assumption of a SUN subnet manager */
1035         lstate.hls_state   = state;
1036         lstate.hls_retry   = lb.alb_num_retry;
1037 
1038         /* Free the temporary space used for GID table/PKey table */
1039         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1040         kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1041         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1042         kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1043 
1044         /*
1045          * Compute the timeout duration in usec per the formula:
1046          *    to_usec_per_retry = 4.096us * (2 ^ supplied_timeout)
1047          * (plus we add a little fudge-factor here too)
1048          */
1049         lstate.hls_timeout = lb.alb_timeout;
1050         max_usec = (4096 * (1 << lstate.hls_timeout)) / 1000;
1051         max_usec = max_usec * (lstate.hls_retry + 1);
1052         max_usec = max_usec + 10000;
1053 
1054         /*
1055          * Determine how many times we should loop before declaring a
1056          * timeout failure.
1057          */
1058         loopmax  = max_usec/HERMON_VTS_LOOPBACK_MIN_WAIT_DUR;
1059         if ((max_usec % HERMON_VTS_LOOPBACK_MIN_WAIT_DUR) != 0) {
1060                 loopmax++;
1061         }
1062 
1063         if (lb.alb_send_buf == NULL || lb.alb_buf_sz == 0) {
1064                 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_INVALID;
1065                 (void) hermon_loopback_copyout(&lb, arg, mode);
1066                 hermon_loopback_free_state(&lstate);
1067                 return (EINVAL);
1068         }
1069 
1070         /* Allocate protection domain (PD) */
1071         if (hermon_loopback_init(state, &lstate) != 0) {
1072                 lb.alb_error_type = lstate.hls_err;
1073                 (void) hermon_loopback_copyout(&lb, arg, mode);
1074                 hermon_loopback_free_state(&lstate);
1075                 return (EFAULT);
1076         }
1077 
1078         /* Allocate and register a TX buffer */
1079         if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_tx,
1080             lb.alb_buf_sz) != 0) {
1081                 lb.alb_error_type =
1082                     HERMON_LOOPBACK_SEND_BUF_MEM_REGION_ALLOC_FAIL;
1083                 (void) hermon_loopback_copyout(&lb, arg, mode);
1084                 hermon_loopback_free_state(&lstate);
1085                 return (EFAULT);
1086         }
1087 
1088         /* Allocate and register an RX buffer */
1089         if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_rx,
1090             lb.alb_buf_sz) != 0) {
1091                 lb.alb_error_type =
1092                     HERMON_LOOPBACK_RECV_BUF_MEM_REGION_ALLOC_FAIL;
1093                 (void) hermon_loopback_copyout(&lb, arg, mode);
1094                 hermon_loopback_free_state(&lstate);
1095                 return (EFAULT);
1096         }
1097 
1098         /* Copy in the transmit buffer data */
1099         if (ddi_copyin((void *)lb.alb_send_buf, lstate.hls_tx.hlc_buf,
1100             lb.alb_buf_sz, mode) != 0) {
1101                 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_COPY_FAIL;
1102                 (void) hermon_loopback_copyout(&lb, arg, mode);
1103                 hermon_loopback_free_state(&lstate);
1104                 return (EFAULT);
1105         }
1106 
1107         /* Allocate the transmit QP and CQs */
1108         lstate.hls_err = HERMON_LOOPBACK_XMIT_SEND_CQ_ALLOC_FAIL;
1109         if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_tx) != 0) {
1110                 lb.alb_error_type = lstate.hls_err;
1111                 (void) hermon_loopback_copyout(&lb, arg, mode);
1112                 hermon_loopback_free_state(&lstate);
1113                 return (EFAULT);
1114         }
1115 
1116         /* Allocate the receive QP and CQs */
1117         lstate.hls_err = HERMON_LOOPBACK_RECV_SEND_CQ_ALLOC_FAIL;
1118         if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_rx) != 0) {
1119                 lb.alb_error_type = lstate.hls_err;
1120                 (void) hermon_loopback_copyout(&lb, arg, mode);
1121                 hermon_loopback_free_state(&lstate);
1122                 return (EFAULT);
1123         }
1124 
1125         /* Activate the TX QP (connect to RX QP) */
1126         lstate.hls_err = HERMON_LOOPBACK_XMIT_QP_INIT_FAIL;
1127         if (hermon_loopback_modify_qp(&lstate, &lstate.hls_tx,
1128             lstate.hls_rx.hlc_qp_num) != 0) {
1129                 lb.alb_error_type = lstate.hls_err;
1130                 (void) hermon_loopback_copyout(&lb, arg, mode);
1131                 hermon_loopback_free_state(&lstate);
1132                 return (EFAULT);
1133         }
1134 
1135         /* Activate the RX QP (connect to TX QP) */
1136         lstate.hls_err = HERMON_LOOPBACK_RECV_QP_INIT_FAIL;
1137         if (hermon_loopback_modify_qp(&lstate, &lstate.hls_rx,
1138             lstate.hls_tx.hlc_qp_num) != 0) {
1139                 lb.alb_error_type = lstate.hls_err;
1140                 (void) hermon_loopback_copyout(&lb, arg, mode);
1141                 hermon_loopback_free_state(&lstate);
1142                 return (EFAULT);
1143         }
1144 
1145         /* Run the loopback test (for specified number of iterations) */
1146         lb.alb_pass_done = 0;
1147         for (iter = 0; iter < lb.alb_num_iter; iter++) {
1148                 lstate.hls_err = 0;
1149                 bzero(lstate.hls_rx.hlc_buf, lb.alb_buf_sz);
1150 
1151                 /* Post RDMA Write work request */
1152                 if (hermon_loopback_post_send(&lstate, &lstate.hls_tx,
1153                     &lstate.hls_rx) != IBT_SUCCESS) {
1154                         lb.alb_error_type = HERMON_LOOPBACK_WQE_POST_FAIL;
1155                         (void) hermon_loopback_copyout(&lb, arg, mode);
1156                         hermon_loopback_free_state(&lstate);
1157                         return (EFAULT);
1158                 }
1159 
1160                 /* Poll the TX CQ for a completion every few ticks */
1161                 for (j = 0; j < loopmax; j++) {
1162                         delay(drv_usectohz(HERMON_VTS_LOOPBACK_MIN_WAIT_DUR));
1163 
1164                         ret = hermon_loopback_poll_cq(&lstate, &lstate.hls_tx);
1165                         if (((ret != IBT_SUCCESS) && (ret != IBT_CQ_EMPTY)) ||
1166                             ((ret == IBT_CQ_EMPTY) && (j == loopmax - 1))) {
1167                                 lb.alb_error_type =
1168                                     HERMON_LOOPBACK_CQ_POLL_FAIL;
1169                                 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1170                                     lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1171                                     mode) != 0) {
1172                                         return (EFAULT);
1173                                 }
1174                                 (void) hermon_loopback_copyout(&lb, arg, mode);
1175                                 hermon_loopback_free_state(&lstate);
1176                                 return (EFAULT);
1177                         } else if (ret == IBT_CQ_EMPTY) {
1178                                 continue;
1179                         }
1180 
1181                         /* Compare the data buffers */
1182                         if (bcmp(lstate.hls_tx.hlc_buf, lstate.hls_rx.hlc_buf,
1183                             lb.alb_buf_sz) == 0) {
1184                                 break;
1185                         } else {
1186                                 lb.alb_error_type =
1187                                     HERMON_LOOPBACK_SEND_RECV_COMPARE_FAIL;
1188                                 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1189                                     lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1190                                     mode) != 0) {
1191                                         return (EFAULT);
1192                                 }
1193                                 (void) hermon_loopback_copyout(&lb, arg, mode);
1194                                 hermon_loopback_free_state(&lstate);
1195                                 return (EFAULT);
1196                         }
1197                 }
1198 
1199                 lstate.hls_err   = HERMON_LOOPBACK_SUCCESS;
1200                 lb.alb_pass_done = iter + 1;
1201         }
1202 
1203         lb.alb_error_type = HERMON_LOOPBACK_SUCCESS;
1204 
1205         /* Copy ioctl results back to user struct */
1206         ret = hermon_loopback_copyout(&lb, arg, mode);
1207 
1208         /* Free up everything and release all consumed resources */
1209         hermon_loopback_free_state(&lstate);
1210 
1211         return (ret);
1212 }
1213 
1214 #ifdef  DEBUG
1215 /*
1216  * hermon_ioctl_reg_read()
1217  */
1218 static int
1219 hermon_ioctl_reg_read(hermon_state_t *state, intptr_t arg, int mode)
1220 {
1221         hermon_reg_ioctl_t      rdreg;
1222         uint32_t                *addr;
1223         uintptr_t               baseaddr;
1224         int                     status;
1225         ddi_acc_handle_t        handle;
1226 
1227         /* initialize the FMA retry loop */
1228         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1229 
1230         /*
1231          * Access to Hemron registers is not allowed in "maintenance mode".
1232          * This is primarily because the device may not have BARs to access
1233          */
1234         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1235                 return (EFAULT);
1236         }
1237 
1238         /* Copy in the hermon_reg_ioctl_t structure */
1239         status = ddi_copyin((void *)arg, &rdreg, sizeof (hermon_reg_ioctl_t),
1240             mode);
1241         if (status != 0) {
1242                 return (EFAULT);
1243         }
1244 
1245         /* Determine base address for requested register set */
1246         switch (rdreg.arg_reg_set) {
1247         case HERMON_CMD_BAR:
1248                 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1249                 handle = hermon_get_cmdhdl(state);
1250                 break;
1251 
1252         case HERMON_UAR_BAR:
1253                 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1254                 handle = hermon_get_uarhdl(state);
1255                 break;
1256 
1257 
1258         default:
1259                 return (EINVAL);
1260         }
1261 
1262         /* Ensure that address is properly-aligned */
1263         addr = (uint32_t *)((baseaddr + rdreg.arg_offset) & ~0x3);
1264 
1265         /* the FMA retry loop starts. */
1266         hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1267             fm_status, fm_test);
1268 
1269         /* Read the register pointed to by addr */
1270         rdreg.arg_data = ddi_get32(handle, addr);
1271 
1272         /* the FMA retry loop ends. */
1273         hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1274             fm_test);
1275 
1276         /* Copy in the result into the hermon_reg_ioctl_t structure */
1277         status = ddi_copyout(&rdreg, (void *)arg, sizeof (hermon_reg_ioctl_t),
1278             mode);
1279         if (status != 0) {
1280                 return (EFAULT);
1281         }
1282         return (0);
1283 
1284 pio_error:
1285         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1286         return (EIO);
1287 }
1288 
1289 
1290 /*
1291  * hermon_ioctl_reg_write()
1292  */
1293 static int
1294 hermon_ioctl_reg_write(hermon_state_t *state, intptr_t arg, int mode)
1295 {
1296         hermon_reg_ioctl_t      wrreg;
1297         uint32_t                *addr;
1298         uintptr_t               baseaddr;
1299         int                     status;
1300         ddi_acc_handle_t        handle;
1301 
1302         /* initialize the FMA retry loop */
1303         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1304 
1305         /*
1306          * Access to Hermon registers is not allowed in "maintenance mode".
1307          * This is primarily because the device may not have BARs to access
1308          */
1309         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1310                 return (EFAULT);
1311         }
1312 
1313         /* Copy in the hermon_reg_ioctl_t structure */
1314         status = ddi_copyin((void *)arg, &wrreg, sizeof (hermon_reg_ioctl_t),
1315             mode);
1316         if (status != 0) {
1317                 return (EFAULT);
1318         }
1319 
1320         /* Determine base address for requested register set */
1321         switch (wrreg.arg_reg_set) {
1322         case HERMON_CMD_BAR:
1323                 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1324                 handle = hermon_get_cmdhdl(state);
1325                 break;
1326 
1327         case HERMON_UAR_BAR:
1328                 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1329                 handle = hermon_get_uarhdl(state);
1330                 break;
1331 
1332         default:
1333                 return (EINVAL);
1334         }
1335 
1336         /* Ensure that address is properly-aligned */
1337         addr = (uint32_t *)((baseaddr + wrreg.arg_offset) & ~0x3);
1338 
1339         /* the FMA retry loop starts. */
1340         hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1341             fm_status, fm_test);
1342 
1343         /* Write the data to the register pointed to by addr */
1344         ddi_put32(handle, addr, wrreg.arg_data);
1345 
1346         /* the FMA retry loop ends. */
1347         hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1348             fm_test);
1349         return (0);
1350 
1351 pio_error:
1352         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1353         return (EIO);
1354 }
1355 #endif  /* DEBUG */
1356 
1357 static int
1358 hermon_ioctl_write_boot_addr(hermon_state_t *state, dev_t dev, intptr_t arg,
1359     int mode)
1360 {
1361         hermon_flash_ioctl_t    ioctl_info;
1362 
1363         /* initialize the FMA retry loop */
1364         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1365 
1366         /*
1367          * Check that flash init ioctl has been called first.  And check
1368          * that the same dev_t that called init is the one calling write now.
1369          */
1370         mutex_enter(&state->hs_fw_flashlock);
1371         if ((state->hs_fw_flashdev != dev) ||
1372             (state->hs_fw_flashstarted == 0)) {
1373                 mutex_exit(&state->hs_fw_flashlock);
1374                 return (EIO);
1375         }
1376 
1377         /* copy user struct to kernel */
1378 #ifdef _MULTI_DATAMODEL
1379         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
1380                 hermon_flash_ioctl32_t info32;
1381 
1382                 if (ddi_copyin((void *)arg, &info32,
1383                     sizeof (hermon_flash_ioctl32_t), mode) != 0) {
1384                         mutex_exit(&state->hs_fw_flashlock);
1385                         return (EFAULT);
1386                 }
1387                 ioctl_info.af_type = info32.af_type;
1388                 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
1389                 ioctl_info.af_sector_num = info32.af_sector_num;
1390                 ioctl_info.af_addr = info32.af_addr;
1391                 ioctl_info.af_byte = info32.af_byte;
1392         } else
1393 #endif /* _MULTI_DATAMODEL */
1394         if (ddi_copyin((void *)arg, &ioctl_info,
1395             sizeof (hermon_flash_ioctl_t), mode) != 0) {
1396                 mutex_exit(&state->hs_fw_flashlock);
1397                 return (EFAULT);
1398         }
1399 
1400         switch (state->hs_fw_cmdset) {
1401         case HERMON_FLASH_AMD_CMDSET:
1402         case HERMON_FLASH_INTEL_CMDSET:
1403                 break;
1404 
1405         case HERMON_FLASH_SPI_CMDSET:
1406         {
1407                 ddi_acc_handle_t pci_hdl = hermon_get_pcihdl(state);
1408 
1409                 /* the FMA retry loop starts. */
1410                 hermon_pio_start(state, pci_hdl, pio_error,
1411                     fm_loop_cnt, fm_status, fm_test);
1412 
1413                 hermon_flash_write_cfg(state, pci_hdl,
1414                     HERMON_HW_FLASH_SPI_BOOT_ADDR_REG,
1415                     (ioctl_info.af_addr << 8) | 0x06);
1416 
1417                 /* the FMA retry loop ends. */
1418                 hermon_pio_end(state, pci_hdl, pio_error,
1419                     fm_loop_cnt, fm_status, fm_test);
1420                 break;
1421         }
1422 
1423         case HERMON_FLASH_UNKNOWN_CMDSET:
1424         default:
1425                 mutex_exit(&state->hs_fw_flashlock);
1426                 return (EINVAL);
1427         }
1428         mutex_exit(&state->hs_fw_flashlock);
1429         return (0);
1430 
1431 pio_error:
1432         mutex_exit(&state->hs_fw_flashlock);
1433         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1434         return (EIO);
1435 }
1436 
1437 /*
1438  * hermon_flash_reset()
1439  */
1440 static int
1441 hermon_flash_reset(hermon_state_t *state)
1442 {
1443         int status;
1444 
1445         /*
1446          * Performs a reset to the flash device.  After a reset the flash will
1447          * be operating in normal mode (capable of read/write, etc.).
1448          */
1449         switch (state->hs_fw_cmdset) {
1450         case HERMON_FLASH_AMD_CMDSET:
1451                 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_AMD,
1452                     &status);
1453                 if (status != 0) {
1454                         return (status);
1455                 }
1456                 break;
1457 
1458         case HERMON_FLASH_INTEL_CMDSET:
1459                 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_INTEL,
1460                     &status);
1461                 if (status != 0) {
1462                         return (status);
1463                 }
1464                 break;
1465 
1466         /* It appears no reset is needed for SPI */
1467         case HERMON_FLASH_SPI_CMDSET:
1468                 status = 0;
1469                 break;
1470 
1471         case HERMON_FLASH_UNKNOWN_CMDSET:
1472         default:
1473                 status = EINVAL;
1474                 break;
1475         }
1476         return (status);
1477 }
1478 
1479 /*
1480  * hermon_flash_read_sector()
1481  */
1482 static int
1483 hermon_flash_read_sector(hermon_state_t *state, uint32_t sector_num)
1484 {
1485         uint32_t addr;
1486         uint32_t end_addr;
1487         uint32_t *image;
1488         int i, status;
1489 
1490         image = (uint32_t *)&state->hs_fw_sector[0];
1491 
1492         /*
1493          * Calculate the start and end address of the sector, based on the
1494          * sector number passed in.
1495          */
1496         addr = sector_num << state->hs_fw_log_sector_sz;
1497         end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1498 
1499         /* Set the flash bank correctly for the given address */
1500         if ((status = hermon_flash_bank(state, addr)) != 0)
1501                 return (status);
1502 
1503         /* Read the entire sector, one quadlet at a time */
1504         for (i = 0; addr < end_addr; i++, addr += 4) {
1505                 image[i] = hermon_flash_read(state, addr, &status);
1506                 if (status != 0) {
1507                         return (status);
1508                 }
1509         }
1510         return (0);
1511 }
1512 
1513 /*
1514  * hermon_flash_read_quadlet()
1515  */
1516 static int
1517 hermon_flash_read_quadlet(hermon_state_t *state, uint32_t *data,
1518     uint32_t addr)
1519 {
1520         int status;
1521 
1522         /* Set the flash bank correctly for the given address */
1523         if ((status = hermon_flash_bank(state, addr)) != 0) {
1524                 return (status);
1525         }
1526 
1527         /* Read one quadlet of data */
1528         *data = hermon_flash_read(state, addr, &status);
1529         if (status != 0) {
1530                 return (EIO);
1531         }
1532 
1533         return (0);
1534 }
1535 
1536 /*
1537  * hermon_flash_write_sector()
1538  */
1539 static int
1540 hermon_flash_write_sector(hermon_state_t *state, uint32_t sector_num)
1541 {
1542         uint32_t        addr;
1543         uint32_t        end_addr;
1544         uint32_t        *databuf;
1545         uchar_t         *sector;
1546         int             status = 0;
1547         int             i;
1548 
1549         sector = (uchar_t *)&state->hs_fw_sector[0];
1550 
1551         /*
1552          * Calculate the start and end address of the sector, based on the
1553          * sector number passed in.
1554          */
1555         addr = sector_num << state->hs_fw_log_sector_sz;
1556         end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1557 
1558         /* Set the flash bank correctly for the given address */
1559         if ((status = hermon_flash_bank(state, addr)) != 0 ||
1560             (status = hermon_flash_reset(state)) != 0) {
1561                 return (status);
1562         }
1563 
1564         /* Erase the sector before writing */
1565         status = hermon_flash_erase_sector(state, sector_num);
1566         if (status != 0) {
1567                 return (status);
1568         }
1569 
1570         switch (state->hs_fw_cmdset) {
1571         case HERMON_FLASH_SPI_CMDSET:
1572                 databuf = (uint32_t *)(void *)sector;
1573                 /* Write the sector, one dword at a time */
1574                 for (i = 0; addr < end_addr; i++, addr += 4) {
1575                         if ((status = hermon_flash_spi_write_dword(state, addr,
1576                             htonl(databuf[i]))) != 0) {
1577                                 return (status);
1578                         }
1579                 }
1580                 status = hermon_flash_reset(state);
1581                 break;
1582 
1583         case HERMON_FLASH_INTEL_CMDSET:
1584         case HERMON_FLASH_AMD_CMDSET:
1585                 /* Write the sector, one byte at a time */
1586                 for (i = 0; addr < end_addr; i++, addr++) {
1587                         status = hermon_flash_write_byte(state, addr,
1588                             sector[i]);
1589                         if (status != 0) {
1590                                 break;
1591                         }
1592                 }
1593                 status = hermon_flash_reset(state);
1594                 break;
1595 
1596         case HERMON_FLASH_UNKNOWN_CMDSET:
1597         default:
1598                 status = EINVAL;
1599                 break;
1600         }
1601 
1602         return (status);
1603 }
1604 
1605 /*
1606  * hermon_flash_spi_write_dword()
1607  *
1608  * NOTE: This function assumes that "data" is in network byte order.
1609  *
1610  */
1611 static int
1612 hermon_flash_spi_write_dword(hermon_state_t *state, uint32_t addr,
1613     uint32_t data)
1614 {
1615         int status;
1616         ddi_acc_handle_t        hdl;
1617 
1618         /* initialize the FMA retry loop */
1619         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1620 
1621         hdl = hermon_get_pcihdl(state);
1622 
1623         /* the FMA retry loop starts. */
1624         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1625             fm_test);
1626 
1627         /* Issue Write Enable */
1628         hermon_flash_spi_write_enable(state);
1629 
1630         /* Set the Address */
1631         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1632             addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1633 
1634         /* Set the Data */
1635         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_DATA, data);
1636 
1637         /* Set the Page Program and execute */
1638         hermon_flash_spi_exec_command(state, hdl,
1639             HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1640             HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1641             HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
1642             HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
1643             (HERMON_HW_FLASH_SPI_PAGE_PROGRAM <<
1644             HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1645 
1646         /* Wait for write to complete */
1647         if ((status = hermon_flash_spi_wait_wip(state)) != 0) {
1648                 return (status);
1649         }
1650 
1651         /* the FMA retry loop ends. */
1652         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
1653         return (0);
1654 
1655 pio_error:
1656         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1657         return (EIO);
1658 }
1659 
1660 /*
1661  * hermon_flash_write_byte()
1662  */
1663 static int
1664 hermon_flash_write_byte(hermon_state_t *state, uint32_t addr, uchar_t data)
1665 {
1666         uint32_t stat;
1667         int status = 0;
1668         int dword_addr;
1669         int byte_offset;
1670         int i;
1671         union {
1672                 uint8_t         bytes[4];
1673                 uint32_t        dword;
1674         } dword;
1675 
1676         switch (state->hs_fw_cmdset) {
1677         case HERMON_FLASH_AMD_CMDSET:
1678                 /* Issue Flash Byte program command */
1679                 hermon_flash_write(state, addr, 0xAA, &status);
1680                 if (status != 0) {
1681                         return (status);
1682                 }
1683 
1684                 hermon_flash_write(state, addr, 0x55, &status);
1685                 if (status != 0) {
1686                         return (status);
1687                 }
1688 
1689                 hermon_flash_write(state, addr, 0xA0, &status);
1690                 if (status != 0) {
1691                         return (status);
1692                 }
1693 
1694                 hermon_flash_write(state, addr, data, &status);
1695                 if (status != 0) {
1696                         return (status);
1697                 }
1698 
1699                 /* Wait for Write Byte to Complete */
1700                 i = 0;
1701                 do {
1702                         drv_usecwait(1);
1703                         stat = hermon_flash_read(state, addr & ~3, &status);
1704                         if (status != 0) {
1705                                 return (status);
1706                         }
1707 
1708                         if (i == hermon_hw_flash_timeout_write) {
1709                                 cmn_err(CE_WARN,
1710                                     "hermon_flash_write_byte: ACS write "
1711                                     "timeout: addr: 0x%x, data: 0x%x\n",
1712                                     addr, data);
1713                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1714                                     HCA_ERR_IOCTL);
1715                                 return (EIO);
1716                         }
1717                         i++;
1718                 } while (data != ((stat >> ((3 - (addr & 3)) << 3)) & 0xFF));
1719 
1720                 break;
1721 
1722         case HERMON_FLASH_INTEL_CMDSET:
1723                 /* Issue Flash Byte program command */
1724                 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_WRITE,
1725                     &status);
1726                 if (status != 0) {
1727                         return (status);
1728                 }
1729                 hermon_flash_write(state, addr, data, &status);
1730                 if (status != 0) {
1731                         return (status);
1732                 }
1733 
1734                 /* Wait for Write Byte to Complete */
1735                 i = 0;
1736                 do {
1737                         drv_usecwait(1);
1738                         stat = hermon_flash_read(state, addr & ~3, &status);
1739                         if (status != 0) {
1740                                 return (status);
1741                         }
1742 
1743                         if (i == hermon_hw_flash_timeout_write) {
1744                                 cmn_err(CE_WARN,
1745                                     "hermon_flash_write_byte: ICS write "
1746                                     "timeout: addr: %x, data: %x\n",
1747                                     addr, data);
1748                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1749                                     HCA_ERR_IOCTL);
1750                                 return (EIO);
1751                         }
1752                         i++;
1753                 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1754 
1755                 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1756                         cmn_err(CE_WARN,
1757                             "hermon_flash_write_byte: ICS write cmd error: "
1758                             "addr: %x, data: %x\n",
1759                             addr, data);
1760                         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1761                         return (EIO);
1762                 }
1763                 break;
1764 
1765         case HERMON_FLASH_SPI_CMDSET:
1766                 /*
1767                  * Our lowest write granularity on SPI is a dword.
1768                  * To support this ioctl option, we can read in the
1769                  * dword that contains this byte, modify this byte,
1770                  * and write the dword back out.
1771                  */
1772 
1773                 /* Determine dword offset and byte offset within the dword */
1774                 byte_offset = addr & 3;
1775                 dword_addr = addr - byte_offset;
1776 #ifdef _LITTLE_ENDIAN
1777                 byte_offset = 3 - byte_offset;
1778 #endif
1779 
1780                 /* Read in dword */
1781                 if ((status = hermon_flash_read_quadlet(state, &dword.dword,
1782                     dword_addr)) != 0)
1783                         break;
1784 
1785                 /* Set "data" to the appopriate byte */
1786                 dword.bytes[byte_offset] = data;
1787 
1788                 /* Write modified dword back out */
1789                 status = hermon_flash_spi_write_dword(state, dword_addr,
1790                     dword.dword);
1791 
1792                 break;
1793 
1794         case HERMON_FLASH_UNKNOWN_CMDSET:
1795         default:
1796                 cmn_err(CE_WARN,
1797                     "hermon_flash_write_byte: unknown cmd set: 0x%x\n",
1798                     state->hs_fw_cmdset);
1799                 status = EINVAL;
1800                 break;
1801         }
1802 
1803         return (status);
1804 }
1805 
1806 /*
1807  * hermon_flash_erase_sector()
1808  */
1809 static int
1810 hermon_flash_erase_sector(hermon_state_t *state, uint32_t sector_num)
1811 {
1812         ddi_acc_handle_t        hdl;
1813         uint32_t addr;
1814         uint32_t stat;
1815         int status = 0;
1816         int i;
1817 
1818         /* initialize the FMA retry loop */
1819         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1820 
1821         /* Get address from sector num */
1822         addr = sector_num << state->hs_fw_log_sector_sz;
1823 
1824         switch (state->hs_fw_cmdset) {
1825         case HERMON_FLASH_AMD_CMDSET:
1826                 /* Issue Flash Sector Erase Command */
1827                 hermon_flash_write(state, addr, 0xAA, &status);
1828                 if (status != 0) {
1829                         return (status);
1830                 }
1831 
1832                 hermon_flash_write(state, addr, 0x55, &status);
1833                 if (status != 0) {
1834                         return (status);
1835                 }
1836 
1837                 hermon_flash_write(state, addr, 0x80, &status);
1838                 if (status != 0) {
1839                         return (status);
1840                 }
1841 
1842                 hermon_flash_write(state, addr, 0xAA, &status);
1843                 if (status != 0) {
1844                         return (status);
1845                 }
1846 
1847                 hermon_flash_write(state, addr, 0x55, &status);
1848                 if (status != 0) {
1849                         return (status);
1850                 }
1851 
1852                 hermon_flash_write(state, addr, 0x30, &status);
1853                 if (status != 0) {
1854                         return (status);
1855                 }
1856 
1857                 /* Wait for Sector Erase to complete */
1858                 i = 0;
1859                 do {
1860                         drv_usecwait(1);
1861                         stat = hermon_flash_read(state, addr, &status);
1862                         if (status != 0) {
1863                                 return (status);
1864                         }
1865 
1866                         if (i == hermon_hw_flash_timeout_erase) {
1867                                 cmn_err(CE_WARN,
1868                                     "hermon_flash_erase_sector: "
1869                                     "ACS erase timeout\n");
1870                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1871                                     HCA_ERR_IOCTL);
1872                                 return (EIO);
1873                         }
1874                         i++;
1875                 } while (stat != 0xFFFFFFFF);
1876                 break;
1877 
1878         case HERMON_FLASH_INTEL_CMDSET:
1879                 /* Issue Flash Sector Erase Command */
1880                 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_ERASE,
1881                     &status);
1882                 if (status != 0) {
1883                         return (status);
1884                 }
1885 
1886                 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_CONFIRM,
1887                     &status);
1888                 if (status != 0) {
1889                         return (status);
1890                 }
1891 
1892                 /* Wait for Sector Erase to complete */
1893                 i = 0;
1894                 do {
1895                         drv_usecwait(1);
1896                         stat = hermon_flash_read(state, addr & ~3, &status);
1897                         if (status != 0) {
1898                                 return (status);
1899                         }
1900 
1901                         if (i == hermon_hw_flash_timeout_erase) {
1902                                 cmn_err(CE_WARN,
1903                                     "hermon_flash_erase_sector: "
1904                                     "ICS erase timeout\n");
1905                                 hermon_fm_ereport(state, HCA_SYS_ERR,
1906                                     HCA_ERR_IOCTL);
1907                                 return (EIO);
1908                         }
1909                         i++;
1910                 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1911 
1912                 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1913                         cmn_err(CE_WARN,
1914                             "hermon_flash_erase_sector: "
1915                             "ICS erase cmd error\n");
1916                         hermon_fm_ereport(state, HCA_SYS_ERR,
1917                             HCA_ERR_IOCTL);
1918                         return (EIO);
1919                 }
1920                 break;
1921 
1922         case HERMON_FLASH_SPI_CMDSET:
1923                 hdl = hermon_get_pcihdl(state);
1924 
1925                 /* the FMA retry loop starts. */
1926                 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1927                     fm_test);
1928 
1929                 /* Issue Write Enable */
1930                 hermon_flash_spi_write_enable(state);
1931 
1932                 /* Set the Address */
1933                 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1934                     addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1935 
1936                 /* Issue Flash Sector Erase */
1937                 hermon_flash_spi_exec_command(state, hdl,
1938                     HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1939                     HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1940                     ((uint32_t)(HERMON_HW_FLASH_SPI_SECTOR_ERASE) <<
1941                     HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1942 
1943                 /* the FMA retry loop ends. */
1944                 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status,
1945                     fm_test);
1946 
1947                 /* Wait for Sector Erase to complete */
1948                 status = hermon_flash_spi_wait_wip(state);
1949                 break;
1950 
1951         case HERMON_FLASH_UNKNOWN_CMDSET:
1952         default:
1953                 cmn_err(CE_WARN,
1954                     "hermon_flash_erase_sector: unknown cmd set: 0x%x\n",
1955                     state->hs_fw_cmdset);
1956                 status = EINVAL;
1957                 break;
1958         }
1959 
1960         /* Reset the flash device */
1961         if (status == 0) {
1962                 status = hermon_flash_reset(state);
1963         }
1964         return (status);
1965 
1966 pio_error:
1967         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1968         return (EIO);
1969 }
1970 
1971 /*
1972  * hermon_flash_erase_chip()
1973  */
1974 static int
1975 hermon_flash_erase_chip(hermon_state_t *state)
1976 {
1977         uint32_t stat;
1978         uint_t size;
1979         int status = 0;
1980         int i;
1981         int num_sect;
1982 
1983         switch (state->hs_fw_cmdset) {
1984         case HERMON_FLASH_AMD_CMDSET:
1985                 /* Issue Flash Chip Erase Command */
1986                 hermon_flash_write(state, 0, 0xAA, &status);
1987                 if (status != 0) {
1988                         return (status);
1989                 }
1990 
1991                 hermon_flash_write(state, 0, 0x55, &status);
1992                 if (status != 0) {
1993                         return (status);
1994                 }
1995 
1996                 hermon_flash_write(state, 0, 0x80, &status);
1997                 if (status != 0) {
1998                         return (status);
1999                 }
2000 
2001                 hermon_flash_write(state, 0, 0xAA, &status);
2002                 if (status != 0) {
2003                         return (status);
2004                 }
2005 
2006                 hermon_flash_write(state, 0, 0x55, &status);
2007                 if (status != 0) {
2008                         return (status);
2009                 }
2010 
2011                 hermon_flash_write(state, 0, 0x10, &status);
2012                 if (status != 0) {
2013                         return (status);
2014                 }
2015 
2016                 /* Wait for Chip Erase to Complete */
2017                 i = 0;
2018                 do {
2019                         drv_usecwait(1);
2020                         stat = hermon_flash_read(state, 0, &status);
2021                         if (status != 0) {
2022                                 return (status);
2023                         }
2024 
2025                         if (i == hermon_hw_flash_timeout_erase) {
2026                                 cmn_err(CE_WARN,
2027                                     "hermon_flash_erase_chip: erase timeout\n");
2028                                 hermon_fm_ereport(state, HCA_SYS_ERR,
2029                                     HCA_ERR_IOCTL);
2030                                 return (EIO);
2031                         }
2032                         i++;
2033                 } while (stat != 0xFFFFFFFF);
2034                 break;
2035 
2036         case HERMON_FLASH_INTEL_CMDSET:
2037         case HERMON_FLASH_SPI_CMDSET:
2038                 /*
2039                  * These chips don't have a chip erase command, so erase
2040                  * all blocks one at a time.
2041                  */
2042                 size = (0x1 << state->hs_fw_log_sector_sz);
2043                 num_sect = state->hs_fw_device_sz / size;
2044 
2045                 for (i = 0; i < num_sect; i++) {
2046                         status = hermon_flash_erase_sector(state, i);
2047                         if (status != 0) {
2048                                 cmn_err(CE_WARN,
2049                                     "hermon_flash_erase_chip: "
2050                                     "sector %d erase error\n", i);
2051                                 return (status);
2052                         }
2053                 }
2054                 break;
2055 
2056         case HERMON_FLASH_UNKNOWN_CMDSET:
2057         default:
2058                 cmn_err(CE_WARN, "hermon_flash_erase_chip: "
2059                     "unknown cmd set: 0x%x\n", state->hs_fw_cmdset);
2060                 status = EINVAL;
2061                 break;
2062         }
2063 
2064         return (status);
2065 }
2066 
2067 /*
2068  * hermon_flash_spi_write_enable()
2069  */
2070 static void
2071 hermon_flash_spi_write_enable(hermon_state_t *state)
2072 {
2073         ddi_acc_handle_t        hdl;
2074 
2075         hdl = hermon_get_pcihdl(state);
2076 
2077         hermon_flash_spi_exec_command(state, hdl,
2078             HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2079             (HERMON_HW_FLASH_SPI_WRITE_ENABLE <<
2080             HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2081 }
2082 
2083 /*
2084  * hermon_flash_spi_wait_wip()
2085  */
2086 static int
2087 hermon_flash_spi_wait_wip(hermon_state_t *state)
2088 {
2089         ddi_acc_handle_t        hdl;
2090         uint32_t                status;
2091 
2092         /* initialize the FMA retry loop */
2093         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2094 
2095         hdl = hermon_get_pcihdl(state);
2096 
2097         /* the FMA retry loop starts. */
2098         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2099             fm_test);
2100 
2101         /* wait on the gateway to clear busy */
2102         do {
2103                 status = hermon_flash_read_cfg(state, hdl,
2104                     HERMON_HW_FLASH_SPI_GW);
2105         } while (status & HERMON_HW_FLASH_SPI_BUSY);
2106 
2107         /* now, get the status and check for WIP to clear */
2108         do {
2109                 hermon_flash_spi_exec_command(state, hdl,
2110                     HERMON_HW_FLASH_SPI_READ_OP |
2111                     HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2112                     HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2113                     HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2114                     (HERMON_HW_FLASH_SPI_READ_STATUS_REG <<
2115                     HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2116 
2117                 status = hermon_flash_read_cfg(state, hdl,
2118                     HERMON_HW_FLASH_SPI_DATA);
2119         } while (status & HERMON_HW_FLASH_SPI_WIP);
2120 
2121         /* the FMA retry loop ends. */
2122         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2123         return (0);
2124 
2125 pio_error:
2126         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2127         return (EIO);
2128 }
2129 
2130 /*
2131  * hermon_flash_bank()
2132  */
2133 static int
2134 hermon_flash_bank(hermon_state_t *state, uint32_t addr)
2135 {
2136         ddi_acc_handle_t        hdl;
2137         uint32_t                bank;
2138 
2139         /* initialize the FMA retry loop */
2140         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2141 
2142         /* Set handle */
2143         hdl = hermon_get_pcihdl(state);
2144 
2145         /* Determine the bank setting from the address */
2146         bank = addr & HERMON_HW_FLASH_BANK_MASK;
2147 
2148         /*
2149          * If the bank is different from the currently set bank, we need to
2150          * change it.  Also, if an 'addr' of 0 is given, this allows the
2151          * capability to force the flash bank to 0.  This is useful at init
2152          * time to initially set the bank value
2153          */
2154         if (state->hs_fw_flashbank != bank || addr == 0) {
2155                 switch (state->hs_fw_cmdset) {
2156                 case HERMON_FLASH_SPI_CMDSET:
2157                         /* CMJ: not needed for hermon */
2158                         break;
2159 
2160                 case HERMON_FLASH_INTEL_CMDSET:
2161                 case HERMON_FLASH_AMD_CMDSET:
2162                         /* the FMA retry loop starts. */
2163                         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt,
2164                             fm_status, fm_test);
2165 
2166                         hermon_flash_write_cfg(state, hdl,
2167                             HERMON_HW_FLASH_GPIO_DATACLEAR, 0x70);
2168                         hermon_flash_write_cfg(state, hdl,
2169                             HERMON_HW_FLASH_GPIO_DATASET, (bank >> 15) & 0x70);
2170 
2171                         /* the FMA retry loop ends. */
2172                         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt,
2173                             fm_status, fm_test);
2174                         break;
2175 
2176                 case HERMON_FLASH_UNKNOWN_CMDSET:
2177                 default:
2178                         return (EINVAL);
2179                 }
2180 
2181                 state->hs_fw_flashbank = bank;
2182         }
2183         return (0);
2184 
2185 pio_error:
2186         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2187         return (EIO);
2188 }
2189 
2190 /*
2191  * hermon_flash_spi_exec_command()
2192  */
2193 static void
2194 hermon_flash_spi_exec_command(hermon_state_t *state, ddi_acc_handle_t hdl,
2195     uint32_t cmd)
2196 {
2197         uint32_t data;
2198         int timeout = 0;
2199 
2200         cmd |= HERMON_HW_FLASH_SPI_BUSY | HERMON_HW_FLASH_SPI_ENABLE_OFF;
2201 
2202         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_GW, cmd);
2203 
2204         do {
2205                 data = hermon_flash_read_cfg(state, hdl,
2206                     HERMON_HW_FLASH_SPI_GW);
2207                 timeout++;
2208         } while ((data & HERMON_HW_FLASH_SPI_BUSY) &&
2209             (timeout < hermon_hw_flash_timeout_config));
2210 }
2211 
2212 /*
2213  * hermon_flash_read()
2214  */
2215 static uint32_t
2216 hermon_flash_read(hermon_state_t *state, uint32_t addr, int *err)
2217 {
2218         ddi_acc_handle_t        hdl;
2219         uint32_t                data = 0;
2220         int                     timeout, status = 0;
2221 
2222         /* initialize the FMA retry loop */
2223         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2224 
2225         hdl = hermon_get_pcihdl(state);
2226 
2227         /* the FMA retry loop starts. */
2228         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2229             fm_test);
2230 
2231         switch (state->hs_fw_cmdset) {
2232         case HERMON_FLASH_SPI_CMDSET:
2233                 /* Set the transaction address */
2234                 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
2235                     (addr & HERMON_HW_FLASH_SPI_ADDR_MASK));
2236 
2237                 hermon_flash_spi_exec_command(state, hdl,
2238                     HERMON_HW_FLASH_SPI_READ_OP |
2239                     HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2240                     HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
2241                     HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2242                     HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2243                     (HERMON_HW_FLASH_SPI_READ <<
2244                     HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2245 
2246                 data = hermon_flash_read_cfg(state, hdl,
2247                     HERMON_HW_FLASH_SPI_DATA);
2248                 break;
2249 
2250         case HERMON_FLASH_INTEL_CMDSET:
2251         case HERMON_FLASH_AMD_CMDSET:
2252                 /*
2253                  * The Read operation does the following:
2254                  *   1) Write the masked address to the HERMON_FLASH_ADDR
2255                  *      register. Only the least significant 19 bits are valid.
2256                  *   2) Read back the register until the command has completed.
2257                  *   3) Read the data retrieved from the address at the
2258                  *      HERMON_FLASH_DATA register.
2259                  */
2260                 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2261                     (addr & HERMON_HW_FLASH_ADDR_MASK) | (1 << 29));
2262 
2263                 timeout = 0;
2264                 do {
2265                         data = hermon_flash_read_cfg(state, hdl,
2266                             HERMON_HW_FLASH_ADDR);
2267                         timeout++;
2268                 } while ((data & HERMON_HW_FLASH_CMD_MASK) &&
2269                     (timeout < hermon_hw_flash_timeout_config));
2270 
2271                 if (timeout == hermon_hw_flash_timeout_config) {
2272                         cmn_err(CE_WARN, "hermon_flash_read: command timed "
2273                             "out.\n");
2274                         *err = EIO;
2275                         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2276                         return (data);
2277                 }
2278 
2279                 data = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_DATA);
2280                 break;
2281 
2282         case HERMON_FLASH_UNKNOWN_CMDSET:
2283         default:
2284                 cmn_err(CE_CONT, "hermon_flash_read: unknown cmdset: 0x%x\n",
2285                     state->hs_fw_cmdset);
2286                 status = EINVAL;
2287                 break;
2288         }
2289 
2290 
2291         /* the FMA retry loop ends. */
2292         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2293         *err = status;
2294         return (data);
2295 
2296 pio_error:
2297         *err = EIO;
2298         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2299         return (data);
2300 }
2301 
2302 /*
2303  * hermon_flash_write()
2304  */
2305 static void
2306 hermon_flash_write(hermon_state_t *state, uint32_t addr, uchar_t data, int *err)
2307 {
2308         ddi_acc_handle_t        hdl;
2309         int                     cmd;
2310         int                     timeout;
2311 
2312         /* initialize the FMA retry loop */
2313         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2314 
2315         hdl = hermon_get_pcihdl(state);
2316 
2317         /* the FMA retry loop starts. */
2318         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2319             fm_test);
2320 
2321         /*
2322          * The Write operation does the following:
2323          *   1) Write the data to be written to the HERMON_FLASH_DATA offset.
2324          *   2) Write the address to write the data to to the HERMON_FLASH_ADDR
2325          *      offset.
2326          *   3) Wait until the write completes.
2327          */
2328 
2329         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_DATA, data << 24);
2330         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2331             (addr & 0x7FFFF) | (2 << 29));
2332 
2333         timeout = 0;
2334         do {
2335                 cmd = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_ADDR);
2336                 timeout++;
2337         } while ((cmd & HERMON_HW_FLASH_CMD_MASK) &&
2338             (timeout < hermon_hw_flash_timeout_config));
2339 
2340         if (timeout == hermon_hw_flash_timeout_config) {
2341                 cmn_err(CE_WARN, "hermon_flash_write: config cmd timeout.\n");
2342                 *err = EIO;
2343                 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2344                 return;
2345         }
2346 
2347         /* the FMA retry loop ends. */
2348         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2349         *err = 0;
2350         return;
2351 
2352 pio_error:
2353         *err = EIO;
2354         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2355 }
2356 
2357 /*
2358  * hermon_flash_init()
2359  */
2360 static int
2361 hermon_flash_init(hermon_state_t *state)
2362 {
2363         uint32_t                word;
2364         ddi_acc_handle_t        hdl;
2365         int                     sema_cnt;
2366         int                     gpio;
2367 
2368         /* initialize the FMA retry loop */
2369         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2370 
2371         /* Set handle */
2372         hdl = hermon_get_pcihdl(state);
2373 
2374         /* the FMA retry loop starts. */
2375         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2376             fm_test);
2377 
2378         /* Init the flash */
2379 
2380 #ifdef DO_WRCONF
2381         /*
2382          * Grab the WRCONF semaphore.
2383          */
2384         word = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_WRCONF_SEMA);
2385 #endif
2386 
2387         /*
2388          * Grab the GPIO semaphore.  This allows us exclusive access to the
2389          * GPIO settings on the Hermon for the duration of the flash burning
2390          * procedure.
2391          */
2392         sema_cnt = 0;
2393         do {
2394                 word = hermon_flash_read_cfg(state, hdl,
2395                     HERMON_HW_FLASH_GPIO_SEMA);
2396                 if (word == 0) {
2397                         break;
2398                 }
2399 
2400                 sema_cnt++;
2401                 drv_usecwait(1);
2402 
2403         } while (sema_cnt < hermon_hw_flash_timeout_gpio_sema);
2404 
2405         /*
2406          * Determine if we timed out trying to grab the GPIO semaphore
2407          */
2408         if (sema_cnt == hermon_hw_flash_timeout_gpio_sema) {
2409                 cmn_err(CE_WARN, "hermon_flash_init: GPIO SEMA timeout\n");
2410                 cmn_err(CE_WARN, "GPIO_SEMA value: 0x%x\n", word);
2411                 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2412                 return (EIO);
2413         }
2414 
2415         /* Save away original GPIO Values */
2416         state->hs_fw_gpio[0] = hermon_flash_read_cfg(state, hdl,
2417             HERMON_HW_FLASH_GPIO_DATA);
2418 
2419         /* Set new GPIO value */
2420         gpio = state->hs_fw_gpio[0] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2421         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA, gpio);
2422 
2423         /* Save away original GPIO Values */
2424         state->hs_fw_gpio[1] = hermon_flash_read_cfg(state, hdl,
2425             HERMON_HW_FLASH_GPIO_MOD0);
2426         state->hs_fw_gpio[2] = hermon_flash_read_cfg(state, hdl,
2427             HERMON_HW_FLASH_GPIO_MOD1);
2428 
2429         /* unlock GPIO */
2430         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2431             HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2432 
2433         /*
2434          * Set new GPIO values
2435          */
2436         gpio = state->hs_fw_gpio[1] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2437         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0, gpio);
2438 
2439         gpio = state->hs_fw_gpio[2] & ~HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2440         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1, gpio);
2441 
2442         /* re-lock GPIO */
2443         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2444 
2445         /* Set CPUMODE to enable hermon to access the flash device */
2446         /* CMJ This code came from arbel.  Hermon doesn't seem to need it. */
2447         /*
2448          *      hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_CPUMODE,
2449          *          1 << HERMON_HW_FLASH_CPU_SHIFT);
2450          */
2451 
2452         /* the FMA retry loop ends. */
2453         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2454         return (0);
2455 
2456 pio_error:
2457         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2458         return (EIO);
2459 }
2460 
2461 /*
2462  * hermon_flash_cfi_init
2463  *   Implements access to the CFI (Common Flash Interface) data
2464  */
2465 static int
2466 hermon_flash_cfi_init(hermon_state_t *state, uint32_t *cfi_info,
2467     int *intel_xcmd)
2468 {
2469         uint32_t        data;
2470         uint32_t        sector_sz_bytes;
2471         uint32_t        bit_count;
2472         uint8_t         cfi_ch_info[HERMON_CFI_INFO_SIZE];
2473         uint32_t        cfi_dw_info[HERMON_CFI_INFO_QSIZE];
2474         int             i;
2475         int             status;
2476 
2477         /* Right now, all hermon cards use SPI. */
2478         if (hermon_device_mode(state)) {
2479                 /*
2480                  * Don't use CFI for SPI part. Just fill in what we need
2481                  * and return.
2482                  */
2483                 state->hs_fw_cmdset = HERMON_FLASH_SPI_CMDSET;
2484                 state->hs_fw_log_sector_sz = HERMON_FLASH_SPI_LOG_SECTOR_SIZE;
2485                 state->hs_fw_device_sz = HERMON_FLASH_SPI_DEVICE_SIZE;
2486 
2487                 /*
2488                  * set this to inform caller of cmdset type.
2489                  */
2490                 cfi_ch_info[0x13] = HERMON_FLASH_SPI_CMDSET;
2491                 hermon_flash_cfi_dword(&cfi_info[4], cfi_ch_info, 0x10);
2492                 return (0);
2493         }
2494 
2495         /*
2496          * Determine if the user command supports the Intel Extended
2497          * Command Set. The query string is contained in the fourth
2498          * quad word.
2499          */
2500         hermon_flash_cfi_byte(cfi_ch_info, cfi_info[0x04], 0x10);
2501         if (cfi_ch_info[0x10] == 'M' &&
2502             cfi_ch_info[0x11] == 'X' &&
2503             cfi_ch_info[0x12] == '2') {
2504                 *intel_xcmd = 1; /* support is there */
2505                 if (hermon_verbose) {
2506                         IBTF_DPRINTF_L2("hermon",
2507                             "Support for Intel X is present\n");
2508                 }
2509         }
2510 
2511         /* CFI QUERY */
2512         hermon_flash_write(state, 0x55, HERMON_FLASH_CFI_INIT, &status);
2513         if (status != 0) {
2514                 return (status);
2515         }
2516 
2517         /* temporarily set the cmdset in order to do the initial read */
2518         state->hs_fw_cmdset = HERMON_FLASH_INTEL_CMDSET;
2519 
2520         /* Read in CFI data */
2521         for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 4) {
2522                 data = hermon_flash_read(state, i, &status);
2523                 if (status != 0) {
2524                         return (status);
2525                 }
2526                 cfi_dw_info[i >> 2] = data;
2527                 hermon_flash_cfi_byte(cfi_ch_info, data, i);
2528         }
2529 
2530         /* Determine chip set */
2531         state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2532         if (cfi_ch_info[0x20] == 'Q' &&
2533             cfi_ch_info[0x22] == 'R' &&
2534             cfi_ch_info[0x24] == 'Y') {
2535                 /*
2536                  * Mode: x16 working in x8 mode (Intel).
2537                  * Pack data - skip spacing bytes.
2538                  */
2539                 if (hermon_verbose) {
2540                         IBTF_DPRINTF_L2("hermon",
2541                             "x16 working in x8 mode (Intel)\n");
2542                 }
2543                 for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 2) {
2544                         cfi_ch_info[i/2] = cfi_ch_info[i];
2545                 }
2546         }
2547         state->hs_fw_cmdset = cfi_ch_info[0x13];
2548 
2549         if (state->hs_fw_cmdset != HERMON_FLASH_INTEL_CMDSET &&
2550             state->hs_fw_cmdset != HERMON_FLASH_AMD_CMDSET) {
2551                 cmn_err(CE_WARN,
2552                     "hermon_flash_cfi_init: UNKNOWN chip cmd set 0x%04x\n",
2553                     state->hs_fw_cmdset);
2554                 state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2555                 return (0);
2556         }
2557 
2558         /* Determine total bytes in one sector size */
2559         sector_sz_bytes = ((cfi_ch_info[0x30] << 8) | cfi_ch_info[0x2F]) << 8;
2560 
2561         /* Calculate equivalent of log2 (n) */
2562         for (bit_count = 0; sector_sz_bytes > 1; bit_count++) {
2563                 sector_sz_bytes >>= 1;
2564         }
2565 
2566         /* Set sector size */
2567         state->hs_fw_log_sector_sz = bit_count;
2568 
2569         /* Set flash size */
2570         state->hs_fw_device_sz = 0x1 << cfi_ch_info[0x27];
2571 
2572         /* Reset to turn off CFI mode */
2573         if ((status = hermon_flash_reset(state)) != 0)
2574                 goto out;
2575 
2576         /* Pass CFI data back to user command. */
2577         for (i = 0; i < HERMON_FLASH_CFI_SIZE_QUADLET; i++) {
2578                 hermon_flash_cfi_dword(&cfi_info[i], cfi_ch_info, i << 2);
2579         }
2580 
2581         if (*intel_xcmd == 1) {
2582                 /*
2583                  * Inform the user cmd that this driver does support the
2584                  * Intel Extended Command Set.
2585                  */
2586                 cfi_ch_info[0x10] = 'M';
2587                 cfi_ch_info[0x11] = 'X';
2588                 cfi_ch_info[0x12] = '2';
2589         } else {
2590                 cfi_ch_info[0x10] = 'Q';
2591                 cfi_ch_info[0x11] = 'R';
2592                 cfi_ch_info[0x12] = 'Y';
2593         }
2594         cfi_ch_info[0x13] = state->hs_fw_cmdset;
2595         hermon_flash_cfi_dword(&cfi_info[0x4], cfi_ch_info, 0x10);
2596 out:
2597         return (status);
2598 }
2599 
2600 /*
2601  * hermon_flash_fini()
2602  */
2603 static int
2604 hermon_flash_fini(hermon_state_t *state)
2605 {
2606         int status;
2607         ddi_acc_handle_t hdl;
2608 
2609         /* initialize the FMA retry loop */
2610         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2611 
2612         /* Set handle */
2613         hdl = hermon_get_pcihdl(state);
2614 
2615         if ((status = hermon_flash_bank(state, 0)) != 0)
2616                 return (status);
2617 
2618         /* the FMA retry loop starts. */
2619         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2620             fm_test);
2621 
2622         /*
2623          * Restore original GPIO Values
2624          */
2625         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA,
2626             state->hs_fw_gpio[0]);
2627 
2628         /* unlock GPIOs */
2629         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2630             HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2631 
2632         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0,
2633             state->hs_fw_gpio[1]);
2634         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1,
2635             state->hs_fw_gpio[2]);
2636 
2637         /* re-lock GPIOs */
2638         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2639 
2640         /* Give up gpio semaphore */
2641         hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_SEMA, 0);
2642 
2643         /* the FMA retry loop ends. */
2644         hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2645         return (0);
2646 
2647 pio_error:
2648         hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2649         return (EIO);
2650 }
2651 
2652 /*
2653  * hermon_flash_read_cfg
2654  */
2655 static uint32_t
2656 hermon_flash_read_cfg(hermon_state_t *state, ddi_acc_handle_t pci_config_hdl,
2657     uint32_t addr)
2658 {
2659         uint32_t        read;
2660 
2661         if (do_bar0) {
2662                 read = ddi_get32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2663                     (state->hs_reg_cmd_baseaddr + addr));
2664         } else {
2665                 /*
2666                  * Perform flash read operation:
2667                  *   1) Place addr to read from on the HERMON_HW_FLASH_CFG_ADDR
2668                  *      register
2669                  *   2) Read data at that addr from the HERMON_HW_FLASH_CFG_DATA
2670                  *       register
2671                  */
2672                 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2673                     addr);
2674                 read = pci_config_get32(pci_config_hdl,
2675                     HERMON_HW_FLASH_CFG_DATA);
2676         }
2677 
2678         return (read);
2679 }
2680 
2681 #ifdef DO_WRCONF
2682 static void
2683 hermon_flash_write_cfg(hermon_state_t *state,
2684     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2685 {
2686         hermon_flash_write_cfg_helper(state, pci_config_hdl, addr, data);
2687         hermon_flash_write_confirm(state, pci_config_hdl);
2688 }
2689 
2690 static void
2691 hermon_flash_write_confirm(hermon_state_t *state,
2692     ddi_acc_handle_t pci_config_hdl)
2693 {
2694         uint32_t        sem_value = 1;
2695 
2696         hermon_flash_write_cfg_helper(state, pci_config_hdl,
2697             HERMON_HW_FLASH_WRCONF_SEMA, 0);
2698         while (sem_value) {
2699                 sem_value = hermon_flash_read_cfg(state, pci_config_hdl,
2700                     HERMON_HW_FLASH_WRCONF_SEMA);
2701         }
2702 }
2703 #endif
2704 
2705 /*
2706  * hermon_flash_write_cfg
2707  */
2708 static void
2709 #ifdef DO_WRCONF
2710 hermon_flash_write_cfg_helper(hermon_state_t *state,
2711     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2712 #else
2713 hermon_flash_write_cfg(hermon_state_t *state,
2714     ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2715 #endif
2716 {
2717         if (do_bar0) {
2718                 ddi_put32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2719                     (state->hs_reg_cmd_baseaddr + addr), data);
2720 
2721         } else {
2722 
2723                 /*
2724                  * Perform flash write operation:
2725                  *   1) Place addr to write to on the HERMON_HW_FLASH_CFG_ADDR
2726                  *      register
2727                  *   2) Place data to write on to the HERMON_HW_FLASH_CFG_DATA
2728                  *      register
2729                  */
2730                 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2731                     addr);
2732                 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_DATA,
2733                     data);
2734         }
2735 }
2736 
2737 /*
2738  * Support routines to convert Common Flash Interface (CFI) data
2739  * from a 32  bit word to a char array, and from a char array to
2740  * a 32 bit word.
2741  */
2742 static void
2743 hermon_flash_cfi_byte(uint8_t *ch, uint32_t dword, int i)
2744 {
2745         ch[i] = (uint8_t)((dword & 0xFF000000) >> 24);
2746         ch[i+1] = (uint8_t)((dword & 0x00FF0000) >> 16);
2747         ch[i+2] = (uint8_t)((dword & 0x0000FF00) >> 8);
2748         ch[i+3] = (uint8_t)((dword & 0x000000FF));
2749 }
2750 
2751 static void
2752 hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i)
2753 {
2754         *dword = (uint32_t)
2755             ((uint32_t)ch[i] << 24 |
2756             (uint32_t)ch[i+1] << 16 |
2757             (uint32_t)ch[i+2] << 8 |
2758             (uint32_t)ch[i+3]);
2759 }
2760 
2761 /*
2762  * hermon_loopback_free_qps
2763  */
2764 static void
2765 hermon_loopback_free_qps(hermon_loopback_state_t *lstate)
2766 {
2767         int i;
2768 
2769         if (lstate->hls_tx.hlc_qp_hdl != NULL) {
2770                 (void) hermon_qp_free(lstate->hls_state,
2771                     &lstate->hls_tx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2772                     HERMON_NOSLEEP);
2773         }
2774         if (lstate->hls_rx.hlc_qp_hdl != NULL) {
2775                 (void) hermon_qp_free(lstate->hls_state,
2776                     &lstate->hls_rx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2777                     HERMON_NOSLEEP);
2778         }
2779         lstate->hls_tx.hlc_qp_hdl = NULL;
2780         lstate->hls_rx.hlc_qp_hdl = NULL;
2781         for (i = 0; i < 2; i++) {
2782                 if (lstate->hls_tx.hlc_cqhdl[i] != NULL) {
2783                         (void) hermon_cq_free(lstate->hls_state,
2784                             &lstate->hls_tx.hlc_cqhdl[i], HERMON_NOSLEEP);
2785                 }
2786                 if (lstate->hls_rx.hlc_cqhdl[i] != NULL) {
2787                         (void) hermon_cq_free(lstate->hls_state,
2788                             &lstate->hls_rx.hlc_cqhdl[i], HERMON_NOSLEEP);
2789                 }
2790                 lstate->hls_tx.hlc_cqhdl[i] = NULL;
2791                 lstate->hls_rx.hlc_cqhdl[i] = NULL;
2792         }
2793 }
2794 
2795 /*
2796  * hermon_loopback_free_state
2797  */
2798 static void
2799 hermon_loopback_free_state(hermon_loopback_state_t *lstate)
2800 {
2801         hermon_loopback_free_qps(lstate);
2802         if (lstate->hls_tx.hlc_mrhdl != NULL) {
2803                 (void) hermon_mr_deregister(lstate->hls_state,
2804                     &lstate->hls_tx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2805                     HERMON_NOSLEEP);
2806         }
2807         if (lstate->hls_rx.hlc_mrhdl !=  NULL) {
2808                 (void) hermon_mr_deregister(lstate->hls_state,
2809                     &lstate->hls_rx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2810                     HERMON_NOSLEEP);
2811         }
2812         if (lstate->hls_pd_hdl != NULL) {
2813                 (void) hermon_pd_free(lstate->hls_state, &lstate->hls_pd_hdl);
2814         }
2815         if (lstate->hls_tx.hlc_buf != NULL) {
2816                 kmem_free(lstate->hls_tx.hlc_buf, lstate->hls_tx.hlc_buf_sz);
2817         }
2818         if (lstate->hls_rx.hlc_buf != NULL) {
2819                 kmem_free(lstate->hls_rx.hlc_buf, lstate->hls_rx.hlc_buf_sz);
2820         }
2821         bzero(lstate, sizeof (hermon_loopback_state_t));
2822 }
2823 
2824 /*
2825  * hermon_loopback_init
2826  */
2827 static int
2828 hermon_loopback_init(hermon_state_t *state, hermon_loopback_state_t *lstate)
2829 {
2830         lstate->hls_hca_hdl = (ibc_hca_hdl_t)state;
2831         lstate->hls_status  = hermon_pd_alloc(lstate->hls_state,
2832             &lstate->hls_pd_hdl, HERMON_NOSLEEP);
2833         if (lstate->hls_status != IBT_SUCCESS) {
2834                 lstate->hls_err = HERMON_LOOPBACK_PROT_DOMAIN_ALLOC_FAIL;
2835                 return (EFAULT);
2836         }
2837 
2838         return (0);
2839 }
2840 
2841 /*
2842  * hermon_loopback_init_qp_info
2843  */
2844 static void
2845 hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
2846     hermon_loopback_comm_t *comm)
2847 {
2848         bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2849         bzero(&comm->hlc_qp_attr, sizeof (ibt_qp_alloc_attr_t));
2850         bzero(&comm->hlc_qp_info, sizeof (ibt_qp_info_t));
2851 
2852         comm->hlc_wrid = 1;
2853         comm->hlc_cq_attr.cq_size = 128;
2854         comm->hlc_qp_attr.qp_sizes.cs_sq_sgl = 3;
2855         comm->hlc_qp_attr.qp_sizes.cs_rq_sgl = 3;
2856         comm->hlc_qp_attr.qp_sizes.cs_sq = 16;
2857         comm->hlc_qp_attr.qp_sizes.cs_rq = 16;
2858         comm->hlc_qp_attr.qp_flags = IBT_WR_SIGNALED;
2859 
2860         comm->hlc_qp_info.qp_state = IBT_STATE_RESET;
2861         comm->hlc_qp_info.qp_trans = IBT_RC_SRV;
2862         comm->hlc_qp_info.qp_flags = IBT_CEP_RDMA_RD | IBT_CEP_RDMA_WR;
2863         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
2864             lstate->hls_port;
2865         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_pkey_ix =
2866             lstate->hls_pkey_ix;
2867         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_timeout =
2868             lstate->hls_timeout;
2869         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srvl = 0;
2870         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srate =
2871             IBT_SRATE_4X;
2872         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_send_grh = 0;
2873         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid =
2874             lstate->hls_lid;
2875         comm->hlc_qp_info.qp_transport.rc.rc_retry_cnt = lstate->hls_retry;
2876         comm->hlc_qp_info.qp_transport.rc.rc_sq_psn = 0;
2877         comm->hlc_qp_info.qp_transport.rc.rc_rq_psn = 0;
2878         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_in       = 4;
2879         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_out = 4;
2880         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = 0;
2881         comm->hlc_qp_info.qp_transport.rc.rc_min_rnr_nak = IBT_RNR_NAK_655ms;
2882         comm->hlc_qp_info.qp_transport.rc.rc_path_mtu = IB_MTU_1K;
2883 }
2884 
2885 /*
2886  * hermon_loopback_alloc_mem
2887  */
2888 static int
2889 hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
2890     hermon_loopback_comm_t *comm, int sz)
2891 {
2892         /* Allocate buffer of specified size */
2893         comm->hlc_buf_sz = sz;
2894         comm->hlc_buf         = kmem_zalloc(sz, KM_NOSLEEP);
2895         if (comm->hlc_buf == NULL) {
2896                 return (EFAULT);
2897         }
2898 
2899         /* Register the buffer as a memory region */
2900         comm->hlc_memattr.mr_vaddr = (uint64_t)(uintptr_t)comm->hlc_buf;
2901         comm->hlc_memattr.mr_len   = (ib_msglen_t)sz;
2902         comm->hlc_memattr.mr_as         = NULL;
2903         comm->hlc_memattr.mr_flags = IBT_MR_NOSLEEP |
2904             IBT_MR_ENABLE_REMOTE_WRITE | IBT_MR_ENABLE_LOCAL_WRITE;
2905 
2906         comm->hlc_status = hermon_mr_register(lstate->hls_state,
2907             lstate->hls_pd_hdl, &comm->hlc_memattr, &comm->hlc_mrhdl,
2908             NULL, HERMON_MPT_DMPT);
2909 
2910         comm->hlc_mrdesc.md_vaddr  = comm->hlc_mrhdl->mr_bindinfo.bi_addr;
2911         comm->hlc_mrdesc.md_lkey   = comm->hlc_mrhdl->mr_lkey;
2912         comm->hlc_mrdesc.md_rkey   = comm->hlc_mrhdl->mr_rkey;
2913         if (comm->hlc_status != IBT_SUCCESS) {
2914                 return (EFAULT);
2915         }
2916         return (0);
2917 }
2918 
2919 /*
2920  * hermon_loopback_alloc_qps
2921  */
2922 static int
2923 hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
2924     hermon_loopback_comm_t *comm)
2925 {
2926         uint32_t                i, real_size;
2927         hermon_qp_info_t                qpinfo;
2928 
2929         /* Allocate send and recv CQs */
2930         for (i = 0; i < 2; i++) {
2931                 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2932                 comm->hlc_cq_attr.cq_size = 128;
2933                 comm->hlc_status = hermon_cq_alloc(lstate->hls_state,
2934                     (ibt_cq_hdl_t)NULL, &comm->hlc_cq_attr, &real_size,
2935                     &comm->hlc_cqhdl[i], HERMON_NOSLEEP);
2936                 if (comm->hlc_status != IBT_SUCCESS) {
2937                         lstate->hls_err += i;
2938                         return (EFAULT);
2939                 }
2940         }
2941 
2942         /* Allocate the QP */
2943         hermon_loopback_init_qp_info(lstate, comm);
2944         comm->hlc_qp_attr.qp_pd_hdl   = (ibt_pd_hdl_t)lstate->hls_pd_hdl;
2945         comm->hlc_qp_attr.qp_scq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[0];
2946         comm->hlc_qp_attr.qp_rcq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[1];
2947         comm->hlc_qp_attr.qp_ibc_scq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[0];
2948         comm->hlc_qp_attr.qp_ibc_rcq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[1];
2949         qpinfo.qpi_attrp        = &comm->hlc_qp_attr;
2950         qpinfo.qpi_type         = IBT_RC_RQP;
2951         qpinfo.qpi_ibt_qphdl    = NULL;
2952         qpinfo.qpi_queueszp     = &comm->hlc_chan_sizes;
2953         qpinfo.qpi_qpn          = &comm->hlc_qp_num;
2954         comm->hlc_status = hermon_qp_alloc(lstate->hls_state, &qpinfo,
2955             HERMON_NOSLEEP);
2956         if (comm->hlc_status == DDI_SUCCESS) {
2957                 comm->hlc_qp_hdl = qpinfo.qpi_qphdl;
2958         }
2959 
2960         if (comm->hlc_status != IBT_SUCCESS) {
2961                 lstate->hls_err += 2;
2962                 return (EFAULT);
2963         }
2964         return (0);
2965 }
2966 
2967 /*
2968  * hermon_loopback_modify_qp
2969  */
2970 static int
2971 hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
2972     hermon_loopback_comm_t *comm, uint_t qp_num)
2973 {
2974         /* Modify QP to INIT */
2975         hermon_loopback_init_qp_info(lstate, comm);
2976         comm->hlc_qp_info.qp_state = IBT_STATE_INIT;
2977         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2978             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2979         if (comm->hlc_status != IBT_SUCCESS) {
2980                 return (EFAULT);
2981         }
2982 
2983         /*
2984          * Modify QP to RTR (set destination LID and QP number to local
2985          * LID and QP number)
2986          */
2987         comm->hlc_qp_info.qp_state = IBT_STATE_RTR;
2988         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid
2989             = lstate->hls_lid;
2990         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = qp_num;
2991         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2992             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2993         if (comm->hlc_status != IBT_SUCCESS) {
2994                 lstate->hls_err += 1;
2995                 return (EFAULT);
2996         }
2997 
2998         /* Modify QP to RTS */
2999         comm->hlc_qp_info.qp_current_state = IBT_STATE_RTR;
3000         comm->hlc_qp_info.qp_state = IBT_STATE_RTS;
3001         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3002             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3003         if (comm->hlc_status != IBT_SUCCESS) {
3004                 lstate->hls_err += 2;
3005                 return (EFAULT);
3006         }
3007         return (0);
3008 }
3009 
3010 /*
3011  * hermon_loopback_copyout
3012  */
3013 static int
3014 hermon_loopback_copyout(hermon_loopback_ioctl_t *lb, intptr_t arg, int mode)
3015 {
3016 #ifdef _MULTI_DATAMODEL
3017         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
3018                 hermon_loopback_ioctl32_t lb32;
3019 
3020                 lb32.alb_revision       = lb->alb_revision;
3021                 lb32.alb_send_buf       =
3022                     (caddr32_t)(uintptr_t)lb->alb_send_buf;
3023                 lb32.alb_fail_buf       =
3024                     (caddr32_t)(uintptr_t)lb->alb_fail_buf;
3025                 lb32.alb_buf_sz         = lb->alb_buf_sz;
3026                 lb32.alb_num_iter       = lb->alb_num_iter;
3027                 lb32.alb_pass_done      = lb->alb_pass_done;
3028                 lb32.alb_timeout        = lb->alb_timeout;
3029                 lb32.alb_error_type     = lb->alb_error_type;
3030                 lb32.alb_port_num       = lb->alb_port_num;
3031                 lb32.alb_num_retry      = lb->alb_num_retry;
3032 
3033                 if (ddi_copyout(&lb32, (void *)arg,
3034                     sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
3035                         return (EFAULT);
3036                 }
3037         } else
3038 #endif /* _MULTI_DATAMODEL */
3039         if (ddi_copyout(lb, (void *)arg, sizeof (hermon_loopback_ioctl_t),
3040             mode) != 0) {
3041                 return (EFAULT);
3042         }
3043         return (0);
3044 }
3045 
3046 /*
3047  * hermon_loopback_post_send
3048  */
3049 static int
3050 hermon_loopback_post_send(hermon_loopback_state_t *lstate,
3051     hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx)
3052 {
3053         int      ret;
3054 
3055         bzero(&tx->hlc_sgl, sizeof (ibt_wr_ds_t));
3056         bzero(&tx->hlc_wr, sizeof (ibt_send_wr_t));
3057 
3058         /* Initialize local address for TX buffer */
3059         tx->hlc_sgl.ds_va   = tx->hlc_mrdesc.md_vaddr;
3060         tx->hlc_sgl.ds_key  = tx->hlc_mrdesc.md_lkey;
3061         tx->hlc_sgl.ds_len  = tx->hlc_buf_sz;
3062 
3063         /* Initialize the remaining details of the work request */
3064         tx->hlc_wr.wr_id = tx->hlc_wrid++;
3065         tx->hlc_wr.wr_flags  = IBT_WR_SEND_SIGNAL;
3066         tx->hlc_wr.wr_nds    = 1;
3067         tx->hlc_wr.wr_sgl    = &tx->hlc_sgl;
3068         tx->hlc_wr.wr_opcode = IBT_WRC_RDMAW;
3069         tx->hlc_wr.wr_trans  = IBT_RC_SRV;
3070 
3071         /* Initialize the remote address for RX buffer */
3072         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_raddr = rx->hlc_mrdesc.md_vaddr;
3073         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_rkey  = rx->hlc_mrdesc.md_rkey;
3074         tx->hlc_complete = 0;
3075         ret = hermon_post_send(lstate->hls_state, tx->hlc_qp_hdl, &tx->hlc_wr,
3076             1, NULL);
3077         if (ret != IBT_SUCCESS) {
3078                 return (EFAULT);
3079         }
3080         return (0);
3081 }
3082 
3083 /*
3084  * hermon_loopback_poll_cq
3085  */
3086 static int
3087 hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
3088     hermon_loopback_comm_t *comm)
3089 {
3090         comm->hlc_wc.wc_status       = 0;
3091         comm->hlc_num_polled = 0;
3092         comm->hlc_status = hermon_cq_poll(lstate->hls_state,
3093             comm->hlc_cqhdl[0], &comm->hlc_wc, 1, &comm->hlc_num_polled);
3094         if ((comm->hlc_status == IBT_SUCCESS) &&
3095             (comm->hlc_wc.wc_status != IBT_WC_SUCCESS)) {
3096                 comm->hlc_status = ibc_get_ci_failure(0);
3097         }
3098         return (comm->hlc_status);
3099 }