8787 hermon: variable 'cfi_dw_info' set but not used
[unleashed.git] / usr / src / uts / common / io / ib / adapters / hermon / hermon_ioctl.c
blobf543ec59fea32ae1b399cfb639e7b78df50564c3
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
27 * hermon_ioctl.c
28 * Hemron IOCTL Routines
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.
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>
42 #include <sys/ib/adapters/hermon/hermon.h>
44 /* Hemron HCA state pointer (extern) */
45 extern void *hermon_statep;
46 extern int hermon_verbose;
48 #define DO_WRCONF 1
49 static int do_bar0 = 1;
52 * The ioctl declarations (for firmware flash burning, register read/write
53 * (DEBUG-only), and VTS interfaces)
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);
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);
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);
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;
149 * hermon_ioctl()
151 /* ARGSUSED */
153 hermon_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
154 int *rvalp)
156 hermon_state_t *state;
157 minor_t instance;
158 int status;
160 if (drv_priv(credp) != 0) {
161 return (EPERM);
164 instance = HERMON_DEV_INSTANCE(dev);
165 if (instance == (minor_t)-1) {
166 return (EBADF);
169 state = ddi_get_soft_state(hermon_statep, instance);
170 if (state == NULL) {
171 return (EBADF);
174 status = 0;
176 switch (cmd) {
177 case HERMON_IOCTL_FLASH_READ:
178 status = hermon_ioctl_flash_read(state, dev, arg, mode);
179 break;
181 case HERMON_IOCTL_FLASH_WRITE:
182 status = hermon_ioctl_flash_write(state, dev, arg, mode);
183 break;
185 case HERMON_IOCTL_FLASH_ERASE:
186 status = hermon_ioctl_flash_erase(state, dev, arg, mode);
187 break;
189 case HERMON_IOCTL_FLASH_INIT:
190 status = hermon_ioctl_flash_init(state, dev, arg, mode);
191 break;
193 case HERMON_IOCTL_FLASH_FINI:
194 status = hermon_ioctl_flash_fini(state, dev);
195 break;
197 case HERMON_IOCTL_INFO:
198 status = hermon_ioctl_info(state, dev, arg, mode);
199 break;
201 case HERMON_IOCTL_PORTS:
202 status = hermon_ioctl_ports(state, arg, mode);
203 break;
205 case HERMON_IOCTL_LOOPBACK:
206 status = hermon_ioctl_loopback(state, arg, mode);
207 break;
209 #ifdef DEBUG
210 case HERMON_IOCTL_REG_WRITE:
211 status = hermon_ioctl_reg_write(state, arg, mode);
212 break;
214 case HERMON_IOCTL_REG_READ:
215 status = hermon_ioctl_reg_read(state, arg, mode);
216 break;
217 #endif /* DEBUG */
219 case HERMON_IOCTL_DDR_READ:
220 /* XXX guard until the ioctl header is cleaned up */
221 status = ENODEV;
222 break;
224 case HERMON_IOCTL_WRITE_BOOT_ADDR:
225 status = hermon_ioctl_write_boot_addr(state, dev, arg, mode);
226 break;
228 default:
229 status = ENOTTY;
230 break;
232 *rvalp = status;
234 return (status);
238 * hermon_ioctl_flash_read()
240 static int
241 hermon_ioctl_flash_read(hermon_state_t *state, dev_t dev, intptr_t arg,
242 int mode)
244 hermon_flash_ioctl_t ioctl_info;
245 int status = 0;
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.
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);
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;
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);
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);
281 * Determine type of READ ioctl
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);
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);
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);
307 break;
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);
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);
323 break;
325 default:
326 mutex_exit(&state->hs_fw_flashlock);
327 return (EINVAL);
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;
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;
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);
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);
354 mutex_exit(&state->hs_fw_flashlock);
355 return (status);
359 * hermon_ioctl_flash_write()
361 static int
362 hermon_ioctl_flash_write(hermon_state_t *state, dev_t dev, intptr_t arg,
363 int mode)
365 hermon_flash_ioctl_t ioctl_info;
366 int status = 0;
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.
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);
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;
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);
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);
403 * Determine type of WRITE ioctl
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);
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);
422 /* Perform Write Sector */
423 status = hermon_flash_write_sector(state,
424 ioctl_info.af_sector_num);
425 break;
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);
434 /* Perform Write Byte */
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.
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);
449 break;
451 default:
452 status = EINVAL;
453 break;
456 mutex_exit(&state->hs_fw_flashlock);
457 return (status);
461 * hermon_ioctl_flash_erase()
463 static int
464 hermon_ioctl_flash_erase(hermon_state_t *state, dev_t dev, intptr_t arg,
465 int mode)
467 hermon_flash_ioctl_t ioctl_info;
468 int status = 0;
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.
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);
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;
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);
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);
502 * Determine type of ERASE ioctl
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);
513 /* Perform Sector Erase */
514 status = hermon_flash_erase_sector(state,
515 ioctl_info.af_sector_num);
516 break;
518 case HERMON_FLASH_ERASE_CHIP:
519 /* Perform Chip Erase */
520 status = hermon_flash_erase_chip(state);
521 break;
523 default:
524 status = EINVAL;
525 break;
528 mutex_exit(&state->hs_fw_flashlock);
529 return (status);
533 * hermon_ioctl_flash_init()
535 static int
536 hermon_ioctl_flash_init(hermon_state_t *state, dev_t dev, intptr_t arg,
537 int mode)
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);
544 /* initialize the FMA retry loop */
545 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
547 state->hs_fw_sector = NULL;
550 * init cannot be called more than once. If we have already init'd the
551 * flash, return directly.
553 mutex_enter(&state->hs_fw_flashlock);
554 if (state->hs_fw_flashstarted == 1) {
555 mutex_exit(&state->hs_fw_flashlock);
556 return (EINVAL);
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);
566 /* Init Flash */
567 if ((ret = hermon_flash_init(state)) != 0) {
568 if (ret == EIO) {
569 goto pio_error;
571 mutex_exit(&state->hs_fw_flashlock);
572 return (ret);
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;
581 mutex_exit(&state->hs_fw_flashlock);
582 return (ret);
586 * Return error if the command set is unknown.
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;
593 mutex_exit(&state->hs_fw_flashlock);
594 return (ret);
596 mutex_exit(&state->hs_fw_flashlock);
597 return (EFAULT);
600 /* the FMA retry loop starts. */
601 hermon_pio_start(state, pci_hdl, pio_error,
602 fm_loop_cnt, fm_status, fm_test);
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;
608 /* the FMA retry loop ends. */
609 hermon_pio_end(state, pci_hdl, pio_error, fm_loop_cnt,
610 fm_status, fm_test);
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;
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);
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);
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;
635 mutex_exit(&state->hs_fw_flashlock);
636 return (ret);
638 mutex_exit(&state->hs_fw_flashlock);
639 return (EFAULT);
642 /* Set flash state to started */
643 state->hs_fw_flashstarted = 1;
644 state->hs_fw_flashdev = dev;
646 mutex_exit(&state->hs_fw_flashlock);
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.
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);
664 return (status);
667 return (0);
669 pio_error:
670 mutex_exit(&state->hs_fw_flashlock);
671 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
672 return (EIO);
676 * hermon_ioctl_flash_fini()
678 static int
679 hermon_ioctl_flash_fini(hermon_state_t *state, dev_t dev)
681 int ret;
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.
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);
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);
699 return (ret);
701 mutex_exit(&state->hs_fw_flashlock);
704 * If "flash fini" is successful, remove the "on close" callback
705 * that was setup during "flash init".
707 ret = hermon_umap_db_clear_onclose_cb(dev,
708 HERMON_ONCLOSE_FLASH_INPROGRESS);
709 if (ret != DDI_SUCCESS) {
710 return (EFAULT);
712 return (0);
717 * hermon_ioctl_flash_cleanup()
719 static int
720 hermon_ioctl_flash_cleanup(hermon_state_t *state)
722 int status;
724 mutex_enter(&state->hs_fw_flashlock);
725 status = hermon_ioctl_flash_cleanup_nolock(state);
726 mutex_exit(&state->hs_fw_flashlock);
728 return (status);
733 * hermon_ioctl_flash_cleanup_nolock()
735 static int
736 hermon_ioctl_flash_cleanup_nolock(hermon_state_t *state)
738 int status;
739 ASSERT(MUTEX_HELD(&state->hs_fw_flashlock));
741 /* free flash mem */
742 if (state->hs_fw_sector) {
743 kmem_free(state->hs_fw_sector, 1 << state->hs_fw_log_sector_sz);
746 /* Fini the Flash */
747 if ((status = hermon_flash_fini(state)) != 0)
748 return (status);
750 /* Set flash state to fini */
751 state->hs_fw_flashstarted = 0;
752 state->hs_fw_flashdev = 0;
753 return (0);
758 * hermon_ioctl_info()
760 static int
761 hermon_ioctl_info(hermon_state_t *state, dev_t dev, intptr_t arg, int mode)
763 hermon_info_ioctl_t info;
764 hermon_flash_init_ioctl_t init_info;
767 * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
769 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
770 return (EFAULT);
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);
780 * Check ioctl revision
782 if (info.ai_revision != HERMON_VTS_IOCTL_REVISION) {
783 return (EINVAL);
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.
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);
800 (void) hermon_ioctl_flash_fini(state, dev);
802 mutex_exit(&state->hs_info_lock);
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;
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);
816 return (0);
820 * hermon_ioctl_ports()
822 static int
823 hermon_ioctl_ports(hermon_state_t *state, intptr_t arg, int mode)
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;
834 * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
836 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
837 return (EFAULT);
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;
845 if (ddi_copyin((void *)arg, &info32,
846 sizeof (hermon_ports_ioctl32_t), mode) != 0) {
847 return (EFAULT);
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;
854 } else
855 #endif /* _MULTI_DATAMODEL */
856 if (ddi_copyin((void *)arg, &info, sizeof (hermon_ports_ioctl_t),
857 mode) != 0) {
858 return (EFAULT);
862 * Check ioctl revision
864 if (info.ap_revision != HERMON_VTS_IOCTL_REVISION) {
865 return (EINVAL);
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);
876 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sgid_tbl, *pkey_tbl))
879 * Setup the number of ports, then loop through all ports and
880 * query properties of each.
882 info.ap_num_ports = (uint8_t)state->hs_cfg_profile->cp_num_ports;
883 for (i = 0; i < info.ap_num_ports; i++) {
885 * Get portstate information from the device. If
886 * hermon_port_query() fails, leave zeroes in user
887 * struct port entry and continue.
889 bzero(&pi, sizeof (ibt_hca_portinfo_t));
890 pi.p_sgid_tbl = sgid_tbl;
891 pi.p_pkey_tbl = pkey_tbl;
892 (void) hermon_port_query(state, i + 1, &pi);
894 portstat.asp_port_num = pi.p_port_num;
895 portstat.asp_state = pi.p_linkstate;
896 portstat.asp_guid = pi.p_sgid_tbl[0].gid_guid;
899 * Copy queried port results back to user struct. If
900 * this fails, then break out of loop, attempt to copy
901 * out remaining info to user struct, and return (without
902 * error).
904 if (ddi_copyout(&portstat,
905 &(((hermon_stat_port_ioctl_t *)info.ap_ports)[i]),
906 sizeof (hermon_stat_port_ioctl_t), mode) != 0) {
907 break;
911 /* Free the temporary space used for GID table/PKey table */
912 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
913 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
914 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
915 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
917 /* Copy ioctl results back to user struct */
918 #ifdef _MULTI_DATAMODEL
919 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
920 hermon_ports_ioctl32_t info32;
922 info32.ap_revision = info.ap_revision;
923 info32.ap_ports = (caddr32_t)(uintptr_t)info.ap_ports;
924 info32.ap_num_ports = info.ap_num_ports;
926 if (ddi_copyout(&info32, (void *)arg,
927 sizeof (hermon_ports_ioctl32_t), mode) != 0) {
928 return (EFAULT);
930 } else
931 #endif /* _MULTI_DATAMODEL */
932 if (ddi_copyout(&info, (void *)arg, sizeof (hermon_ports_ioctl_t),
933 mode) != 0) {
934 return (EFAULT);
937 return (0);
941 * hermon_ioctl_loopback()
943 static int
944 hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg, int mode)
946 hermon_loopback_ioctl_t lb;
947 hermon_loopback_state_t lstate;
948 ibt_hca_portinfo_t pi;
949 uint_t tbl_size, loopmax, max_usec;
950 ib_gid_t *sgid_tbl;
951 ib_pkey_t *pkey_tbl;
952 int j, iter, ret;
954 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(lstate))
957 * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
959 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
960 return (EFAULT);
963 /* copyin the user struct to kernel */
964 #ifdef _MULTI_DATAMODEL
965 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
966 hermon_loopback_ioctl32_t lb32;
968 if (ddi_copyin((void *)arg, &lb32,
969 sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
970 return (EFAULT);
972 lb.alb_revision = lb32.alb_revision;
973 lb.alb_send_buf = (caddr_t)(uintptr_t)lb32.alb_send_buf;
974 lb.alb_fail_buf = (caddr_t)(uintptr_t)lb32.alb_fail_buf;
975 lb.alb_buf_sz = lb32.alb_buf_sz;
976 lb.alb_num_iter = lb32.alb_num_iter;
977 lb.alb_pass_done = lb32.alb_pass_done;
978 lb.alb_timeout = lb32.alb_timeout;
979 lb.alb_error_type = lb32.alb_error_type;
980 lb.alb_port_num = lb32.alb_port_num;
981 lb.alb_num_retry = lb32.alb_num_retry;
982 } else
983 #endif /* _MULTI_DATAMODEL */
984 if (ddi_copyin((void *)arg, &lb, sizeof (hermon_loopback_ioctl_t),
985 mode) != 0) {
986 return (EFAULT);
989 /* Initialize the internal loopback test state structure */
990 bzero(&lstate, sizeof (hermon_loopback_state_t));
993 * Check ioctl revision
995 if (lb.alb_revision != HERMON_VTS_IOCTL_REVISION) {
996 lb.alb_error_type = HERMON_LOOPBACK_INVALID_REVISION;
997 (void) hermon_loopback_copyout(&lb, arg, mode);
998 return (EINVAL);
1001 /* Validate that specified port number is legal */
1002 if (!hermon_portnum_is_valid(state, lb.alb_port_num)) {
1003 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1004 (void) hermon_loopback_copyout(&lb, arg, mode);
1005 return (EINVAL);
1008 /* Allocate space for temporary GID table/PKey table */
1009 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1010 sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
1011 KM_SLEEP);
1012 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1013 pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
1014 KM_SLEEP);
1017 * Get portstate information from specific port on device
1019 bzero(&pi, sizeof (ibt_hca_portinfo_t));
1020 pi.p_sgid_tbl = sgid_tbl;
1021 pi.p_pkey_tbl = pkey_tbl;
1022 if (hermon_port_query(state, lb.alb_port_num, &pi) != 0) {
1023 /* Free the temporary space used for GID table/PKey table */
1024 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1025 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1026 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1027 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1029 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1030 (void) hermon_loopback_copyout(&lb, arg, mode);
1031 hermon_loopback_free_state(&lstate);
1032 return (EINVAL);
1035 lstate.hls_port = pi.p_port_num;
1036 lstate.hls_lid = pi.p_base_lid;
1037 lstate.hls_pkey_ix = (pi.p_linkstate == HERMON_PORT_LINK_ACTIVE) ?
1038 1 : 0; /* XXX bogus assumption of a SUN subnet manager */
1039 lstate.hls_state = state;
1040 lstate.hls_retry = lb.alb_num_retry;
1042 /* Free the temporary space used for GID table/PKey table */
1043 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1044 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1045 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1046 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1049 * Compute the timeout duration in usec per the formula:
1050 * to_usec_per_retry = 4.096us * (2 ^ supplied_timeout)
1051 * (plus we add a little fudge-factor here too)
1053 lstate.hls_timeout = lb.alb_timeout;
1054 max_usec = (4096 * (1 << lstate.hls_timeout)) / 1000;
1055 max_usec = max_usec * (lstate.hls_retry + 1);
1056 max_usec = max_usec + 10000;
1059 * Determine how many times we should loop before declaring a
1060 * timeout failure.
1062 loopmax = max_usec/HERMON_VTS_LOOPBACK_MIN_WAIT_DUR;
1063 if ((max_usec % HERMON_VTS_LOOPBACK_MIN_WAIT_DUR) != 0) {
1064 loopmax++;
1067 if (lb.alb_send_buf == NULL || lb.alb_buf_sz == 0) {
1068 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_INVALID;
1069 (void) hermon_loopback_copyout(&lb, arg, mode);
1070 hermon_loopback_free_state(&lstate);
1071 return (EINVAL);
1074 /* Allocate protection domain (PD) */
1075 if (hermon_loopback_init(state, &lstate) != 0) {
1076 lb.alb_error_type = lstate.hls_err;
1077 (void) hermon_loopback_copyout(&lb, arg, mode);
1078 hermon_loopback_free_state(&lstate);
1079 return (EFAULT);
1082 /* Allocate and register a TX buffer */
1083 if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_tx,
1084 lb.alb_buf_sz) != 0) {
1085 lb.alb_error_type =
1086 HERMON_LOOPBACK_SEND_BUF_MEM_REGION_ALLOC_FAIL;
1087 (void) hermon_loopback_copyout(&lb, arg, mode);
1088 hermon_loopback_free_state(&lstate);
1089 return (EFAULT);
1092 /* Allocate and register an RX buffer */
1093 if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_rx,
1094 lb.alb_buf_sz) != 0) {
1095 lb.alb_error_type =
1096 HERMON_LOOPBACK_RECV_BUF_MEM_REGION_ALLOC_FAIL;
1097 (void) hermon_loopback_copyout(&lb, arg, mode);
1098 hermon_loopback_free_state(&lstate);
1099 return (EFAULT);
1102 /* Copy in the transmit buffer data */
1103 if (ddi_copyin((void *)lb.alb_send_buf, lstate.hls_tx.hlc_buf,
1104 lb.alb_buf_sz, mode) != 0) {
1105 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_COPY_FAIL;
1106 (void) hermon_loopback_copyout(&lb, arg, mode);
1107 hermon_loopback_free_state(&lstate);
1108 return (EFAULT);
1111 /* Allocate the transmit QP and CQs */
1112 lstate.hls_err = HERMON_LOOPBACK_XMIT_SEND_CQ_ALLOC_FAIL;
1113 if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_tx) != 0) {
1114 lb.alb_error_type = lstate.hls_err;
1115 (void) hermon_loopback_copyout(&lb, arg, mode);
1116 hermon_loopback_free_state(&lstate);
1117 return (EFAULT);
1120 /* Allocate the receive QP and CQs */
1121 lstate.hls_err = HERMON_LOOPBACK_RECV_SEND_CQ_ALLOC_FAIL;
1122 if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_rx) != 0) {
1123 lb.alb_error_type = lstate.hls_err;
1124 (void) hermon_loopback_copyout(&lb, arg, mode);
1125 hermon_loopback_free_state(&lstate);
1126 return (EFAULT);
1129 /* Activate the TX QP (connect to RX QP) */
1130 lstate.hls_err = HERMON_LOOPBACK_XMIT_QP_INIT_FAIL;
1131 if (hermon_loopback_modify_qp(&lstate, &lstate.hls_tx,
1132 lstate.hls_rx.hlc_qp_num) != 0) {
1133 lb.alb_error_type = lstate.hls_err;
1134 (void) hermon_loopback_copyout(&lb, arg, mode);
1135 hermon_loopback_free_state(&lstate);
1136 return (EFAULT);
1139 /* Activate the RX QP (connect to TX QP) */
1140 lstate.hls_err = HERMON_LOOPBACK_RECV_QP_INIT_FAIL;
1141 if (hermon_loopback_modify_qp(&lstate, &lstate.hls_rx,
1142 lstate.hls_tx.hlc_qp_num) != 0) {
1143 lb.alb_error_type = lstate.hls_err;
1144 (void) hermon_loopback_copyout(&lb, arg, mode);
1145 hermon_loopback_free_state(&lstate);
1146 return (EFAULT);
1149 /* Run the loopback test (for specified number of iterations) */
1150 lb.alb_pass_done = 0;
1151 for (iter = 0; iter < lb.alb_num_iter; iter++) {
1152 lstate.hls_err = 0;
1153 bzero(lstate.hls_rx.hlc_buf, lb.alb_buf_sz);
1155 /* Post RDMA Write work request */
1156 if (hermon_loopback_post_send(&lstate, &lstate.hls_tx,
1157 &lstate.hls_rx) != IBT_SUCCESS) {
1158 lb.alb_error_type = HERMON_LOOPBACK_WQE_POST_FAIL;
1159 (void) hermon_loopback_copyout(&lb, arg, mode);
1160 hermon_loopback_free_state(&lstate);
1161 return (EFAULT);
1164 /* Poll the TX CQ for a completion every few ticks */
1165 for (j = 0; j < loopmax; j++) {
1166 delay(drv_usectohz(HERMON_VTS_LOOPBACK_MIN_WAIT_DUR));
1168 ret = hermon_loopback_poll_cq(&lstate, &lstate.hls_tx);
1169 if (((ret != IBT_SUCCESS) && (ret != IBT_CQ_EMPTY)) ||
1170 ((ret == IBT_CQ_EMPTY) && (j == loopmax - 1))) {
1171 lb.alb_error_type =
1172 HERMON_LOOPBACK_CQ_POLL_FAIL;
1173 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1174 lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1175 mode) != 0) {
1176 return (EFAULT);
1178 (void) hermon_loopback_copyout(&lb, arg, mode);
1179 hermon_loopback_free_state(&lstate);
1180 return (EFAULT);
1181 } else if (ret == IBT_CQ_EMPTY) {
1182 continue;
1185 /* Compare the data buffers */
1186 if (bcmp(lstate.hls_tx.hlc_buf, lstate.hls_rx.hlc_buf,
1187 lb.alb_buf_sz) == 0) {
1188 break;
1189 } else {
1190 lb.alb_error_type =
1191 HERMON_LOOPBACK_SEND_RECV_COMPARE_FAIL;
1192 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1193 lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1194 mode) != 0) {
1195 return (EFAULT);
1197 (void) hermon_loopback_copyout(&lb, arg, mode);
1198 hermon_loopback_free_state(&lstate);
1199 return (EFAULT);
1203 lstate.hls_err = HERMON_LOOPBACK_SUCCESS;
1204 lb.alb_pass_done = iter + 1;
1207 lb.alb_error_type = HERMON_LOOPBACK_SUCCESS;
1209 /* Copy ioctl results back to user struct */
1210 ret = hermon_loopback_copyout(&lb, arg, mode);
1212 /* Free up everything and release all consumed resources */
1213 hermon_loopback_free_state(&lstate);
1215 return (ret);
1218 #ifdef DEBUG
1220 * hermon_ioctl_reg_read()
1222 static int
1223 hermon_ioctl_reg_read(hermon_state_t *state, intptr_t arg, int mode)
1225 hermon_reg_ioctl_t rdreg;
1226 uint32_t *addr;
1227 uintptr_t baseaddr;
1228 int status;
1229 ddi_acc_handle_t handle;
1231 /* initialize the FMA retry loop */
1232 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1235 * Access to Hemron registers is not allowed in "maintenance mode".
1236 * This is primarily because the device may not have BARs to access
1238 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1239 return (EFAULT);
1242 /* Copy in the hermon_reg_ioctl_t structure */
1243 status = ddi_copyin((void *)arg, &rdreg, sizeof (hermon_reg_ioctl_t),
1244 mode);
1245 if (status != 0) {
1246 return (EFAULT);
1249 /* Determine base address for requested register set */
1250 switch (rdreg.arg_reg_set) {
1251 case HERMON_CMD_BAR:
1252 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1253 handle = hermon_get_cmdhdl(state);
1254 break;
1256 case HERMON_UAR_BAR:
1257 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1258 handle = hermon_get_uarhdl(state);
1259 break;
1262 default:
1263 return (EINVAL);
1266 /* Ensure that address is properly-aligned */
1267 addr = (uint32_t *)((baseaddr + rdreg.arg_offset) & ~0x3);
1269 /* the FMA retry loop starts. */
1270 hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1271 fm_status, fm_test);
1273 /* Read the register pointed to by addr */
1274 rdreg.arg_data = ddi_get32(handle, addr);
1276 /* the FMA retry loop ends. */
1277 hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1278 fm_test);
1280 /* Copy in the result into the hermon_reg_ioctl_t structure */
1281 status = ddi_copyout(&rdreg, (void *)arg, sizeof (hermon_reg_ioctl_t),
1282 mode);
1283 if (status != 0) {
1284 return (EFAULT);
1286 return (0);
1288 pio_error:
1289 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1290 return (EIO);
1295 * hermon_ioctl_reg_write()
1297 static int
1298 hermon_ioctl_reg_write(hermon_state_t *state, intptr_t arg, int mode)
1300 hermon_reg_ioctl_t wrreg;
1301 uint32_t *addr;
1302 uintptr_t baseaddr;
1303 int status;
1304 ddi_acc_handle_t handle;
1306 /* initialize the FMA retry loop */
1307 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1310 * Access to Hermon registers is not allowed in "maintenance mode".
1311 * This is primarily because the device may not have BARs to access
1313 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1314 return (EFAULT);
1317 /* Copy in the hermon_reg_ioctl_t structure */
1318 status = ddi_copyin((void *)arg, &wrreg, sizeof (hermon_reg_ioctl_t),
1319 mode);
1320 if (status != 0) {
1321 return (EFAULT);
1324 /* Determine base address for requested register set */
1325 switch (wrreg.arg_reg_set) {
1326 case HERMON_CMD_BAR:
1327 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1328 handle = hermon_get_cmdhdl(state);
1329 break;
1331 case HERMON_UAR_BAR:
1332 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1333 handle = hermon_get_uarhdl(state);
1334 break;
1336 default:
1337 return (EINVAL);
1340 /* Ensure that address is properly-aligned */
1341 addr = (uint32_t *)((baseaddr + wrreg.arg_offset) & ~0x3);
1343 /* the FMA retry loop starts. */
1344 hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1345 fm_status, fm_test);
1347 /* Write the data to the register pointed to by addr */
1348 ddi_put32(handle, addr, wrreg.arg_data);
1350 /* the FMA retry loop ends. */
1351 hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1352 fm_test);
1353 return (0);
1355 pio_error:
1356 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1357 return (EIO);
1359 #endif /* DEBUG */
1361 static int
1362 hermon_ioctl_write_boot_addr(hermon_state_t *state, dev_t dev, intptr_t arg,
1363 int mode)
1365 hermon_flash_ioctl_t ioctl_info;
1367 /* initialize the FMA retry loop */
1368 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1371 * Check that flash init ioctl has been called first. And check
1372 * that the same dev_t that called init is the one calling write now.
1374 mutex_enter(&state->hs_fw_flashlock);
1375 if ((state->hs_fw_flashdev != dev) ||
1376 (state->hs_fw_flashstarted == 0)) {
1377 mutex_exit(&state->hs_fw_flashlock);
1378 return (EIO);
1381 /* copy user struct to kernel */
1382 #ifdef _MULTI_DATAMODEL
1383 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
1384 hermon_flash_ioctl32_t info32;
1386 if (ddi_copyin((void *)arg, &info32,
1387 sizeof (hermon_flash_ioctl32_t), mode) != 0) {
1388 mutex_exit(&state->hs_fw_flashlock);
1389 return (EFAULT);
1391 ioctl_info.af_type = info32.af_type;
1392 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
1393 ioctl_info.af_sector_num = info32.af_sector_num;
1394 ioctl_info.af_addr = info32.af_addr;
1395 ioctl_info.af_byte = info32.af_byte;
1396 } else
1397 #endif /* _MULTI_DATAMODEL */
1398 if (ddi_copyin((void *)arg, &ioctl_info,
1399 sizeof (hermon_flash_ioctl_t), mode) != 0) {
1400 mutex_exit(&state->hs_fw_flashlock);
1401 return (EFAULT);
1404 switch (state->hs_fw_cmdset) {
1405 case HERMON_FLASH_AMD_CMDSET:
1406 case HERMON_FLASH_INTEL_CMDSET:
1407 break;
1409 case HERMON_FLASH_SPI_CMDSET:
1411 ddi_acc_handle_t pci_hdl = hermon_get_pcihdl(state);
1413 /* the FMA retry loop starts. */
1414 hermon_pio_start(state, pci_hdl, pio_error,
1415 fm_loop_cnt, fm_status, fm_test);
1417 hermon_flash_write_cfg(state, pci_hdl,
1418 HERMON_HW_FLASH_SPI_BOOT_ADDR_REG,
1419 (ioctl_info.af_addr << 8) | 0x06);
1421 /* the FMA retry loop ends. */
1422 hermon_pio_end(state, pci_hdl, pio_error,
1423 fm_loop_cnt, fm_status, fm_test);
1424 break;
1427 case HERMON_FLASH_UNKNOWN_CMDSET:
1428 default:
1429 mutex_exit(&state->hs_fw_flashlock);
1430 return (EINVAL);
1432 mutex_exit(&state->hs_fw_flashlock);
1433 return (0);
1435 pio_error:
1436 mutex_exit(&state->hs_fw_flashlock);
1437 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1438 return (EIO);
1442 * hermon_flash_reset()
1444 static int
1445 hermon_flash_reset(hermon_state_t *state)
1447 int status;
1450 * Performs a reset to the flash device. After a reset the flash will
1451 * be operating in normal mode (capable of read/write, etc.).
1453 switch (state->hs_fw_cmdset) {
1454 case HERMON_FLASH_AMD_CMDSET:
1455 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_AMD,
1456 &status);
1457 if (status != 0) {
1458 return (status);
1460 break;
1462 case HERMON_FLASH_INTEL_CMDSET:
1463 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_INTEL,
1464 &status);
1465 if (status != 0) {
1466 return (status);
1468 break;
1470 /* It appears no reset is needed for SPI */
1471 case HERMON_FLASH_SPI_CMDSET:
1472 status = 0;
1473 break;
1475 case HERMON_FLASH_UNKNOWN_CMDSET:
1476 default:
1477 status = EINVAL;
1478 break;
1480 return (status);
1484 * hermon_flash_read_sector()
1486 static int
1487 hermon_flash_read_sector(hermon_state_t *state, uint32_t sector_num)
1489 uint32_t addr;
1490 uint32_t end_addr;
1491 uint32_t *image;
1492 int i, status;
1494 image = (uint32_t *)&state->hs_fw_sector[0];
1497 * Calculate the start and end address of the sector, based on the
1498 * sector number passed in.
1500 addr = sector_num << state->hs_fw_log_sector_sz;
1501 end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1503 /* Set the flash bank correctly for the given address */
1504 if ((status = hermon_flash_bank(state, addr)) != 0)
1505 return (status);
1507 /* Read the entire sector, one quadlet at a time */
1508 for (i = 0; addr < end_addr; i++, addr += 4) {
1509 image[i] = hermon_flash_read(state, addr, &status);
1510 if (status != 0) {
1511 return (status);
1514 return (0);
1518 * hermon_flash_read_quadlet()
1520 static int
1521 hermon_flash_read_quadlet(hermon_state_t *state, uint32_t *data,
1522 uint32_t addr)
1524 int status;
1526 /* Set the flash bank correctly for the given address */
1527 if ((status = hermon_flash_bank(state, addr)) != 0) {
1528 return (status);
1531 /* Read one quadlet of data */
1532 *data = hermon_flash_read(state, addr, &status);
1533 if (status != 0) {
1534 return (EIO);
1537 return (0);
1541 * hermon_flash_write_sector()
1543 static int
1544 hermon_flash_write_sector(hermon_state_t *state, uint32_t sector_num)
1546 uint32_t addr;
1547 uint32_t end_addr;
1548 uint32_t *databuf;
1549 uchar_t *sector;
1550 int status = 0;
1551 int i;
1553 sector = (uchar_t *)&state->hs_fw_sector[0];
1556 * Calculate the start and end address of the sector, based on the
1557 * sector number passed in.
1559 addr = sector_num << state->hs_fw_log_sector_sz;
1560 end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1562 /* Set the flash bank correctly for the given address */
1563 if ((status = hermon_flash_bank(state, addr)) != 0 ||
1564 (status = hermon_flash_reset(state)) != 0) {
1565 return (status);
1568 /* Erase the sector before writing */
1569 status = hermon_flash_erase_sector(state, sector_num);
1570 if (status != 0) {
1571 return (status);
1574 switch (state->hs_fw_cmdset) {
1575 case HERMON_FLASH_SPI_CMDSET:
1576 databuf = (uint32_t *)(void *)sector;
1577 /* Write the sector, one dword at a time */
1578 for (i = 0; addr < end_addr; i++, addr += 4) {
1579 if ((status = hermon_flash_spi_write_dword(state, addr,
1580 htonl(databuf[i]))) != 0) {
1581 return (status);
1584 status = hermon_flash_reset(state);
1585 break;
1587 case HERMON_FLASH_INTEL_CMDSET:
1588 case HERMON_FLASH_AMD_CMDSET:
1589 /* Write the sector, one byte at a time */
1590 for (i = 0; addr < end_addr; i++, addr++) {
1591 status = hermon_flash_write_byte(state, addr,
1592 sector[i]);
1593 if (status != 0) {
1594 break;
1597 status = hermon_flash_reset(state);
1598 break;
1600 case HERMON_FLASH_UNKNOWN_CMDSET:
1601 default:
1602 status = EINVAL;
1603 break;
1606 return (status);
1610 * hermon_flash_spi_write_dword()
1612 * NOTE: This function assumes that "data" is in network byte order.
1615 static int
1616 hermon_flash_spi_write_dword(hermon_state_t *state, uint32_t addr,
1617 uint32_t data)
1619 int status;
1620 ddi_acc_handle_t hdl;
1622 /* initialize the FMA retry loop */
1623 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1625 hdl = hermon_get_pcihdl(state);
1627 /* the FMA retry loop starts. */
1628 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1629 fm_test);
1631 /* Issue Write Enable */
1632 hermon_flash_spi_write_enable(state);
1634 /* Set the Address */
1635 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1636 addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1638 /* Set the Data */
1639 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_DATA, data);
1641 /* Set the Page Program and execute */
1642 hermon_flash_spi_exec_command(state, hdl,
1643 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1644 HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1645 HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
1646 HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
1647 (HERMON_HW_FLASH_SPI_PAGE_PROGRAM <<
1648 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1650 /* Wait for write to complete */
1651 if ((status = hermon_flash_spi_wait_wip(state)) != 0) {
1652 return (status);
1655 /* the FMA retry loop ends. */
1656 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
1657 return (0);
1659 pio_error:
1660 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1661 return (EIO);
1665 * hermon_flash_write_byte()
1667 static int
1668 hermon_flash_write_byte(hermon_state_t *state, uint32_t addr, uchar_t data)
1670 uint32_t stat;
1671 int status = 0;
1672 int dword_addr;
1673 int byte_offset;
1674 int i;
1675 union {
1676 uint8_t bytes[4];
1677 uint32_t dword;
1678 } dword;
1680 switch (state->hs_fw_cmdset) {
1681 case HERMON_FLASH_AMD_CMDSET:
1682 /* Issue Flash Byte program command */
1683 hermon_flash_write(state, addr, 0xAA, &status);
1684 if (status != 0) {
1685 return (status);
1688 hermon_flash_write(state, addr, 0x55, &status);
1689 if (status != 0) {
1690 return (status);
1693 hermon_flash_write(state, addr, 0xA0, &status);
1694 if (status != 0) {
1695 return (status);
1698 hermon_flash_write(state, addr, data, &status);
1699 if (status != 0) {
1700 return (status);
1703 /* Wait for Write Byte to Complete */
1704 i = 0;
1705 do {
1706 drv_usecwait(1);
1707 stat = hermon_flash_read(state, addr & ~3, &status);
1708 if (status != 0) {
1709 return (status);
1712 if (i == hermon_hw_flash_timeout_write) {
1713 cmn_err(CE_WARN,
1714 "hermon_flash_write_byte: ACS write "
1715 "timeout: addr: 0x%x, data: 0x%x\n",
1716 addr, data);
1717 hermon_fm_ereport(state, HCA_SYS_ERR,
1718 HCA_ERR_IOCTL);
1719 return (EIO);
1721 i++;
1722 } while (data != ((stat >> ((3 - (addr & 3)) << 3)) & 0xFF));
1724 break;
1726 case HERMON_FLASH_INTEL_CMDSET:
1727 /* Issue Flash Byte program command */
1728 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_WRITE,
1729 &status);
1730 if (status != 0) {
1731 return (status);
1733 hermon_flash_write(state, addr, data, &status);
1734 if (status != 0) {
1735 return (status);
1738 /* Wait for Write Byte to Complete */
1739 i = 0;
1740 do {
1741 drv_usecwait(1);
1742 stat = hermon_flash_read(state, addr & ~3, &status);
1743 if (status != 0) {
1744 return (status);
1747 if (i == hermon_hw_flash_timeout_write) {
1748 cmn_err(CE_WARN,
1749 "hermon_flash_write_byte: ICS write "
1750 "timeout: addr: %x, data: %x\n",
1751 addr, data);
1752 hermon_fm_ereport(state, HCA_SYS_ERR,
1753 HCA_ERR_IOCTL);
1754 return (EIO);
1756 i++;
1757 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1759 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1760 cmn_err(CE_WARN,
1761 "hermon_flash_write_byte: ICS write cmd error: "
1762 "addr: %x, data: %x\n",
1763 addr, data);
1764 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1765 return (EIO);
1767 break;
1769 case HERMON_FLASH_SPI_CMDSET:
1771 * Our lowest write granularity on SPI is a dword.
1772 * To support this ioctl option, we can read in the
1773 * dword that contains this byte, modify this byte,
1774 * and write the dword back out.
1777 /* Determine dword offset and byte offset within the dword */
1778 byte_offset = addr & 3;
1779 dword_addr = addr - byte_offset;
1780 #ifdef _LITTLE_ENDIAN
1781 byte_offset = 3 - byte_offset;
1782 #endif
1784 /* Read in dword */
1785 if ((status = hermon_flash_read_quadlet(state, &dword.dword,
1786 dword_addr)) != 0)
1787 break;
1789 /* Set "data" to the appopriate byte */
1790 dword.bytes[byte_offset] = data;
1792 /* Write modified dword back out */
1793 status = hermon_flash_spi_write_dword(state, dword_addr,
1794 dword.dword);
1796 break;
1798 case HERMON_FLASH_UNKNOWN_CMDSET:
1799 default:
1800 cmn_err(CE_WARN,
1801 "hermon_flash_write_byte: unknown cmd set: 0x%x\n",
1802 state->hs_fw_cmdset);
1803 status = EINVAL;
1804 break;
1807 return (status);
1811 * hermon_flash_erase_sector()
1813 static int
1814 hermon_flash_erase_sector(hermon_state_t *state, uint32_t sector_num)
1816 ddi_acc_handle_t hdl;
1817 uint32_t addr;
1818 uint32_t stat;
1819 int status = 0;
1820 int i;
1822 /* initialize the FMA retry loop */
1823 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1825 /* Get address from sector num */
1826 addr = sector_num << state->hs_fw_log_sector_sz;
1828 switch (state->hs_fw_cmdset) {
1829 case HERMON_FLASH_AMD_CMDSET:
1830 /* Issue Flash Sector Erase Command */
1831 hermon_flash_write(state, addr, 0xAA, &status);
1832 if (status != 0) {
1833 return (status);
1836 hermon_flash_write(state, addr, 0x55, &status);
1837 if (status != 0) {
1838 return (status);
1841 hermon_flash_write(state, addr, 0x80, &status);
1842 if (status != 0) {
1843 return (status);
1846 hermon_flash_write(state, addr, 0xAA, &status);
1847 if (status != 0) {
1848 return (status);
1851 hermon_flash_write(state, addr, 0x55, &status);
1852 if (status != 0) {
1853 return (status);
1856 hermon_flash_write(state, addr, 0x30, &status);
1857 if (status != 0) {
1858 return (status);
1861 /* Wait for Sector Erase to complete */
1862 i = 0;
1863 do {
1864 drv_usecwait(1);
1865 stat = hermon_flash_read(state, addr, &status);
1866 if (status != 0) {
1867 return (status);
1870 if (i == hermon_hw_flash_timeout_erase) {
1871 cmn_err(CE_WARN,
1872 "hermon_flash_erase_sector: "
1873 "ACS erase timeout\n");
1874 hermon_fm_ereport(state, HCA_SYS_ERR,
1875 HCA_ERR_IOCTL);
1876 return (EIO);
1878 i++;
1879 } while (stat != 0xFFFFFFFF);
1880 break;
1882 case HERMON_FLASH_INTEL_CMDSET:
1883 /* Issue Flash Sector Erase Command */
1884 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_ERASE,
1885 &status);
1886 if (status != 0) {
1887 return (status);
1890 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_CONFIRM,
1891 &status);
1892 if (status != 0) {
1893 return (status);
1896 /* Wait for Sector Erase to complete */
1897 i = 0;
1898 do {
1899 drv_usecwait(1);
1900 stat = hermon_flash_read(state, addr & ~3, &status);
1901 if (status != 0) {
1902 return (status);
1905 if (i == hermon_hw_flash_timeout_erase) {
1906 cmn_err(CE_WARN,
1907 "hermon_flash_erase_sector: "
1908 "ICS erase timeout\n");
1909 hermon_fm_ereport(state, HCA_SYS_ERR,
1910 HCA_ERR_IOCTL);
1911 return (EIO);
1913 i++;
1914 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1916 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1917 cmn_err(CE_WARN,
1918 "hermon_flash_erase_sector: "
1919 "ICS erase cmd error\n");
1920 hermon_fm_ereport(state, HCA_SYS_ERR,
1921 HCA_ERR_IOCTL);
1922 return (EIO);
1924 break;
1926 case HERMON_FLASH_SPI_CMDSET:
1927 hdl = hermon_get_pcihdl(state);
1929 /* the FMA retry loop starts. */
1930 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1931 fm_test);
1933 /* Issue Write Enable */
1934 hermon_flash_spi_write_enable(state);
1936 /* Set the Address */
1937 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1938 addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1940 /* Issue Flash Sector Erase */
1941 hermon_flash_spi_exec_command(state, hdl,
1942 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1943 HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1944 ((uint32_t)(HERMON_HW_FLASH_SPI_SECTOR_ERASE) <<
1945 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1947 /* the FMA retry loop ends. */
1948 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status,
1949 fm_test);
1951 /* Wait for Sector Erase to complete */
1952 status = hermon_flash_spi_wait_wip(state);
1953 break;
1955 case HERMON_FLASH_UNKNOWN_CMDSET:
1956 default:
1957 cmn_err(CE_WARN,
1958 "hermon_flash_erase_sector: unknown cmd set: 0x%x\n",
1959 state->hs_fw_cmdset);
1960 status = EINVAL;
1961 break;
1964 /* Reset the flash device */
1965 if (status == 0) {
1966 status = hermon_flash_reset(state);
1968 return (status);
1970 pio_error:
1971 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1972 return (EIO);
1976 * hermon_flash_erase_chip()
1978 static int
1979 hermon_flash_erase_chip(hermon_state_t *state)
1981 uint32_t stat;
1982 uint_t size;
1983 int status = 0;
1984 int i;
1985 int num_sect;
1987 switch (state->hs_fw_cmdset) {
1988 case HERMON_FLASH_AMD_CMDSET:
1989 /* Issue Flash Chip Erase Command */
1990 hermon_flash_write(state, 0, 0xAA, &status);
1991 if (status != 0) {
1992 return (status);
1995 hermon_flash_write(state, 0, 0x55, &status);
1996 if (status != 0) {
1997 return (status);
2000 hermon_flash_write(state, 0, 0x80, &status);
2001 if (status != 0) {
2002 return (status);
2005 hermon_flash_write(state, 0, 0xAA, &status);
2006 if (status != 0) {
2007 return (status);
2010 hermon_flash_write(state, 0, 0x55, &status);
2011 if (status != 0) {
2012 return (status);
2015 hermon_flash_write(state, 0, 0x10, &status);
2016 if (status != 0) {
2017 return (status);
2020 /* Wait for Chip Erase to Complete */
2021 i = 0;
2022 do {
2023 drv_usecwait(1);
2024 stat = hermon_flash_read(state, 0, &status);
2025 if (status != 0) {
2026 return (status);
2029 if (i == hermon_hw_flash_timeout_erase) {
2030 cmn_err(CE_WARN,
2031 "hermon_flash_erase_chip: erase timeout\n");
2032 hermon_fm_ereport(state, HCA_SYS_ERR,
2033 HCA_ERR_IOCTL);
2034 return (EIO);
2036 i++;
2037 } while (stat != 0xFFFFFFFF);
2038 break;
2040 case HERMON_FLASH_INTEL_CMDSET:
2041 case HERMON_FLASH_SPI_CMDSET:
2043 * These chips don't have a chip erase command, so erase
2044 * all blocks one at a time.
2046 size = (0x1 << state->hs_fw_log_sector_sz);
2047 num_sect = state->hs_fw_device_sz / size;
2049 for (i = 0; i < num_sect; i++) {
2050 status = hermon_flash_erase_sector(state, i);
2051 if (status != 0) {
2052 cmn_err(CE_WARN,
2053 "hermon_flash_erase_chip: "
2054 "sector %d erase error\n", i);
2055 return (status);
2058 break;
2060 case HERMON_FLASH_UNKNOWN_CMDSET:
2061 default:
2062 cmn_err(CE_WARN, "hermon_flash_erase_chip: "
2063 "unknown cmd set: 0x%x\n", state->hs_fw_cmdset);
2064 status = EINVAL;
2065 break;
2068 return (status);
2072 * hermon_flash_spi_write_enable()
2074 static void
2075 hermon_flash_spi_write_enable(hermon_state_t *state)
2077 ddi_acc_handle_t hdl;
2079 hdl = hermon_get_pcihdl(state);
2081 hermon_flash_spi_exec_command(state, hdl,
2082 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2083 (HERMON_HW_FLASH_SPI_WRITE_ENABLE <<
2084 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2088 * hermon_flash_spi_wait_wip()
2090 static int
2091 hermon_flash_spi_wait_wip(hermon_state_t *state)
2093 ddi_acc_handle_t hdl;
2094 uint32_t status;
2096 /* initialize the FMA retry loop */
2097 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2099 hdl = hermon_get_pcihdl(state);
2101 /* the FMA retry loop starts. */
2102 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2103 fm_test);
2105 /* wait on the gateway to clear busy */
2106 do {
2107 status = hermon_flash_read_cfg(state, hdl,
2108 HERMON_HW_FLASH_SPI_GW);
2109 } while (status & HERMON_HW_FLASH_SPI_BUSY);
2111 /* now, get the status and check for WIP to clear */
2112 do {
2113 hermon_flash_spi_exec_command(state, hdl,
2114 HERMON_HW_FLASH_SPI_READ_OP |
2115 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2116 HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2117 HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2118 (HERMON_HW_FLASH_SPI_READ_STATUS_REG <<
2119 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2121 status = hermon_flash_read_cfg(state, hdl,
2122 HERMON_HW_FLASH_SPI_DATA);
2123 } while (status & HERMON_HW_FLASH_SPI_WIP);
2125 /* the FMA retry loop ends. */
2126 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2127 return (0);
2129 pio_error:
2130 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2131 return (EIO);
2135 * hermon_flash_bank()
2137 static int
2138 hermon_flash_bank(hermon_state_t *state, uint32_t addr)
2140 ddi_acc_handle_t hdl;
2141 uint32_t bank;
2143 /* initialize the FMA retry loop */
2144 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2146 /* Set handle */
2147 hdl = hermon_get_pcihdl(state);
2149 /* Determine the bank setting from the address */
2150 bank = addr & HERMON_HW_FLASH_BANK_MASK;
2152 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(state->hs_fw_flashbank))
2155 * If the bank is different from the currently set bank, we need to
2156 * change it. Also, if an 'addr' of 0 is given, this allows the
2157 * capability to force the flash bank to 0. This is useful at init
2158 * time to initially set the bank value
2160 if (state->hs_fw_flashbank != bank || addr == 0) {
2161 switch (state->hs_fw_cmdset) {
2162 case HERMON_FLASH_SPI_CMDSET:
2163 /* CMJ: not needed for hermon */
2164 break;
2166 case HERMON_FLASH_INTEL_CMDSET:
2167 case HERMON_FLASH_AMD_CMDSET:
2168 /* the FMA retry loop starts. */
2169 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt,
2170 fm_status, fm_test);
2172 hermon_flash_write_cfg(state, hdl,
2173 HERMON_HW_FLASH_GPIO_DATACLEAR, 0x70);
2174 hermon_flash_write_cfg(state, hdl,
2175 HERMON_HW_FLASH_GPIO_DATASET, (bank >> 15) & 0x70);
2177 /* the FMA retry loop ends. */
2178 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt,
2179 fm_status, fm_test);
2180 break;
2182 case HERMON_FLASH_UNKNOWN_CMDSET:
2183 default:
2184 return (EINVAL);
2187 state->hs_fw_flashbank = bank;
2189 return (0);
2191 pio_error:
2192 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2193 return (EIO);
2197 * hermon_flash_spi_exec_command()
2199 static void
2200 hermon_flash_spi_exec_command(hermon_state_t *state, ddi_acc_handle_t hdl,
2201 uint32_t cmd)
2203 uint32_t data;
2204 int timeout = 0;
2206 cmd |= HERMON_HW_FLASH_SPI_BUSY | HERMON_HW_FLASH_SPI_ENABLE_OFF;
2208 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_GW, cmd);
2210 do {
2211 data = hermon_flash_read_cfg(state, hdl,
2212 HERMON_HW_FLASH_SPI_GW);
2213 timeout++;
2214 } while ((data & HERMON_HW_FLASH_SPI_BUSY) &&
2215 (timeout < hermon_hw_flash_timeout_config));
2219 * hermon_flash_read()
2221 static uint32_t
2222 hermon_flash_read(hermon_state_t *state, uint32_t addr, int *err)
2224 ddi_acc_handle_t hdl;
2225 uint32_t data = 0;
2226 int timeout, status = 0;
2228 /* initialize the FMA retry loop */
2229 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2231 hdl = hermon_get_pcihdl(state);
2233 /* the FMA retry loop starts. */
2234 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2235 fm_test);
2237 switch (state->hs_fw_cmdset) {
2238 case HERMON_FLASH_SPI_CMDSET:
2239 /* Set the transaction address */
2240 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
2241 (addr & HERMON_HW_FLASH_SPI_ADDR_MASK));
2243 hermon_flash_spi_exec_command(state, hdl,
2244 HERMON_HW_FLASH_SPI_READ_OP |
2245 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2246 HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
2247 HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2248 HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2249 (HERMON_HW_FLASH_SPI_READ <<
2250 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2252 data = hermon_flash_read_cfg(state, hdl,
2253 HERMON_HW_FLASH_SPI_DATA);
2254 break;
2256 case HERMON_FLASH_INTEL_CMDSET:
2257 case HERMON_FLASH_AMD_CMDSET:
2259 * The Read operation does the following:
2260 * 1) Write the masked address to the HERMON_FLASH_ADDR
2261 * register. Only the least significant 19 bits are valid.
2262 * 2) Read back the register until the command has completed.
2263 * 3) Read the data retrieved from the address at the
2264 * HERMON_FLASH_DATA register.
2266 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2267 (addr & HERMON_HW_FLASH_ADDR_MASK) | (1 << 29));
2269 timeout = 0;
2270 do {
2271 data = hermon_flash_read_cfg(state, hdl,
2272 HERMON_HW_FLASH_ADDR);
2273 timeout++;
2274 } while ((data & HERMON_HW_FLASH_CMD_MASK) &&
2275 (timeout < hermon_hw_flash_timeout_config));
2277 if (timeout == hermon_hw_flash_timeout_config) {
2278 cmn_err(CE_WARN, "hermon_flash_read: command timed "
2279 "out.\n");
2280 *err = EIO;
2281 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2282 return (data);
2285 data = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_DATA);
2286 break;
2288 case HERMON_FLASH_UNKNOWN_CMDSET:
2289 default:
2290 cmn_err(CE_CONT, "hermon_flash_read: unknown cmdset: 0x%x\n",
2291 state->hs_fw_cmdset);
2292 status = EINVAL;
2293 break;
2297 /* the FMA retry loop ends. */
2298 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2299 *err = status;
2300 return (data);
2302 pio_error:
2303 *err = EIO;
2304 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2305 return (data);
2309 * hermon_flash_write()
2311 static void
2312 hermon_flash_write(hermon_state_t *state, uint32_t addr, uchar_t data, int *err)
2314 ddi_acc_handle_t hdl;
2315 int cmd;
2316 int timeout;
2318 /* initialize the FMA retry loop */
2319 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2321 hdl = hermon_get_pcihdl(state);
2323 /* the FMA retry loop starts. */
2324 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2325 fm_test);
2328 * The Write operation does the following:
2329 * 1) Write the data to be written to the HERMON_FLASH_DATA offset.
2330 * 2) Write the address to write the data to to the HERMON_FLASH_ADDR
2331 * offset.
2332 * 3) Wait until the write completes.
2335 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_DATA, data << 24);
2336 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2337 (addr & 0x7FFFF) | (2 << 29));
2339 timeout = 0;
2340 do {
2341 cmd = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_ADDR);
2342 timeout++;
2343 } while ((cmd & HERMON_HW_FLASH_CMD_MASK) &&
2344 (timeout < hermon_hw_flash_timeout_config));
2346 if (timeout == hermon_hw_flash_timeout_config) {
2347 cmn_err(CE_WARN, "hermon_flash_write: config cmd timeout.\n");
2348 *err = EIO;
2349 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2350 return;
2353 /* the FMA retry loop ends. */
2354 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2355 *err = 0;
2356 return;
2358 pio_error:
2359 *err = EIO;
2360 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2364 * hermon_flash_init()
2366 static int
2367 hermon_flash_init(hermon_state_t *state)
2369 uint32_t word;
2370 ddi_acc_handle_t hdl;
2371 int sema_cnt;
2372 int gpio;
2374 /* initialize the FMA retry loop */
2375 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2377 /* Set handle */
2378 hdl = hermon_get_pcihdl(state);
2380 /* the FMA retry loop starts. */
2381 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2382 fm_test);
2384 /* Init the flash */
2386 #ifdef DO_WRCONF
2388 * Grab the WRCONF semaphore.
2390 word = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_WRCONF_SEMA);
2391 #endif
2394 * Grab the GPIO semaphore. This allows us exclusive access to the
2395 * GPIO settings on the Hermon for the duration of the flash burning
2396 * procedure.
2398 sema_cnt = 0;
2399 do {
2400 word = hermon_flash_read_cfg(state, hdl,
2401 HERMON_HW_FLASH_GPIO_SEMA);
2402 if (word == 0) {
2403 break;
2406 sema_cnt++;
2407 drv_usecwait(1);
2409 } while (sema_cnt < hermon_hw_flash_timeout_gpio_sema);
2412 * Determine if we timed out trying to grab the GPIO semaphore
2414 if (sema_cnt == hermon_hw_flash_timeout_gpio_sema) {
2415 cmn_err(CE_WARN, "hermon_flash_init: GPIO SEMA timeout\n");
2416 cmn_err(CE_WARN, "GPIO_SEMA value: 0x%x\n", word);
2417 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2418 return (EIO);
2421 /* Save away original GPIO Values */
2422 state->hs_fw_gpio[0] = hermon_flash_read_cfg(state, hdl,
2423 HERMON_HW_FLASH_GPIO_DATA);
2425 /* Set new GPIO value */
2426 gpio = state->hs_fw_gpio[0] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2427 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA, gpio);
2429 /* Save away original GPIO Values */
2430 state->hs_fw_gpio[1] = hermon_flash_read_cfg(state, hdl,
2431 HERMON_HW_FLASH_GPIO_MOD0);
2432 state->hs_fw_gpio[2] = hermon_flash_read_cfg(state, hdl,
2433 HERMON_HW_FLASH_GPIO_MOD1);
2435 /* unlock GPIO */
2436 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2437 HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2440 * Set new GPIO values
2442 gpio = state->hs_fw_gpio[1] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2443 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0, gpio);
2445 gpio = state->hs_fw_gpio[2] & ~HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2446 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1, gpio);
2448 /* re-lock GPIO */
2449 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2451 /* Set CPUMODE to enable hermon to access the flash device */
2452 /* CMJ This code came from arbel. Hermon doesn't seem to need it. */
2454 * hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_CPUMODE,
2455 * 1 << HERMON_HW_FLASH_CPU_SHIFT);
2458 /* the FMA retry loop ends. */
2459 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2460 return (0);
2462 pio_error:
2463 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2464 return (EIO);
2468 * hermon_flash_cfi_init
2469 * Implements access to the CFI (Common Flash Interface) data
2471 static int
2472 hermon_flash_cfi_init(hermon_state_t *state, uint32_t *cfi_info,
2473 int *intel_xcmd)
2475 uint32_t data;
2476 uint32_t sector_sz_bytes;
2477 uint32_t bit_count;
2478 uint8_t cfi_ch_info[HERMON_CFI_INFO_SIZE];
2479 int i;
2480 int status;
2482 /* Right now, all hermon cards use SPI. */
2483 if (hermon_device_mode(state)) {
2485 * Don't use CFI for SPI part. Just fill in what we need
2486 * and return.
2488 state->hs_fw_cmdset = HERMON_FLASH_SPI_CMDSET;
2489 state->hs_fw_log_sector_sz = HERMON_FLASH_SPI_LOG_SECTOR_SIZE;
2490 state->hs_fw_device_sz = HERMON_FLASH_SPI_DEVICE_SIZE;
2493 * set this to inform caller of cmdset type.
2495 cfi_ch_info[0x13] = HERMON_FLASH_SPI_CMDSET;
2496 hermon_flash_cfi_dword(&cfi_info[4], cfi_ch_info, 0x10);
2497 return (0);
2501 * Determine if the user command supports the Intel Extended
2502 * Command Set. The query string is contained in the fourth
2503 * quad word.
2505 hermon_flash_cfi_byte(cfi_ch_info, cfi_info[0x04], 0x10);
2506 if (cfi_ch_info[0x10] == 'M' &&
2507 cfi_ch_info[0x11] == 'X' &&
2508 cfi_ch_info[0x12] == '2') {
2509 *intel_xcmd = 1; /* support is there */
2510 if (hermon_verbose) {
2511 IBTF_DPRINTF_L2("hermon",
2512 "Support for Intel X is present\n");
2516 /* CFI QUERY */
2517 hermon_flash_write(state, 0x55, HERMON_FLASH_CFI_INIT, &status);
2518 if (status != 0) {
2519 return (status);
2522 /* temporarily set the cmdset in order to do the initial read */
2523 state->hs_fw_cmdset = HERMON_FLASH_INTEL_CMDSET;
2525 /* Read in CFI data */
2526 for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 4) {
2527 data = hermon_flash_read(state, i, &status);
2528 if (status != 0) {
2529 return (status);
2531 hermon_flash_cfi_byte(cfi_ch_info, data, i);
2534 /* Determine chip set */
2535 state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2536 if (cfi_ch_info[0x20] == 'Q' &&
2537 cfi_ch_info[0x22] == 'R' &&
2538 cfi_ch_info[0x24] == 'Y') {
2540 * Mode: x16 working in x8 mode (Intel).
2541 * Pack data - skip spacing bytes.
2543 if (hermon_verbose) {
2544 IBTF_DPRINTF_L2("hermon",
2545 "x16 working in x8 mode (Intel)\n");
2547 for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 2) {
2548 cfi_ch_info[i/2] = cfi_ch_info[i];
2551 state->hs_fw_cmdset = cfi_ch_info[0x13];
2553 if (state->hs_fw_cmdset != HERMON_FLASH_INTEL_CMDSET &&
2554 state->hs_fw_cmdset != HERMON_FLASH_AMD_CMDSET) {
2555 cmn_err(CE_WARN,
2556 "hermon_flash_cfi_init: UNKNOWN chip cmd set 0x%04x\n",
2557 state->hs_fw_cmdset);
2558 state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2559 return (0);
2562 /* Determine total bytes in one sector size */
2563 sector_sz_bytes = ((cfi_ch_info[0x30] << 8) | cfi_ch_info[0x2F]) << 8;
2565 /* Calculate equivalent of log2 (n) */
2566 for (bit_count = 0; sector_sz_bytes > 1; bit_count++) {
2567 sector_sz_bytes >>= 1;
2570 /* Set sector size */
2571 state->hs_fw_log_sector_sz = bit_count;
2573 /* Set flash size */
2574 state->hs_fw_device_sz = 0x1 << cfi_ch_info[0x27];
2576 /* Reset to turn off CFI mode */
2577 if ((status = hermon_flash_reset(state)) != 0)
2578 goto out;
2580 /* Pass CFI data back to user command. */
2581 for (i = 0; i < HERMON_FLASH_CFI_SIZE_QUADLET; i++) {
2582 hermon_flash_cfi_dword(&cfi_info[i], cfi_ch_info, i << 2);
2585 if (*intel_xcmd == 1) {
2587 * Inform the user cmd that this driver does support the
2588 * Intel Extended Command Set.
2590 cfi_ch_info[0x10] = 'M';
2591 cfi_ch_info[0x11] = 'X';
2592 cfi_ch_info[0x12] = '2';
2593 } else {
2594 cfi_ch_info[0x10] = 'Q';
2595 cfi_ch_info[0x11] = 'R';
2596 cfi_ch_info[0x12] = 'Y';
2598 cfi_ch_info[0x13] = state->hs_fw_cmdset;
2599 hermon_flash_cfi_dword(&cfi_info[0x4], cfi_ch_info, 0x10);
2600 out:
2601 return (status);
2605 * hermon_flash_fini()
2607 static int
2608 hermon_flash_fini(hermon_state_t *state)
2610 int status;
2611 ddi_acc_handle_t hdl;
2613 /* initialize the FMA retry loop */
2614 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2616 /* Set handle */
2617 hdl = hermon_get_pcihdl(state);
2619 if ((status = hermon_flash_bank(state, 0)) != 0)
2620 return (status);
2622 /* the FMA retry loop starts. */
2623 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2624 fm_test);
2627 * Restore original GPIO Values
2629 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA,
2630 state->hs_fw_gpio[0]);
2632 /* unlock GPIOs */
2633 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2634 HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2636 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0,
2637 state->hs_fw_gpio[1]);
2638 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1,
2639 state->hs_fw_gpio[2]);
2641 /* re-lock GPIOs */
2642 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2644 /* Give up gpio semaphore */
2645 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_SEMA, 0);
2647 /* the FMA retry loop ends. */
2648 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2649 return (0);
2651 pio_error:
2652 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2653 return (EIO);
2657 * hermon_flash_read_cfg
2659 static uint32_t
2660 hermon_flash_read_cfg(hermon_state_t *state, ddi_acc_handle_t pci_config_hdl,
2661 uint32_t addr)
2663 uint32_t read;
2665 if (do_bar0) {
2666 read = ddi_get32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2667 (state->hs_reg_cmd_baseaddr + addr));
2668 } else {
2670 * Perform flash read operation:
2671 * 1) Place addr to read from on the HERMON_HW_FLASH_CFG_ADDR
2672 * register
2673 * 2) Read data at that addr from the HERMON_HW_FLASH_CFG_DATA
2674 * register
2676 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2677 addr);
2678 read = pci_config_get32(pci_config_hdl,
2679 HERMON_HW_FLASH_CFG_DATA);
2682 return (read);
2685 #ifdef DO_WRCONF
2686 static void
2687 hermon_flash_write_cfg(hermon_state_t *state,
2688 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2690 hermon_flash_write_cfg_helper(state, pci_config_hdl, addr, data);
2691 hermon_flash_write_confirm(state, pci_config_hdl);
2694 static void
2695 hermon_flash_write_confirm(hermon_state_t *state,
2696 ddi_acc_handle_t pci_config_hdl)
2698 uint32_t sem_value = 1;
2700 hermon_flash_write_cfg_helper(state, pci_config_hdl,
2701 HERMON_HW_FLASH_WRCONF_SEMA, 0);
2702 while (sem_value) {
2703 sem_value = hermon_flash_read_cfg(state, pci_config_hdl,
2704 HERMON_HW_FLASH_WRCONF_SEMA);
2707 #endif
2710 * hermon_flash_write_cfg
2712 static void
2713 #ifdef DO_WRCONF
2714 hermon_flash_write_cfg_helper(hermon_state_t *state,
2715 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2716 #else
2717 hermon_flash_write_cfg(hermon_state_t *state,
2718 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2719 #endif
2721 if (do_bar0) {
2722 ddi_put32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2723 (state->hs_reg_cmd_baseaddr + addr), data);
2725 } else {
2728 * Perform flash write operation:
2729 * 1) Place addr to write to on the HERMON_HW_FLASH_CFG_ADDR
2730 * register
2731 * 2) Place data to write on to the HERMON_HW_FLASH_CFG_DATA
2732 * register
2734 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2735 addr);
2736 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_DATA,
2737 data);
2742 * Support routines to convert Common Flash Interface (CFI) data
2743 * from a 32 bit word to a char array, and from a char array to
2744 * a 32 bit word.
2746 static void
2747 hermon_flash_cfi_byte(uint8_t *ch, uint32_t dword, int i)
2749 ch[i] = (uint8_t)((dword & 0xFF000000) >> 24);
2750 ch[i+1] = (uint8_t)((dword & 0x00FF0000) >> 16);
2751 ch[i+2] = (uint8_t)((dword & 0x0000FF00) >> 8);
2752 ch[i+3] = (uint8_t)((dword & 0x000000FF));
2755 static void
2756 hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i)
2758 *dword = (uint32_t)
2759 ((uint32_t)ch[i] << 24 |
2760 (uint32_t)ch[i+1] << 16 |
2761 (uint32_t)ch[i+2] << 8 |
2762 (uint32_t)ch[i+3]);
2766 * hermon_loopback_free_qps
2768 static void
2769 hermon_loopback_free_qps(hermon_loopback_state_t *lstate)
2771 int i;
2773 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2775 if (lstate->hls_tx.hlc_qp_hdl != NULL) {
2776 (void) hermon_qp_free(lstate->hls_state,
2777 &lstate->hls_tx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2778 HERMON_NOSLEEP);
2780 if (lstate->hls_rx.hlc_qp_hdl != NULL) {
2781 (void) hermon_qp_free(lstate->hls_state,
2782 &lstate->hls_rx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2783 HERMON_NOSLEEP);
2785 lstate->hls_tx.hlc_qp_hdl = NULL;
2786 lstate->hls_rx.hlc_qp_hdl = NULL;
2787 for (i = 0; i < 2; i++) {
2788 if (lstate->hls_tx.hlc_cqhdl[i] != NULL) {
2789 (void) hermon_cq_free(lstate->hls_state,
2790 &lstate->hls_tx.hlc_cqhdl[i], HERMON_NOSLEEP);
2792 if (lstate->hls_rx.hlc_cqhdl[i] != NULL) {
2793 (void) hermon_cq_free(lstate->hls_state,
2794 &lstate->hls_rx.hlc_cqhdl[i], HERMON_NOSLEEP);
2796 lstate->hls_tx.hlc_cqhdl[i] = NULL;
2797 lstate->hls_rx.hlc_cqhdl[i] = NULL;
2802 * hermon_loopback_free_state
2804 static void
2805 hermon_loopback_free_state(hermon_loopback_state_t *lstate)
2807 hermon_loopback_free_qps(lstate);
2808 if (lstate->hls_tx.hlc_mrhdl != NULL) {
2809 (void) hermon_mr_deregister(lstate->hls_state,
2810 &lstate->hls_tx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2811 HERMON_NOSLEEP);
2813 if (lstate->hls_rx.hlc_mrhdl != NULL) {
2814 (void) hermon_mr_deregister(lstate->hls_state,
2815 &lstate->hls_rx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2816 HERMON_NOSLEEP);
2818 if (lstate->hls_pd_hdl != NULL) {
2819 (void) hermon_pd_free(lstate->hls_state, &lstate->hls_pd_hdl);
2821 if (lstate->hls_tx.hlc_buf != NULL) {
2822 kmem_free(lstate->hls_tx.hlc_buf, lstate->hls_tx.hlc_buf_sz);
2824 if (lstate->hls_rx.hlc_buf != NULL) {
2825 kmem_free(lstate->hls_rx.hlc_buf, lstate->hls_rx.hlc_buf_sz);
2827 bzero(lstate, sizeof (hermon_loopback_state_t));
2831 * hermon_loopback_init
2833 static int
2834 hermon_loopback_init(hermon_state_t *state, hermon_loopback_state_t *lstate)
2836 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2838 lstate->hls_hca_hdl = (ibc_hca_hdl_t)state;
2839 lstate->hls_status = hermon_pd_alloc(lstate->hls_state,
2840 &lstate->hls_pd_hdl, HERMON_NOSLEEP);
2841 if (lstate->hls_status != IBT_SUCCESS) {
2842 lstate->hls_err = HERMON_LOOPBACK_PROT_DOMAIN_ALLOC_FAIL;
2843 return (EFAULT);
2846 return (0);
2850 * hermon_loopback_init_qp_info
2852 static void
2853 hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
2854 hermon_loopback_comm_t *comm)
2856 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2857 bzero(&comm->hlc_qp_attr, sizeof (ibt_qp_alloc_attr_t));
2858 bzero(&comm->hlc_qp_info, sizeof (ibt_qp_info_t));
2860 comm->hlc_wrid = 1;
2861 comm->hlc_cq_attr.cq_size = 128;
2862 comm->hlc_qp_attr.qp_sizes.cs_sq_sgl = 3;
2863 comm->hlc_qp_attr.qp_sizes.cs_rq_sgl = 3;
2864 comm->hlc_qp_attr.qp_sizes.cs_sq = 16;
2865 comm->hlc_qp_attr.qp_sizes.cs_rq = 16;
2866 comm->hlc_qp_attr.qp_flags = IBT_WR_SIGNALED;
2868 comm->hlc_qp_info.qp_state = IBT_STATE_RESET;
2869 comm->hlc_qp_info.qp_trans = IBT_RC_SRV;
2870 comm->hlc_qp_info.qp_flags = IBT_CEP_RDMA_RD | IBT_CEP_RDMA_WR;
2871 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
2872 lstate->hls_port;
2873 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_pkey_ix =
2874 lstate->hls_pkey_ix;
2875 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_timeout =
2876 lstate->hls_timeout;
2877 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srvl = 0;
2878 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srate =
2879 IBT_SRATE_4X;
2880 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_send_grh = 0;
2881 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid =
2882 lstate->hls_lid;
2883 comm->hlc_qp_info.qp_transport.rc.rc_retry_cnt = lstate->hls_retry;
2884 comm->hlc_qp_info.qp_transport.rc.rc_sq_psn = 0;
2885 comm->hlc_qp_info.qp_transport.rc.rc_rq_psn = 0;
2886 comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_in = 4;
2887 comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_out = 4;
2888 comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = 0;
2889 comm->hlc_qp_info.qp_transport.rc.rc_min_rnr_nak = IBT_RNR_NAK_655ms;
2890 comm->hlc_qp_info.qp_transport.rc.rc_path_mtu = IB_MTU_1K;
2894 * hermon_loopback_alloc_mem
2896 static int
2897 hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
2898 hermon_loopback_comm_t *comm, int sz)
2900 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2902 /* Allocate buffer of specified size */
2903 comm->hlc_buf_sz = sz;
2904 comm->hlc_buf = kmem_zalloc(sz, KM_NOSLEEP);
2905 if (comm->hlc_buf == NULL) {
2906 return (EFAULT);
2909 /* Register the buffer as a memory region */
2910 comm->hlc_memattr.mr_vaddr = (uint64_t)(uintptr_t)comm->hlc_buf;
2911 comm->hlc_memattr.mr_len = (ib_msglen_t)sz;
2912 comm->hlc_memattr.mr_as = NULL;
2913 comm->hlc_memattr.mr_flags = IBT_MR_NOSLEEP |
2914 IBT_MR_ENABLE_REMOTE_WRITE | IBT_MR_ENABLE_LOCAL_WRITE;
2916 comm->hlc_status = hermon_mr_register(lstate->hls_state,
2917 lstate->hls_pd_hdl, &comm->hlc_memattr, &comm->hlc_mrhdl,
2918 NULL, HERMON_MPT_DMPT);
2920 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm->hlc_mrhdl))
2922 comm->hlc_mrdesc.md_vaddr = comm->hlc_mrhdl->mr_bindinfo.bi_addr;
2923 comm->hlc_mrdesc.md_lkey = comm->hlc_mrhdl->mr_lkey;
2924 comm->hlc_mrdesc.md_rkey = comm->hlc_mrhdl->mr_rkey;
2925 if (comm->hlc_status != IBT_SUCCESS) {
2926 return (EFAULT);
2928 return (0);
2932 * hermon_loopback_alloc_qps
2934 static int
2935 hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
2936 hermon_loopback_comm_t *comm)
2938 uint32_t i, real_size;
2939 hermon_qp_info_t qpinfo;
2941 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2942 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2944 /* Allocate send and recv CQs */
2945 for (i = 0; i < 2; i++) {
2946 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2947 comm->hlc_cq_attr.cq_size = 128;
2948 comm->hlc_status = hermon_cq_alloc(lstate->hls_state,
2949 (ibt_cq_hdl_t)NULL, &comm->hlc_cq_attr, &real_size,
2950 &comm->hlc_cqhdl[i], HERMON_NOSLEEP);
2951 if (comm->hlc_status != IBT_SUCCESS) {
2952 lstate->hls_err += i;
2953 return (EFAULT);
2957 /* Allocate the QP */
2958 hermon_loopback_init_qp_info(lstate, comm);
2959 comm->hlc_qp_attr.qp_pd_hdl = (ibt_pd_hdl_t)lstate->hls_pd_hdl;
2960 comm->hlc_qp_attr.qp_scq_hdl = (ibt_cq_hdl_t)comm->hlc_cqhdl[0];
2961 comm->hlc_qp_attr.qp_rcq_hdl = (ibt_cq_hdl_t)comm->hlc_cqhdl[1];
2962 comm->hlc_qp_attr.qp_ibc_scq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[0];
2963 comm->hlc_qp_attr.qp_ibc_rcq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[1];
2964 qpinfo.qpi_attrp = &comm->hlc_qp_attr;
2965 qpinfo.qpi_type = IBT_RC_RQP;
2966 qpinfo.qpi_ibt_qphdl = NULL;
2967 qpinfo.qpi_queueszp = &comm->hlc_chan_sizes;
2968 qpinfo.qpi_qpn = &comm->hlc_qp_num;
2969 comm->hlc_status = hermon_qp_alloc(lstate->hls_state, &qpinfo,
2970 HERMON_NOSLEEP);
2971 if (comm->hlc_status == DDI_SUCCESS) {
2972 comm->hlc_qp_hdl = qpinfo.qpi_qphdl;
2975 if (comm->hlc_status != IBT_SUCCESS) {
2976 lstate->hls_err += 2;
2977 return (EFAULT);
2979 return (0);
2983 * hermon_loopback_modify_qp
2985 static int
2986 hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
2987 hermon_loopback_comm_t *comm, uint_t qp_num)
2989 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2990 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2992 /* Modify QP to INIT */
2993 hermon_loopback_init_qp_info(lstate, comm);
2994 comm->hlc_qp_info.qp_state = IBT_STATE_INIT;
2995 comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2996 IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2997 if (comm->hlc_status != IBT_SUCCESS) {
2998 return (EFAULT);
3002 * Modify QP to RTR (set destination LID and QP number to local
3003 * LID and QP number)
3005 comm->hlc_qp_info.qp_state = IBT_STATE_RTR;
3006 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid
3007 = lstate->hls_lid;
3008 comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = qp_num;
3009 comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3010 IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3011 if (comm->hlc_status != IBT_SUCCESS) {
3012 lstate->hls_err += 1;
3013 return (EFAULT);
3016 /* Modify QP to RTS */
3017 comm->hlc_qp_info.qp_current_state = IBT_STATE_RTR;
3018 comm->hlc_qp_info.qp_state = IBT_STATE_RTS;
3019 comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3020 IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3021 if (comm->hlc_status != IBT_SUCCESS) {
3022 lstate->hls_err += 2;
3023 return (EFAULT);
3025 return (0);
3029 * hermon_loopback_copyout
3031 static int
3032 hermon_loopback_copyout(hermon_loopback_ioctl_t *lb, intptr_t arg, int mode)
3034 #ifdef _MULTI_DATAMODEL
3035 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
3036 hermon_loopback_ioctl32_t lb32;
3038 lb32.alb_revision = lb->alb_revision;
3039 lb32.alb_send_buf =
3040 (caddr32_t)(uintptr_t)lb->alb_send_buf;
3041 lb32.alb_fail_buf =
3042 (caddr32_t)(uintptr_t)lb->alb_fail_buf;
3043 lb32.alb_buf_sz = lb->alb_buf_sz;
3044 lb32.alb_num_iter = lb->alb_num_iter;
3045 lb32.alb_pass_done = lb->alb_pass_done;
3046 lb32.alb_timeout = lb->alb_timeout;
3047 lb32.alb_error_type = lb->alb_error_type;
3048 lb32.alb_port_num = lb->alb_port_num;
3049 lb32.alb_num_retry = lb->alb_num_retry;
3051 if (ddi_copyout(&lb32, (void *)arg,
3052 sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
3053 return (EFAULT);
3055 } else
3056 #endif /* _MULTI_DATAMODEL */
3057 if (ddi_copyout(lb, (void *)arg, sizeof (hermon_loopback_ioctl_t),
3058 mode) != 0) {
3059 return (EFAULT);
3061 return (0);
3065 * hermon_loopback_post_send
3067 static int
3068 hermon_loopback_post_send(hermon_loopback_state_t *lstate,
3069 hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx)
3071 int ret;
3073 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tx))
3075 bzero(&tx->hlc_sgl, sizeof (ibt_wr_ds_t));
3076 bzero(&tx->hlc_wr, sizeof (ibt_send_wr_t));
3078 /* Initialize local address for TX buffer */
3079 tx->hlc_sgl.ds_va = tx->hlc_mrdesc.md_vaddr;
3080 tx->hlc_sgl.ds_key = tx->hlc_mrdesc.md_lkey;
3081 tx->hlc_sgl.ds_len = tx->hlc_buf_sz;
3083 /* Initialize the remaining details of the work request */
3084 tx->hlc_wr.wr_id = tx->hlc_wrid++;
3085 tx->hlc_wr.wr_flags = IBT_WR_SEND_SIGNAL;
3086 tx->hlc_wr.wr_nds = 1;
3087 tx->hlc_wr.wr_sgl = &tx->hlc_sgl;
3088 tx->hlc_wr.wr_opcode = IBT_WRC_RDMAW;
3089 tx->hlc_wr.wr_trans = IBT_RC_SRV;
3091 /* Initialize the remote address for RX buffer */
3092 tx->hlc_wr.wr.rc.rcwr.rdma.rdma_raddr = rx->hlc_mrdesc.md_vaddr;
3093 tx->hlc_wr.wr.rc.rcwr.rdma.rdma_rkey = rx->hlc_mrdesc.md_rkey;
3094 tx->hlc_complete = 0;
3095 ret = hermon_post_send(lstate->hls_state, tx->hlc_qp_hdl, &tx->hlc_wr,
3096 1, NULL);
3097 if (ret != IBT_SUCCESS) {
3098 return (EFAULT);
3100 return (0);
3104 * hermon_loopback_poll_cq
3106 static int
3107 hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
3108 hermon_loopback_comm_t *comm)
3110 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
3112 comm->hlc_wc.wc_status = 0;
3113 comm->hlc_num_polled = 0;
3114 comm->hlc_status = hermon_cq_poll(lstate->hls_state,
3115 comm->hlc_cqhdl[0], &comm->hlc_wc, 1, &comm->hlc_num_polled);
3116 if ((comm->hlc_status == IBT_SUCCESS) &&
3117 (comm->hlc_wc.wc_status != IBT_WC_SUCCESS)) {
3118 comm->hlc_status = ibc_get_ci_failure(0);
3120 return (comm->hlc_status);