Print this page
8368 remove warlock leftovers from usr/src/uts


 856         if (ddi_copyin((void *)arg, &info, sizeof (hermon_ports_ioctl_t),
 857             mode) != 0) {
 858                 return (EFAULT);
 859         }
 860 
 861         /*
 862          * Check ioctl revision
 863          */
 864         if (info.ap_revision != HERMON_VTS_IOCTL_REVISION) {
 865                 return (EINVAL);
 866         }
 867 
 868         /* Allocate space for temporary GID table/PKey table */
 869         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
 870         sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
 871             KM_SLEEP);
 872         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
 873         pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
 874             KM_SLEEP);
 875 
 876         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sgid_tbl, *pkey_tbl))
 877 
 878         /*
 879          * Setup the number of ports, then loop through all ports and
 880          * query properties of each.
 881          */
 882         info.ap_num_ports = (uint8_t)state->hs_cfg_profile->cp_num_ports;
 883         for (i = 0; i < info.ap_num_ports; i++) {
 884                 /*
 885                  * Get portstate information from the device.  If
 886                  * hermon_port_query() fails, leave zeroes in user
 887                  * struct port entry and continue.
 888                  */
 889                 bzero(&pi, sizeof (ibt_hca_portinfo_t));
 890                 pi.p_sgid_tbl = sgid_tbl;
 891                 pi.p_pkey_tbl = pkey_tbl;
 892                 (void) hermon_port_query(state, i + 1, &pi);
 893 
 894                 portstat.asp_port_num   = pi.p_port_num;
 895                 portstat.asp_state      = pi.p_linkstate;
 896                 portstat.asp_guid       = pi.p_sgid_tbl[0].gid_guid;
 897 


 934                 return (EFAULT);
 935         }
 936 
 937         return (0);
 938 }
 939 
 940 /*
 941  * hermon_ioctl_loopback()
 942  */
 943 static int
 944 hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg, int mode)
 945 {
 946         hermon_loopback_ioctl_t lb;
 947         hermon_loopback_state_t lstate;
 948         ibt_hca_portinfo_t      pi;
 949         uint_t                  tbl_size, loopmax, max_usec;
 950         ib_gid_t                *sgid_tbl;
 951         ib_pkey_t               *pkey_tbl;
 952         int                     j, iter, ret;
 953 
 954         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(lstate))
 955 
 956         /*
 957          * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
 958          */
 959         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
 960                 return (EFAULT);
 961         }
 962 
 963         /* copyin the user struct to kernel */
 964 #ifdef _MULTI_DATAMODEL
 965         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 966                 hermon_loopback_ioctl32_t lb32;
 967 
 968                 if (ddi_copyin((void *)arg, &lb32,
 969                     sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
 970                         return (EFAULT);
 971                 }
 972                 lb.alb_revision     = lb32.alb_revision;
 973                 lb.alb_send_buf     = (caddr_t)(uintptr_t)lb32.alb_send_buf;
 974                 lb.alb_fail_buf     = (caddr_t)(uintptr_t)lb32.alb_fail_buf;
 975                 lb.alb_buf_sz       = lb32.alb_buf_sz;


2132 }
2133 
2134 /*
2135  * hermon_flash_bank()
2136  */
2137 static int
2138 hermon_flash_bank(hermon_state_t *state, uint32_t addr)
2139 {
2140         ddi_acc_handle_t        hdl;
2141         uint32_t                bank;
2142 
2143         /* initialize the FMA retry loop */
2144         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2145 
2146         /* Set handle */
2147         hdl = hermon_get_pcihdl(state);
2148 
2149         /* Determine the bank setting from the address */
2150         bank = addr & HERMON_HW_FLASH_BANK_MASK;
2151 
2152         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(state->hs_fw_flashbank))
2153 
2154         /*
2155          * If the bank is different from the currently set bank, we need to
2156          * change it.  Also, if an 'addr' of 0 is given, this allows the
2157          * capability to force the flash bank to 0.  This is useful at init
2158          * time to initially set the bank value
2159          */
2160         if (state->hs_fw_flashbank != bank || addr == 0) {
2161                 switch (state->hs_fw_cmdset) {
2162                 case HERMON_FLASH_SPI_CMDSET:
2163                         /* CMJ: not needed for hermon */
2164                         break;
2165 
2166                 case HERMON_FLASH_INTEL_CMDSET:
2167                 case HERMON_FLASH_AMD_CMDSET:
2168                         /* the FMA retry loop starts. */
2169                         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt,
2170                             fm_status, fm_test);
2171 
2172                         hermon_flash_write_cfg(state, hdl,
2173                             HERMON_HW_FLASH_GPIO_DATACLEAR, 0x70);


2755 }
2756 
2757 static void
2758 hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i)
2759 {
2760         *dword = (uint32_t)
2761             ((uint32_t)ch[i] << 24 |
2762             (uint32_t)ch[i+1] << 16 |
2763             (uint32_t)ch[i+2] << 8 |
2764             (uint32_t)ch[i+3]);
2765 }
2766 
2767 /*
2768  * hermon_loopback_free_qps
2769  */
2770 static void
2771 hermon_loopback_free_qps(hermon_loopback_state_t *lstate)
2772 {
2773         int i;
2774 
2775         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2776 
2777         if (lstate->hls_tx.hlc_qp_hdl != NULL) {
2778                 (void) hermon_qp_free(lstate->hls_state,
2779                     &lstate->hls_tx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2780                     HERMON_NOSLEEP);
2781         }
2782         if (lstate->hls_rx.hlc_qp_hdl != NULL) {
2783                 (void) hermon_qp_free(lstate->hls_state,
2784                     &lstate->hls_rx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2785                     HERMON_NOSLEEP);
2786         }
2787         lstate->hls_tx.hlc_qp_hdl = NULL;
2788         lstate->hls_rx.hlc_qp_hdl = NULL;
2789         for (i = 0; i < 2; i++) {
2790                 if (lstate->hls_tx.hlc_cqhdl[i] != NULL) {
2791                         (void) hermon_cq_free(lstate->hls_state,
2792                             &lstate->hls_tx.hlc_cqhdl[i], HERMON_NOSLEEP);
2793                 }
2794                 if (lstate->hls_rx.hlc_cqhdl[i] != NULL) {
2795                         (void) hermon_cq_free(lstate->hls_state,
2796                             &lstate->hls_rx.hlc_cqhdl[i], HERMON_NOSLEEP);


2818                     HERMON_NOSLEEP);
2819         }
2820         if (lstate->hls_pd_hdl != NULL) {
2821                 (void) hermon_pd_free(lstate->hls_state, &lstate->hls_pd_hdl);
2822         }
2823         if (lstate->hls_tx.hlc_buf != NULL) {
2824                 kmem_free(lstate->hls_tx.hlc_buf, lstate->hls_tx.hlc_buf_sz);
2825         }
2826         if (lstate->hls_rx.hlc_buf != NULL) {
2827                 kmem_free(lstate->hls_rx.hlc_buf, lstate->hls_rx.hlc_buf_sz);
2828         }
2829         bzero(lstate, sizeof (hermon_loopback_state_t));
2830 }
2831 
2832 /*
2833  * hermon_loopback_init
2834  */
2835 static int
2836 hermon_loopback_init(hermon_state_t *state, hermon_loopback_state_t *lstate)
2837 {
2838         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2839 
2840         lstate->hls_hca_hdl = (ibc_hca_hdl_t)state;
2841         lstate->hls_status  = hermon_pd_alloc(lstate->hls_state,
2842             &lstate->hls_pd_hdl, HERMON_NOSLEEP);
2843         if (lstate->hls_status != IBT_SUCCESS) {
2844                 lstate->hls_err = HERMON_LOOPBACK_PROT_DOMAIN_ALLOC_FAIL;
2845                 return (EFAULT);
2846         }
2847 
2848         return (0);
2849 }
2850 
2851 /*
2852  * hermon_loopback_init_qp_info
2853  */
2854 static void
2855 hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
2856     hermon_loopback_comm_t *comm)
2857 {
2858         bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2859         bzero(&comm->hlc_qp_attr, sizeof (ibt_qp_alloc_attr_t));


2882         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_send_grh = 0;
2883         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid =
2884             lstate->hls_lid;
2885         comm->hlc_qp_info.qp_transport.rc.rc_retry_cnt = lstate->hls_retry;
2886         comm->hlc_qp_info.qp_transport.rc.rc_sq_psn = 0;
2887         comm->hlc_qp_info.qp_transport.rc.rc_rq_psn = 0;
2888         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_in       = 4;
2889         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_out = 4;
2890         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = 0;
2891         comm->hlc_qp_info.qp_transport.rc.rc_min_rnr_nak = IBT_RNR_NAK_655ms;
2892         comm->hlc_qp_info.qp_transport.rc.rc_path_mtu = IB_MTU_1K;
2893 }
2894 
2895 /*
2896  * hermon_loopback_alloc_mem
2897  */
2898 static int
2899 hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
2900     hermon_loopback_comm_t *comm, int sz)
2901 {
2902         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2903 
2904         /* Allocate buffer of specified size */
2905         comm->hlc_buf_sz = sz;
2906         comm->hlc_buf         = kmem_zalloc(sz, KM_NOSLEEP);
2907         if (comm->hlc_buf == NULL) {
2908                 return (EFAULT);
2909         }
2910 
2911         /* Register the buffer as a memory region */
2912         comm->hlc_memattr.mr_vaddr = (uint64_t)(uintptr_t)comm->hlc_buf;
2913         comm->hlc_memattr.mr_len   = (ib_msglen_t)sz;
2914         comm->hlc_memattr.mr_as         = NULL;
2915         comm->hlc_memattr.mr_flags = IBT_MR_NOSLEEP |
2916             IBT_MR_ENABLE_REMOTE_WRITE | IBT_MR_ENABLE_LOCAL_WRITE;
2917 
2918         comm->hlc_status = hermon_mr_register(lstate->hls_state,
2919             lstate->hls_pd_hdl, &comm->hlc_memattr, &comm->hlc_mrhdl,
2920             NULL, HERMON_MPT_DMPT);
2921 
2922         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm->hlc_mrhdl))
2923 
2924         comm->hlc_mrdesc.md_vaddr  = comm->hlc_mrhdl->mr_bindinfo.bi_addr;
2925         comm->hlc_mrdesc.md_lkey   = comm->hlc_mrhdl->mr_lkey;
2926         comm->hlc_mrdesc.md_rkey   = comm->hlc_mrhdl->mr_rkey;
2927         if (comm->hlc_status != IBT_SUCCESS) {
2928                 return (EFAULT);
2929         }
2930         return (0);
2931 }
2932 
2933 /*
2934  * hermon_loopback_alloc_qps
2935  */
2936 static int
2937 hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
2938     hermon_loopback_comm_t *comm)
2939 {
2940         uint32_t                i, real_size;
2941         hermon_qp_info_t                qpinfo;
2942 
2943         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2944         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2945 
2946         /* Allocate send and recv CQs */
2947         for (i = 0; i < 2; i++) {
2948                 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2949                 comm->hlc_cq_attr.cq_size = 128;
2950                 comm->hlc_status = hermon_cq_alloc(lstate->hls_state,
2951                     (ibt_cq_hdl_t)NULL, &comm->hlc_cq_attr, &real_size,
2952                     &comm->hlc_cqhdl[i], HERMON_NOSLEEP);
2953                 if (comm->hlc_status != IBT_SUCCESS) {
2954                         lstate->hls_err += i;
2955                         return (EFAULT);
2956                 }
2957         }
2958 
2959         /* Allocate the QP */
2960         hermon_loopback_init_qp_info(lstate, comm);
2961         comm->hlc_qp_attr.qp_pd_hdl   = (ibt_pd_hdl_t)lstate->hls_pd_hdl;
2962         comm->hlc_qp_attr.qp_scq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[0];
2963         comm->hlc_qp_attr.qp_rcq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[1];
2964         comm->hlc_qp_attr.qp_ibc_scq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[0];
2965         comm->hlc_qp_attr.qp_ibc_rcq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[1];


2971         comm->hlc_status = hermon_qp_alloc(lstate->hls_state, &qpinfo,
2972             HERMON_NOSLEEP);
2973         if (comm->hlc_status == DDI_SUCCESS) {
2974                 comm->hlc_qp_hdl = qpinfo.qpi_qphdl;
2975         }
2976 
2977         if (comm->hlc_status != IBT_SUCCESS) {
2978                 lstate->hls_err += 2;
2979                 return (EFAULT);
2980         }
2981         return (0);
2982 }
2983 
2984 /*
2985  * hermon_loopback_modify_qp
2986  */
2987 static int
2988 hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
2989     hermon_loopback_comm_t *comm, uint_t qp_num)
2990 {
2991         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2992         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2993 
2994         /* Modify QP to INIT */
2995         hermon_loopback_init_qp_info(lstate, comm);
2996         comm->hlc_qp_info.qp_state = IBT_STATE_INIT;
2997         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2998             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2999         if (comm->hlc_status != IBT_SUCCESS) {
3000                 return (EFAULT);
3001         }
3002 
3003         /*
3004          * Modify QP to RTR (set destination LID and QP number to local
3005          * LID and QP number)
3006          */
3007         comm->hlc_qp_info.qp_state = IBT_STATE_RTR;
3008         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid
3009             = lstate->hls_lid;
3010         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = qp_num;
3011         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3012             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3013         if (comm->hlc_status != IBT_SUCCESS) {


3055                         return (EFAULT);
3056                 }
3057         } else
3058 #endif /* _MULTI_DATAMODEL */
3059         if (ddi_copyout(lb, (void *)arg, sizeof (hermon_loopback_ioctl_t),
3060             mode) != 0) {
3061                 return (EFAULT);
3062         }
3063         return (0);
3064 }
3065 
3066 /*
3067  * hermon_loopback_post_send
3068  */
3069 static int
3070 hermon_loopback_post_send(hermon_loopback_state_t *lstate,
3071     hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx)
3072 {
3073         int      ret;
3074 
3075         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tx))
3076 
3077         bzero(&tx->hlc_sgl, sizeof (ibt_wr_ds_t));
3078         bzero(&tx->hlc_wr, sizeof (ibt_send_wr_t));
3079 
3080         /* Initialize local address for TX buffer */
3081         tx->hlc_sgl.ds_va   = tx->hlc_mrdesc.md_vaddr;
3082         tx->hlc_sgl.ds_key  = tx->hlc_mrdesc.md_lkey;
3083         tx->hlc_sgl.ds_len  = tx->hlc_buf_sz;
3084 
3085         /* Initialize the remaining details of the work request */
3086         tx->hlc_wr.wr_id = tx->hlc_wrid++;
3087         tx->hlc_wr.wr_flags  = IBT_WR_SEND_SIGNAL;
3088         tx->hlc_wr.wr_nds    = 1;
3089         tx->hlc_wr.wr_sgl    = &tx->hlc_sgl;
3090         tx->hlc_wr.wr_opcode = IBT_WRC_RDMAW;
3091         tx->hlc_wr.wr_trans  = IBT_RC_SRV;
3092 
3093         /* Initialize the remote address for RX buffer */
3094         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_raddr = rx->hlc_mrdesc.md_vaddr;
3095         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_rkey  = rx->hlc_mrdesc.md_rkey;
3096         tx->hlc_complete = 0;
3097         ret = hermon_post_send(lstate->hls_state, tx->hlc_qp_hdl, &tx->hlc_wr,
3098             1, NULL);
3099         if (ret != IBT_SUCCESS) {
3100                 return (EFAULT);
3101         }
3102         return (0);
3103 }
3104 
3105 /*
3106  * hermon_loopback_poll_cq
3107  */
3108 static int
3109 hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
3110     hermon_loopback_comm_t *comm)
3111 {
3112         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
3113 
3114         comm->hlc_wc.wc_status       = 0;
3115         comm->hlc_num_polled = 0;
3116         comm->hlc_status = hermon_cq_poll(lstate->hls_state,
3117             comm->hlc_cqhdl[0], &comm->hlc_wc, 1, &comm->hlc_num_polled);
3118         if ((comm->hlc_status == IBT_SUCCESS) &&
3119             (comm->hlc_wc.wc_status != IBT_WC_SUCCESS)) {
3120                 comm->hlc_status = ibc_get_ci_failure(0);
3121         }
3122         return (comm->hlc_status);
3123 }


 856         if (ddi_copyin((void *)arg, &info, sizeof (hermon_ports_ioctl_t),
 857             mode) != 0) {
 858                 return (EFAULT);
 859         }
 860 
 861         /*
 862          * Check ioctl revision
 863          */
 864         if (info.ap_revision != HERMON_VTS_IOCTL_REVISION) {
 865                 return (EINVAL);
 866         }
 867 
 868         /* Allocate space for temporary GID table/PKey table */
 869         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
 870         sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
 871             KM_SLEEP);
 872         tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
 873         pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
 874             KM_SLEEP);
 875 


 876         /*
 877          * Setup the number of ports, then loop through all ports and
 878          * query properties of each.
 879          */
 880         info.ap_num_ports = (uint8_t)state->hs_cfg_profile->cp_num_ports;
 881         for (i = 0; i < info.ap_num_ports; i++) {
 882                 /*
 883                  * Get portstate information from the device.  If
 884                  * hermon_port_query() fails, leave zeroes in user
 885                  * struct port entry and continue.
 886                  */
 887                 bzero(&pi, sizeof (ibt_hca_portinfo_t));
 888                 pi.p_sgid_tbl = sgid_tbl;
 889                 pi.p_pkey_tbl = pkey_tbl;
 890                 (void) hermon_port_query(state, i + 1, &pi);
 891 
 892                 portstat.asp_port_num   = pi.p_port_num;
 893                 portstat.asp_state      = pi.p_linkstate;
 894                 portstat.asp_guid       = pi.p_sgid_tbl[0].gid_guid;
 895 


 932                 return (EFAULT);
 933         }
 934 
 935         return (0);
 936 }
 937 
 938 /*
 939  * hermon_ioctl_loopback()
 940  */
 941 static int
 942 hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg, int mode)
 943 {
 944         hermon_loopback_ioctl_t lb;
 945         hermon_loopback_state_t lstate;
 946         ibt_hca_portinfo_t      pi;
 947         uint_t                  tbl_size, loopmax, max_usec;
 948         ib_gid_t                *sgid_tbl;
 949         ib_pkey_t               *pkey_tbl;
 950         int                     j, iter, ret;
 951 


 952         /*
 953          * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
 954          */
 955         if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
 956                 return (EFAULT);
 957         }
 958 
 959         /* copyin the user struct to kernel */
 960 #ifdef _MULTI_DATAMODEL
 961         if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
 962                 hermon_loopback_ioctl32_t lb32;
 963 
 964                 if (ddi_copyin((void *)arg, &lb32,
 965                     sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
 966                         return (EFAULT);
 967                 }
 968                 lb.alb_revision     = lb32.alb_revision;
 969                 lb.alb_send_buf     = (caddr_t)(uintptr_t)lb32.alb_send_buf;
 970                 lb.alb_fail_buf     = (caddr_t)(uintptr_t)lb32.alb_fail_buf;
 971                 lb.alb_buf_sz       = lb32.alb_buf_sz;


2128 }
2129 
2130 /*
2131  * hermon_flash_bank()
2132  */
2133 static int
2134 hermon_flash_bank(hermon_state_t *state, uint32_t addr)
2135 {
2136         ddi_acc_handle_t        hdl;
2137         uint32_t                bank;
2138 
2139         /* initialize the FMA retry loop */
2140         hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2141 
2142         /* Set handle */
2143         hdl = hermon_get_pcihdl(state);
2144 
2145         /* Determine the bank setting from the address */
2146         bank = addr & HERMON_HW_FLASH_BANK_MASK;
2147 


2148         /*
2149          * If the bank is different from the currently set bank, we need to
2150          * change it.  Also, if an 'addr' of 0 is given, this allows the
2151          * capability to force the flash bank to 0.  This is useful at init
2152          * time to initially set the bank value
2153          */
2154         if (state->hs_fw_flashbank != bank || addr == 0) {
2155                 switch (state->hs_fw_cmdset) {
2156                 case HERMON_FLASH_SPI_CMDSET:
2157                         /* CMJ: not needed for hermon */
2158                         break;
2159 
2160                 case HERMON_FLASH_INTEL_CMDSET:
2161                 case HERMON_FLASH_AMD_CMDSET:
2162                         /* the FMA retry loop starts. */
2163                         hermon_pio_start(state, hdl, pio_error, fm_loop_cnt,
2164                             fm_status, fm_test);
2165 
2166                         hermon_flash_write_cfg(state, hdl,
2167                             HERMON_HW_FLASH_GPIO_DATACLEAR, 0x70);


2749 }
2750 
2751 static void
2752 hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i)
2753 {
2754         *dword = (uint32_t)
2755             ((uint32_t)ch[i] << 24 |
2756             (uint32_t)ch[i+1] << 16 |
2757             (uint32_t)ch[i+2] << 8 |
2758             (uint32_t)ch[i+3]);
2759 }
2760 
2761 /*
2762  * hermon_loopback_free_qps
2763  */
2764 static void
2765 hermon_loopback_free_qps(hermon_loopback_state_t *lstate)
2766 {
2767         int i;
2768 


2769         if (lstate->hls_tx.hlc_qp_hdl != NULL) {
2770                 (void) hermon_qp_free(lstate->hls_state,
2771                     &lstate->hls_tx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2772                     HERMON_NOSLEEP);
2773         }
2774         if (lstate->hls_rx.hlc_qp_hdl != NULL) {
2775                 (void) hermon_qp_free(lstate->hls_state,
2776                     &lstate->hls_rx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2777                     HERMON_NOSLEEP);
2778         }
2779         lstate->hls_tx.hlc_qp_hdl = NULL;
2780         lstate->hls_rx.hlc_qp_hdl = NULL;
2781         for (i = 0; i < 2; i++) {
2782                 if (lstate->hls_tx.hlc_cqhdl[i] != NULL) {
2783                         (void) hermon_cq_free(lstate->hls_state,
2784                             &lstate->hls_tx.hlc_cqhdl[i], HERMON_NOSLEEP);
2785                 }
2786                 if (lstate->hls_rx.hlc_cqhdl[i] != NULL) {
2787                         (void) hermon_cq_free(lstate->hls_state,
2788                             &lstate->hls_rx.hlc_cqhdl[i], HERMON_NOSLEEP);


2810                     HERMON_NOSLEEP);
2811         }
2812         if (lstate->hls_pd_hdl != NULL) {
2813                 (void) hermon_pd_free(lstate->hls_state, &lstate->hls_pd_hdl);
2814         }
2815         if (lstate->hls_tx.hlc_buf != NULL) {
2816                 kmem_free(lstate->hls_tx.hlc_buf, lstate->hls_tx.hlc_buf_sz);
2817         }
2818         if (lstate->hls_rx.hlc_buf != NULL) {
2819                 kmem_free(lstate->hls_rx.hlc_buf, lstate->hls_rx.hlc_buf_sz);
2820         }
2821         bzero(lstate, sizeof (hermon_loopback_state_t));
2822 }
2823 
2824 /*
2825  * hermon_loopback_init
2826  */
2827 static int
2828 hermon_loopback_init(hermon_state_t *state, hermon_loopback_state_t *lstate)
2829 {


2830         lstate->hls_hca_hdl = (ibc_hca_hdl_t)state;
2831         lstate->hls_status  = hermon_pd_alloc(lstate->hls_state,
2832             &lstate->hls_pd_hdl, HERMON_NOSLEEP);
2833         if (lstate->hls_status != IBT_SUCCESS) {
2834                 lstate->hls_err = HERMON_LOOPBACK_PROT_DOMAIN_ALLOC_FAIL;
2835                 return (EFAULT);
2836         }
2837 
2838         return (0);
2839 }
2840 
2841 /*
2842  * hermon_loopback_init_qp_info
2843  */
2844 static void
2845 hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
2846     hermon_loopback_comm_t *comm)
2847 {
2848         bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2849         bzero(&comm->hlc_qp_attr, sizeof (ibt_qp_alloc_attr_t));


2872         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_send_grh = 0;
2873         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid =
2874             lstate->hls_lid;
2875         comm->hlc_qp_info.qp_transport.rc.rc_retry_cnt = lstate->hls_retry;
2876         comm->hlc_qp_info.qp_transport.rc.rc_sq_psn = 0;
2877         comm->hlc_qp_info.qp_transport.rc.rc_rq_psn = 0;
2878         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_in       = 4;
2879         comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_out = 4;
2880         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = 0;
2881         comm->hlc_qp_info.qp_transport.rc.rc_min_rnr_nak = IBT_RNR_NAK_655ms;
2882         comm->hlc_qp_info.qp_transport.rc.rc_path_mtu = IB_MTU_1K;
2883 }
2884 
2885 /*
2886  * hermon_loopback_alloc_mem
2887  */
2888 static int
2889 hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
2890     hermon_loopback_comm_t *comm, int sz)
2891 {


2892         /* Allocate buffer of specified size */
2893         comm->hlc_buf_sz = sz;
2894         comm->hlc_buf         = kmem_zalloc(sz, KM_NOSLEEP);
2895         if (comm->hlc_buf == NULL) {
2896                 return (EFAULT);
2897         }
2898 
2899         /* Register the buffer as a memory region */
2900         comm->hlc_memattr.mr_vaddr = (uint64_t)(uintptr_t)comm->hlc_buf;
2901         comm->hlc_memattr.mr_len   = (ib_msglen_t)sz;
2902         comm->hlc_memattr.mr_as         = NULL;
2903         comm->hlc_memattr.mr_flags = IBT_MR_NOSLEEP |
2904             IBT_MR_ENABLE_REMOTE_WRITE | IBT_MR_ENABLE_LOCAL_WRITE;
2905 
2906         comm->hlc_status = hermon_mr_register(lstate->hls_state,
2907             lstate->hls_pd_hdl, &comm->hlc_memattr, &comm->hlc_mrhdl,
2908             NULL, HERMON_MPT_DMPT);
2909 


2910         comm->hlc_mrdesc.md_vaddr  = comm->hlc_mrhdl->mr_bindinfo.bi_addr;
2911         comm->hlc_mrdesc.md_lkey   = comm->hlc_mrhdl->mr_lkey;
2912         comm->hlc_mrdesc.md_rkey   = comm->hlc_mrhdl->mr_rkey;
2913         if (comm->hlc_status != IBT_SUCCESS) {
2914                 return (EFAULT);
2915         }
2916         return (0);
2917 }
2918 
2919 /*
2920  * hermon_loopback_alloc_qps
2921  */
2922 static int
2923 hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
2924     hermon_loopback_comm_t *comm)
2925 {
2926         uint32_t                i, real_size;
2927         hermon_qp_info_t                qpinfo;
2928 



2929         /* Allocate send and recv CQs */
2930         for (i = 0; i < 2; i++) {
2931                 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2932                 comm->hlc_cq_attr.cq_size = 128;
2933                 comm->hlc_status = hermon_cq_alloc(lstate->hls_state,
2934                     (ibt_cq_hdl_t)NULL, &comm->hlc_cq_attr, &real_size,
2935                     &comm->hlc_cqhdl[i], HERMON_NOSLEEP);
2936                 if (comm->hlc_status != IBT_SUCCESS) {
2937                         lstate->hls_err += i;
2938                         return (EFAULT);
2939                 }
2940         }
2941 
2942         /* Allocate the QP */
2943         hermon_loopback_init_qp_info(lstate, comm);
2944         comm->hlc_qp_attr.qp_pd_hdl   = (ibt_pd_hdl_t)lstate->hls_pd_hdl;
2945         comm->hlc_qp_attr.qp_scq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[0];
2946         comm->hlc_qp_attr.qp_rcq_hdl  = (ibt_cq_hdl_t)comm->hlc_cqhdl[1];
2947         comm->hlc_qp_attr.qp_ibc_scq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[0];
2948         comm->hlc_qp_attr.qp_ibc_rcq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[1];


2954         comm->hlc_status = hermon_qp_alloc(lstate->hls_state, &qpinfo,
2955             HERMON_NOSLEEP);
2956         if (comm->hlc_status == DDI_SUCCESS) {
2957                 comm->hlc_qp_hdl = qpinfo.qpi_qphdl;
2958         }
2959 
2960         if (comm->hlc_status != IBT_SUCCESS) {
2961                 lstate->hls_err += 2;
2962                 return (EFAULT);
2963         }
2964         return (0);
2965 }
2966 
2967 /*
2968  * hermon_loopback_modify_qp
2969  */
2970 static int
2971 hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
2972     hermon_loopback_comm_t *comm, uint_t qp_num)
2973 {



2974         /* Modify QP to INIT */
2975         hermon_loopback_init_qp_info(lstate, comm);
2976         comm->hlc_qp_info.qp_state = IBT_STATE_INIT;
2977         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2978             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2979         if (comm->hlc_status != IBT_SUCCESS) {
2980                 return (EFAULT);
2981         }
2982 
2983         /*
2984          * Modify QP to RTR (set destination LID and QP number to local
2985          * LID and QP number)
2986          */
2987         comm->hlc_qp_info.qp_state = IBT_STATE_RTR;
2988         comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid
2989             = lstate->hls_lid;
2990         comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = qp_num;
2991         comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2992             IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2993         if (comm->hlc_status != IBT_SUCCESS) {


3035                         return (EFAULT);
3036                 }
3037         } else
3038 #endif /* _MULTI_DATAMODEL */
3039         if (ddi_copyout(lb, (void *)arg, sizeof (hermon_loopback_ioctl_t),
3040             mode) != 0) {
3041                 return (EFAULT);
3042         }
3043         return (0);
3044 }
3045 
3046 /*
3047  * hermon_loopback_post_send
3048  */
3049 static int
3050 hermon_loopback_post_send(hermon_loopback_state_t *lstate,
3051     hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx)
3052 {
3053         int      ret;
3054 


3055         bzero(&tx->hlc_sgl, sizeof (ibt_wr_ds_t));
3056         bzero(&tx->hlc_wr, sizeof (ibt_send_wr_t));
3057 
3058         /* Initialize local address for TX buffer */
3059         tx->hlc_sgl.ds_va   = tx->hlc_mrdesc.md_vaddr;
3060         tx->hlc_sgl.ds_key  = tx->hlc_mrdesc.md_lkey;
3061         tx->hlc_sgl.ds_len  = tx->hlc_buf_sz;
3062 
3063         /* Initialize the remaining details of the work request */
3064         tx->hlc_wr.wr_id = tx->hlc_wrid++;
3065         tx->hlc_wr.wr_flags  = IBT_WR_SEND_SIGNAL;
3066         tx->hlc_wr.wr_nds    = 1;
3067         tx->hlc_wr.wr_sgl    = &tx->hlc_sgl;
3068         tx->hlc_wr.wr_opcode = IBT_WRC_RDMAW;
3069         tx->hlc_wr.wr_trans  = IBT_RC_SRV;
3070 
3071         /* Initialize the remote address for RX buffer */
3072         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_raddr = rx->hlc_mrdesc.md_vaddr;
3073         tx->hlc_wr.wr.rc.rcwr.rdma.rdma_rkey  = rx->hlc_mrdesc.md_rkey;
3074         tx->hlc_complete = 0;
3075         ret = hermon_post_send(lstate->hls_state, tx->hlc_qp_hdl, &tx->hlc_wr,
3076             1, NULL);
3077         if (ret != IBT_SUCCESS) {
3078                 return (EFAULT);
3079         }
3080         return (0);
3081 }
3082 
3083 /*
3084  * hermon_loopback_poll_cq
3085  */
3086 static int
3087 hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
3088     hermon_loopback_comm_t *comm)
3089 {


3090         comm->hlc_wc.wc_status       = 0;
3091         comm->hlc_num_polled = 0;
3092         comm->hlc_status = hermon_cq_poll(lstate->hls_state,
3093             comm->hlc_cqhdl[0], &comm->hlc_wc, 1, &comm->hlc_num_polled);
3094         if ((comm->hlc_status == IBT_SUCCESS) &&
3095             (comm->hlc_wc.wc_status != IBT_WC_SUCCESS)) {
3096                 comm->hlc_status = ibc_get_ci_failure(0);
3097         }
3098         return (comm->hlc_status);
3099 }