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]
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
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>
38 #include <sys/sunddi.h>
39 #include <sys/modctl.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
;
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
);
67 static int hermon_ioctl_reg_write(hermon_state_t
*state
, intptr_t arg
,
69 static int hermon_ioctl_reg_read(hermon_state_t
*state
, intptr_t arg
,
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
,
78 static int hermon_ioctl_loopback(hermon_state_t
*state
, intptr_t arg
,
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
,
86 static int hermon_flash_read_quadlet(hermon_state_t
*state
, uint32_t *data
,
88 static int hermon_flash_write_sector(hermon_state_t
*state
,
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
,
94 static int hermon_flash_erase_sector(hermon_state_t
*state
,
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
,
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
,
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
);
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
);
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
;
153 hermon_ioctl(dev_t dev
, int cmd
, intptr_t arg
, int mode
, cred_t
*credp
,
156 hermon_state_t
*state
;
160 if (drv_priv(credp
) != 0) {
164 instance
= HERMON_DEV_INSTANCE(dev
);
165 if (instance
== (minor_t
)-1) {
169 state
= ddi_get_soft_state(hermon_statep
, instance
);
177 case HERMON_IOCTL_FLASH_READ
:
178 status
= hermon_ioctl_flash_read(state
, dev
, arg
, mode
);
181 case HERMON_IOCTL_FLASH_WRITE
:
182 status
= hermon_ioctl_flash_write(state
, dev
, arg
, mode
);
185 case HERMON_IOCTL_FLASH_ERASE
:
186 status
= hermon_ioctl_flash_erase(state
, dev
, arg
, mode
);
189 case HERMON_IOCTL_FLASH_INIT
:
190 status
= hermon_ioctl_flash_init(state
, dev
, arg
, mode
);
193 case HERMON_IOCTL_FLASH_FINI
:
194 status
= hermon_ioctl_flash_fini(state
, dev
);
197 case HERMON_IOCTL_INFO
:
198 status
= hermon_ioctl_info(state
, dev
, arg
, mode
);
201 case HERMON_IOCTL_PORTS
:
202 status
= hermon_ioctl_ports(state
, arg
, mode
);
205 case HERMON_IOCTL_LOOPBACK
:
206 status
= hermon_ioctl_loopback(state
, arg
, mode
);
210 case HERMON_IOCTL_REG_WRITE
:
211 status
= hermon_ioctl_reg_write(state
, arg
, mode
);
214 case HERMON_IOCTL_REG_READ
:
215 status
= hermon_ioctl_reg_read(state
, arg
, mode
);
219 case HERMON_IOCTL_DDR_READ
:
220 /* XXX guard until the ioctl header is cleaned up */
224 case HERMON_IOCTL_WRITE_BOOT_ADDR
:
225 status
= hermon_ioctl_write_boot_addr(state
, dev
, arg
, mode
);
238 * hermon_ioctl_flash_read()
241 hermon_ioctl_flash_read(hermon_state_t
*state
, dev_t dev
, intptr_t arg
,
244 hermon_flash_ioctl_t ioctl_info
;
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
);
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
);
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
;
273 #endif /* _MULTI_DATAMODEL */
274 if (ddi_copyin((void *)arg
, &ioctl_info
, sizeof (hermon_flash_ioctl_t
),
276 mutex_exit(&state
->hs_fw_flashlock
);
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
);
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
);
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
,
304 mutex_exit(&state
->hs_fw_flashlock
);
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
);
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
);
326 mutex_exit(&state
->hs_fw_flashlock
);
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
);
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
);
354 mutex_exit(&state
->hs_fw_flashlock
);
359 * hermon_ioctl_flash_write()
362 hermon_ioctl_flash_write(hermon_state_t
*state
, dev_t dev
, intptr_t arg
,
365 hermon_flash_ioctl_t ioctl_info
;
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
);
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
);
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
;
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
);
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
);
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
,
418 mutex_exit(&state
->hs_fw_flashlock
);
422 /* Perform Write Sector */
423 status
= hermon_flash_write_sector(state
,
424 ioctl_info
.af_sector_num
);
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
);
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
);
456 mutex_exit(&state
->hs_fw_flashlock
);
461 * hermon_ioctl_flash_erase()
464 hermon_ioctl_flash_erase(hermon_state_t
*state
, dev_t dev
, intptr_t arg
,
467 hermon_flash_ioctl_t ioctl_info
;
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
);
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
);
491 ioctl_info
.af_type
= info32
.af_type
;
492 ioctl_info
.af_sector_num
= info32
.af_sector_num
;
494 #endif /* _MULTI_DATAMODEL */
495 if (ddi_copyin((void *)arg
, &ioctl_info
, sizeof (hermon_flash_ioctl_t
),
497 mutex_exit(&state
->hs_fw_flashlock
);
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
);
513 /* Perform Sector Erase */
514 status
= hermon_flash_erase_sector(state
,
515 ioctl_info
.af_sector_num
);
518 case HERMON_FLASH_ERASE_CHIP
:
519 /* Perform Chip Erase */
520 status
= hermon_flash_erase_chip(state
);
528 mutex_exit(&state
->hs_fw_flashlock
);
533 * hermon_ioctl_flash_init()
536 hermon_ioctl_flash_init(hermon_state_t
*state
, dev_t dev
, intptr_t arg
,
539 hermon_flash_init_ioctl_t init_info
;
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
);
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
);
567 if ((ret
= hermon_flash_init(state
)) != 0) {
571 mutex_exit(&state
->hs_fw_flashlock
);
576 if ((ret
= hermon_flash_cfi_init(state
, &init_info
.af_cfi_info
[0],
577 &intel_xcmd
)) != 0) {
581 mutex_exit(&state
->hs_fw_flashlock
);
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) {
593 mutex_exit(&state
->hs_fw_flashlock
);
596 mutex_exit(&state
->hs_fw_flashlock
);
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
,
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) {
635 mutex_exit(&state
->hs_fw_flashlock
);
638 mutex_exit(&state
->hs_fw_flashlock
);
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
);
660 hermon_fm_ereport(state
, HCA_SYS_ERR
,
670 mutex_exit(&state
->hs_fw_flashlock
);
671 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
676 * hermon_ioctl_flash_fini()
679 hermon_ioctl_flash_fini(hermon_state_t
*state
, dev_t dev
)
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
);
694 if ((ret
= hermon_ioctl_flash_cleanup_nolock(state
)) != 0) {
695 mutex_exit(&state
->hs_fw_flashlock
);
697 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
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
) {
717 * hermon_ioctl_flash_cleanup()
720 hermon_ioctl_flash_cleanup(hermon_state_t
*state
)
724 mutex_enter(&state
->hs_fw_flashlock
);
725 status
= hermon_ioctl_flash_cleanup_nolock(state
);
726 mutex_exit(&state
->hs_fw_flashlock
);
733 * hermon_ioctl_flash_cleanup_nolock()
736 hermon_ioctl_flash_cleanup_nolock(hermon_state_t
*state
)
739 ASSERT(MUTEX_HELD(&state
->hs_fw_flashlock
));
742 if (state
->hs_fw_sector
) {
743 kmem_free(state
->hs_fw_sector
, 1 << state
->hs_fw_log_sector_sz
);
747 if ((status
= hermon_flash_fini(state
)) != 0)
750 /* Set flash state to fini */
751 state
->hs_fw_flashstarted
= 0;
752 state
->hs_fw_flashdev
= 0;
758 * hermon_ioctl_info()
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
) {
773 /* copyin the user struct to kernel */
774 if (ddi_copyin((void *)arg
, &info
, sizeof (hermon_info_ioctl_t
),
780 * Check ioctl revision
782 if (info
.ai_revision
!= HERMON_VTS_IOCTL_REVISION
) {
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
);
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
),
820 * hermon_ioctl_ports()
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
;
834 * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
836 if (state
->hs_operational_mode
== HERMON_MAINTENANCE_MODE
) {
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) {
849 info
.ap_revision
= info32
.ap_revision
;
851 (hermon_stat_port_ioctl_t
*)(uintptr_t)info32
.ap_ports
;
852 info
.ap_num_ports
= info32
.ap_num_ports
;
855 #endif /* _MULTI_DATAMODEL */
856 if (ddi_copyin((void *)arg
, &info
, sizeof (hermon_ports_ioctl_t
),
862 * Check ioctl revision
864 if (info
.ap_revision
!= HERMON_VTS_IOCTL_REVISION
) {
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
),
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
),
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
904 if (ddi_copyout(&portstat
,
905 &(((hermon_stat_port_ioctl_t
*)info
.ap_ports
)[i
]),
906 sizeof (hermon_stat_port_ioctl_t
), mode
) != 0) {
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) {
931 #endif /* _MULTI_DATAMODEL */
932 if (ddi_copyout(&info
, (void *)arg
, sizeof (hermon_ports_ioctl_t
),
941 * hermon_ioctl_loopback()
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
;
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
) {
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) {
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
;
983 #endif /* _MULTI_DATAMODEL */
984 if (ddi_copyin((void *)arg
, &lb
, sizeof (hermon_loopback_ioctl_t
),
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
);
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
);
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
),
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
),
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
);
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
1062 loopmax
= max_usec
/HERMON_VTS_LOOPBACK_MIN_WAIT_DUR
;
1063 if ((max_usec
% HERMON_VTS_LOOPBACK_MIN_WAIT_DUR
) != 0) {
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
);
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
);
1082 /* Allocate and register a TX buffer */
1083 if (hermon_loopback_alloc_mem(&lstate
, &lstate
.hls_tx
,
1084 lb
.alb_buf_sz
) != 0) {
1086 HERMON_LOOPBACK_SEND_BUF_MEM_REGION_ALLOC_FAIL
;
1087 (void) hermon_loopback_copyout(&lb
, arg
, mode
);
1088 hermon_loopback_free_state(&lstate
);
1092 /* Allocate and register an RX buffer */
1093 if (hermon_loopback_alloc_mem(&lstate
, &lstate
.hls_rx
,
1094 lb
.alb_buf_sz
) != 0) {
1096 HERMON_LOOPBACK_RECV_BUF_MEM_REGION_ALLOC_FAIL
;
1097 (void) hermon_loopback_copyout(&lb
, arg
, mode
);
1098 hermon_loopback_free_state(&lstate
);
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
);
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
);
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
);
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
);
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
);
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
++) {
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
);
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))) {
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
,
1178 (void) hermon_loopback_copyout(&lb
, arg
, mode
);
1179 hermon_loopback_free_state(&lstate
);
1181 } else if (ret
== IBT_CQ_EMPTY
) {
1185 /* Compare the data buffers */
1186 if (bcmp(lstate
.hls_tx
.hlc_buf
, lstate
.hls_rx
.hlc_buf
,
1187 lb
.alb_buf_sz
) == 0) {
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
,
1197 (void) hermon_loopback_copyout(&lb
, arg
, mode
);
1198 hermon_loopback_free_state(&lstate
);
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
);
1220 * hermon_ioctl_reg_read()
1223 hermon_ioctl_reg_read(hermon_state_t
*state
, intptr_t arg
, int mode
)
1225 hermon_reg_ioctl_t rdreg
;
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
) {
1242 /* Copy in the hermon_reg_ioctl_t structure */
1243 status
= ddi_copyin((void *)arg
, &rdreg
, sizeof (hermon_reg_ioctl_t
),
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
);
1256 case HERMON_UAR_BAR
:
1257 baseaddr
= (uintptr_t)state
->hs_reg_uar_baseaddr
;
1258 handle
= hermon_get_uarhdl(state
);
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
,
1280 /* Copy in the result into the hermon_reg_ioctl_t structure */
1281 status
= ddi_copyout(&rdreg
, (void *)arg
, sizeof (hermon_reg_ioctl_t
),
1289 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
1295 * hermon_ioctl_reg_write()
1298 hermon_ioctl_reg_write(hermon_state_t
*state
, intptr_t arg
, int mode
)
1300 hermon_reg_ioctl_t wrreg
;
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
) {
1317 /* Copy in the hermon_reg_ioctl_t structure */
1318 status
= ddi_copyin((void *)arg
, &wrreg
, sizeof (hermon_reg_ioctl_t
),
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
);
1331 case HERMON_UAR_BAR
:
1332 baseaddr
= (uintptr_t)state
->hs_reg_uar_baseaddr
;
1333 handle
= hermon_get_uarhdl(state
);
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
,
1356 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
1362 hermon_ioctl_write_boot_addr(hermon_state_t
*state
, dev_t dev
, intptr_t arg
,
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
);
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
);
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
;
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
);
1404 switch (state
->hs_fw_cmdset
) {
1405 case HERMON_FLASH_AMD_CMDSET
:
1406 case HERMON_FLASH_INTEL_CMDSET
:
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
);
1427 case HERMON_FLASH_UNKNOWN_CMDSET
:
1429 mutex_exit(&state
->hs_fw_flashlock
);
1432 mutex_exit(&state
->hs_fw_flashlock
);
1436 mutex_exit(&state
->hs_fw_flashlock
);
1437 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
1442 * hermon_flash_reset()
1445 hermon_flash_reset(hermon_state_t
*state
)
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
,
1462 case HERMON_FLASH_INTEL_CMDSET
:
1463 hermon_flash_write(state
, 0x555, HERMON_HW_FLASH_RESET_INTEL
,
1470 /* It appears no reset is needed for SPI */
1471 case HERMON_FLASH_SPI_CMDSET
:
1475 case HERMON_FLASH_UNKNOWN_CMDSET
:
1484 * hermon_flash_read_sector()
1487 hermon_flash_read_sector(hermon_state_t
*state
, uint32_t sector_num
)
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)
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
);
1518 * hermon_flash_read_quadlet()
1521 hermon_flash_read_quadlet(hermon_state_t
*state
, uint32_t *data
,
1526 /* Set the flash bank correctly for the given address */
1527 if ((status
= hermon_flash_bank(state
, addr
)) != 0) {
1531 /* Read one quadlet of data */
1532 *data
= hermon_flash_read(state
, addr
, &status
);
1541 * hermon_flash_write_sector()
1544 hermon_flash_write_sector(hermon_state_t
*state
, uint32_t sector_num
)
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) {
1568 /* Erase the sector before writing */
1569 status
= hermon_flash_erase_sector(state
, sector_num
);
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) {
1584 status
= hermon_flash_reset(state
);
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
,
1597 status
= hermon_flash_reset(state
);
1600 case HERMON_FLASH_UNKNOWN_CMDSET
:
1610 * hermon_flash_spi_write_dword()
1612 * NOTE: This function assumes that "data" is in network byte order.
1616 hermon_flash_spi_write_dword(hermon_state_t
*state
, uint32_t addr
,
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
,
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
);
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) {
1655 /* the FMA retry loop ends. */
1656 hermon_pio_end(state
, hdl
, pio_error
, fm_loop_cnt
, fm_status
, fm_test
);
1660 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
1665 * hermon_flash_write_byte()
1668 hermon_flash_write_byte(hermon_state_t
*state
, uint32_t addr
, uchar_t data
)
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
);
1688 hermon_flash_write(state
, addr
, 0x55, &status
);
1693 hermon_flash_write(state
, addr
, 0xA0, &status
);
1698 hermon_flash_write(state
, addr
, data
, &status
);
1703 /* Wait for Write Byte to Complete */
1707 stat
= hermon_flash_read(state
, addr
& ~3, &status
);
1712 if (i
== hermon_hw_flash_timeout_write
) {
1714 "hermon_flash_write_byte: ACS write "
1715 "timeout: addr: 0x%x, data: 0x%x\n",
1717 hermon_fm_ereport(state
, HCA_SYS_ERR
,
1722 } while (data
!= ((stat
>> ((3 - (addr
& 3)) << 3)) & 0xFF));
1726 case HERMON_FLASH_INTEL_CMDSET
:
1727 /* Issue Flash Byte program command */
1728 hermon_flash_write(state
, addr
, HERMON_HW_FLASH_ICS_WRITE
,
1733 hermon_flash_write(state
, addr
, data
, &status
);
1738 /* Wait for Write Byte to Complete */
1742 stat
= hermon_flash_read(state
, addr
& ~3, &status
);
1747 if (i
== hermon_hw_flash_timeout_write
) {
1749 "hermon_flash_write_byte: ICS write "
1750 "timeout: addr: %x, data: %x\n",
1752 hermon_fm_ereport(state
, HCA_SYS_ERR
,
1757 } while ((stat
& HERMON_HW_FLASH_ICS_READY
) == 0);
1759 if (stat
& HERMON_HW_FLASH_ICS_ERROR
) {
1761 "hermon_flash_write_byte: ICS write cmd error: "
1762 "addr: %x, data: %x\n",
1764 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
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
;
1785 if ((status
= hermon_flash_read_quadlet(state
, &dword
.dword
,
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
,
1798 case HERMON_FLASH_UNKNOWN_CMDSET
:
1801 "hermon_flash_write_byte: unknown cmd set: 0x%x\n",
1802 state
->hs_fw_cmdset
);
1811 * hermon_flash_erase_sector()
1814 hermon_flash_erase_sector(hermon_state_t
*state
, uint32_t sector_num
)
1816 ddi_acc_handle_t hdl
;
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
);
1836 hermon_flash_write(state
, addr
, 0x55, &status
);
1841 hermon_flash_write(state
, addr
, 0x80, &status
);
1846 hermon_flash_write(state
, addr
, 0xAA, &status
);
1851 hermon_flash_write(state
, addr
, 0x55, &status
);
1856 hermon_flash_write(state
, addr
, 0x30, &status
);
1861 /* Wait for Sector Erase to complete */
1865 stat
= hermon_flash_read(state
, addr
, &status
);
1870 if (i
== hermon_hw_flash_timeout_erase
) {
1872 "hermon_flash_erase_sector: "
1873 "ACS erase timeout\n");
1874 hermon_fm_ereport(state
, HCA_SYS_ERR
,
1879 } while (stat
!= 0xFFFFFFFF);
1882 case HERMON_FLASH_INTEL_CMDSET
:
1883 /* Issue Flash Sector Erase Command */
1884 hermon_flash_write(state
, addr
, HERMON_HW_FLASH_ICS_ERASE
,
1890 hermon_flash_write(state
, addr
, HERMON_HW_FLASH_ICS_CONFIRM
,
1896 /* Wait for Sector Erase to complete */
1900 stat
= hermon_flash_read(state
, addr
& ~3, &status
);
1905 if (i
== hermon_hw_flash_timeout_erase
) {
1907 "hermon_flash_erase_sector: "
1908 "ICS erase timeout\n");
1909 hermon_fm_ereport(state
, HCA_SYS_ERR
,
1914 } while ((stat
& HERMON_HW_FLASH_ICS_READY
) == 0);
1916 if (stat
& HERMON_HW_FLASH_ICS_ERROR
) {
1918 "hermon_flash_erase_sector: "
1919 "ICS erase cmd error\n");
1920 hermon_fm_ereport(state
, HCA_SYS_ERR
,
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
,
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
,
1951 /* Wait for Sector Erase to complete */
1952 status
= hermon_flash_spi_wait_wip(state
);
1955 case HERMON_FLASH_UNKNOWN_CMDSET
:
1958 "hermon_flash_erase_sector: unknown cmd set: 0x%x\n",
1959 state
->hs_fw_cmdset
);
1964 /* Reset the flash device */
1966 status
= hermon_flash_reset(state
);
1971 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
1976 * hermon_flash_erase_chip()
1979 hermon_flash_erase_chip(hermon_state_t
*state
)
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
);
1995 hermon_flash_write(state
, 0, 0x55, &status
);
2000 hermon_flash_write(state
, 0, 0x80, &status
);
2005 hermon_flash_write(state
, 0, 0xAA, &status
);
2010 hermon_flash_write(state
, 0, 0x55, &status
);
2015 hermon_flash_write(state
, 0, 0x10, &status
);
2020 /* Wait for Chip Erase to Complete */
2024 stat
= hermon_flash_read(state
, 0, &status
);
2029 if (i
== hermon_hw_flash_timeout_erase
) {
2031 "hermon_flash_erase_chip: erase timeout\n");
2032 hermon_fm_ereport(state
, HCA_SYS_ERR
,
2037 } while (stat
!= 0xFFFFFFFF);
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
);
2053 "hermon_flash_erase_chip: "
2054 "sector %d erase error\n", i
);
2060 case HERMON_FLASH_UNKNOWN_CMDSET
:
2062 cmn_err(CE_WARN
, "hermon_flash_erase_chip: "
2063 "unknown cmd set: 0x%x\n", state
->hs_fw_cmdset
);
2072 * hermon_flash_spi_write_enable()
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()
2091 hermon_flash_spi_wait_wip(hermon_state_t
*state
)
2093 ddi_acc_handle_t hdl
;
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
,
2105 /* wait on the gateway to clear busy */
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 */
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
);
2130 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2135 * hermon_flash_bank()
2138 hermon_flash_bank(hermon_state_t
*state
, uint32_t addr
)
2140 ddi_acc_handle_t hdl
;
2143 /* initialize the FMA retry loop */
2144 hermon_pio_init(fm_loop_cnt
, fm_status
, fm_test
);
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 */
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
);
2182 case HERMON_FLASH_UNKNOWN_CMDSET
:
2187 state
->hs_fw_flashbank
= bank
;
2192 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2197 * hermon_flash_spi_exec_command()
2200 hermon_flash_spi_exec_command(hermon_state_t
*state
, ddi_acc_handle_t hdl
,
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
);
2211 data
= hermon_flash_read_cfg(state
, hdl
,
2212 HERMON_HW_FLASH_SPI_GW
);
2214 } while ((data
& HERMON_HW_FLASH_SPI_BUSY
) &&
2215 (timeout
< hermon_hw_flash_timeout_config
));
2219 * hermon_flash_read()
2222 hermon_flash_read(hermon_state_t
*state
, uint32_t addr
, int *err
)
2224 ddi_acc_handle_t hdl
;
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
,
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
);
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));
2271 data
= hermon_flash_read_cfg(state
, hdl
,
2272 HERMON_HW_FLASH_ADDR
);
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 "
2281 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2285 data
= hermon_flash_read_cfg(state
, hdl
, HERMON_HW_FLASH_DATA
);
2288 case HERMON_FLASH_UNKNOWN_CMDSET
:
2290 cmn_err(CE_CONT
, "hermon_flash_read: unknown cmdset: 0x%x\n",
2291 state
->hs_fw_cmdset
);
2297 /* the FMA retry loop ends. */
2298 hermon_pio_end(state
, hdl
, pio_error
, fm_loop_cnt
, fm_status
, fm_test
);
2304 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2309 * hermon_flash_write()
2312 hermon_flash_write(hermon_state_t
*state
, uint32_t addr
, uchar_t data
, int *err
)
2314 ddi_acc_handle_t hdl
;
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
,
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
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));
2341 cmd
= hermon_flash_read_cfg(state
, hdl
, HERMON_HW_FLASH_ADDR
);
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");
2349 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2353 /* the FMA retry loop ends. */
2354 hermon_pio_end(state
, hdl
, pio_error
, fm_loop_cnt
, fm_status
, fm_test
);
2360 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2364 * hermon_flash_init()
2367 hermon_flash_init(hermon_state_t
*state
)
2370 ddi_acc_handle_t hdl
;
2374 /* initialize the FMA retry loop */
2375 hermon_pio_init(fm_loop_cnt
, fm_status
, fm_test
);
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
,
2384 /* Init the flash */
2388 * Grab the WRCONF semaphore.
2390 word
= hermon_flash_read_cfg(state
, hdl
, HERMON_HW_FLASH_WRCONF_SEMA
);
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
2400 word
= hermon_flash_read_cfg(state
, hdl
,
2401 HERMON_HW_FLASH_GPIO_SEMA
);
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
);
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
);
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
);
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
);
2463 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2468 * hermon_flash_cfi_init
2469 * Implements access to the CFI (Common Flash Interface) data
2472 hermon_flash_cfi_init(hermon_state_t
*state
, uint32_t *cfi_info
,
2476 uint32_t sector_sz_bytes
;
2478 uint8_t cfi_ch_info
[HERMON_CFI_INFO_SIZE
];
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
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);
2501 * Determine if the user command supports the Intel Extended
2502 * Command Set. The query string is contained in the fourth
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");
2517 hermon_flash_write(state
, 0x55, HERMON_FLASH_CFI_INIT
, &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
);
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
) {
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
;
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)
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';
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);
2605 * hermon_flash_fini()
2608 hermon_flash_fini(hermon_state_t
*state
)
2611 ddi_acc_handle_t hdl
;
2613 /* initialize the FMA retry loop */
2614 hermon_pio_init(fm_loop_cnt
, fm_status
, fm_test
);
2617 hdl
= hermon_get_pcihdl(state
);
2619 if ((status
= hermon_flash_bank(state
, 0)) != 0)
2622 /* the FMA retry loop starts. */
2623 hermon_pio_start(state
, hdl
, pio_error
, fm_loop_cnt
, fm_status
,
2627 * Restore original GPIO Values
2629 hermon_flash_write_cfg(state
, hdl
, HERMON_HW_FLASH_GPIO_DATA
,
2630 state
->hs_fw_gpio
[0]);
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]);
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
);
2652 hermon_fm_ereport(state
, HCA_SYS_ERR
, HCA_ERR_IOCTL
);
2657 * hermon_flash_read_cfg
2660 hermon_flash_read_cfg(hermon_state_t
*state
, ddi_acc_handle_t pci_config_hdl
,
2666 read
= ddi_get32(hermon_get_cmdhdl(state
), (uint32_t *)(void *)
2667 (state
->hs_reg_cmd_baseaddr
+ addr
));
2670 * Perform flash read operation:
2671 * 1) Place addr to read from on the HERMON_HW_FLASH_CFG_ADDR
2673 * 2) Read data at that addr from the HERMON_HW_FLASH_CFG_DATA
2676 pci_config_put32(pci_config_hdl
, HERMON_HW_FLASH_CFG_ADDR
,
2678 read
= pci_config_get32(pci_config_hdl
,
2679 HERMON_HW_FLASH_CFG_DATA
);
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
);
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);
2703 sem_value
= hermon_flash_read_cfg(state
, pci_config_hdl
,
2704 HERMON_HW_FLASH_WRCONF_SEMA
);
2710 * hermon_flash_write_cfg
2714 hermon_flash_write_cfg_helper(hermon_state_t
*state
,
2715 ddi_acc_handle_t pci_config_hdl
, uint32_t addr
, uint32_t data
)
2717 hermon_flash_write_cfg(hermon_state_t
*state
,
2718 ddi_acc_handle_t pci_config_hdl
, uint32_t addr
, uint32_t data
)
2722 ddi_put32(hermon_get_cmdhdl(state
), (uint32_t *)(void *)
2723 (state
->hs_reg_cmd_baseaddr
+ addr
), data
);
2728 * Perform flash write operation:
2729 * 1) Place addr to write to on the HERMON_HW_FLASH_CFG_ADDR
2731 * 2) Place data to write on to the HERMON_HW_FLASH_CFG_DATA
2734 pci_config_put32(pci_config_hdl
, HERMON_HW_FLASH_CFG_ADDR
,
2736 pci_config_put32(pci_config_hdl
, HERMON_HW_FLASH_CFG_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
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));
2756 hermon_flash_cfi_dword(uint32_t *dword
, uint8_t *ch
, int i
)
2759 ((uint32_t)ch
[i
] << 24 |
2760 (uint32_t)ch
[i
+1] << 16 |
2761 (uint32_t)ch
[i
+2] << 8 |
2766 * hermon_loopback_free_qps
2769 hermon_loopback_free_qps(hermon_loopback_state_t
*lstate
)
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
,
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
,
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
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
,
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
,
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
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
;
2850 * hermon_loopback_init_qp_info
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
));
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
=
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
=
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
=
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
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
) {
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
) {
2932 * hermon_loopback_alloc_qps
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
;
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
,
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;
2983 * hermon_loopback_modify_qp
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
) {
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
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;
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;
3029 * hermon_loopback_copyout
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
;
3040 (caddr32_t
)(uintptr_t)lb
->alb_send_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) {
3056 #endif /* _MULTI_DATAMODEL */
3057 if (ddi_copyout(lb
, (void *)arg
, sizeof (hermon_loopback_ioctl_t
),
3065 * hermon_loopback_post_send
3068 hermon_loopback_post_send(hermon_loopback_state_t
*lstate
,
3069 hermon_loopback_comm_t
*tx
, hermon_loopback_comm_t
*rx
)
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
,
3097 if (ret
!= IBT_SUCCESS
) {
3104 * hermon_loopback_poll_cq
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
);