Home | History | Annotate | Download | only in hxge
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 #include	<hxge_impl.h>
     29 #include	<hpi_vmac.h>
     30 #include	<hpi_rxdma.h>
     31 
     32 /*
     33  * System interrupt registers that are under function zero management.
     34  */
     35 hxge_status_t
     36 hxge_fzc_intr_init(p_hxge_t hxgep)
     37 {
     38 	hxge_status_t	status = HXGE_OK;
     39 
     40 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_init"));
     41 
     42 	/* Configure the initial timer resolution */
     43 	if ((status = hxge_fzc_intr_tmres_set(hxgep)) != HXGE_OK) {
     44 		return (status);
     45 	}
     46 
     47 	/*
     48 	 * Set up the logical device group's logical devices that
     49 	 * the group owns.
     50 	 */
     51 	if ((status = hxge_fzc_intr_ldg_num_set(hxgep)) != HXGE_OK) {
     52 		return (status);
     53 	}
     54 
     55 	/* Configure the system interrupt data */
     56 	if ((status = hxge_fzc_intr_sid_set(hxgep)) != HXGE_OK) {
     57 		return (status);
     58 	}
     59 
     60 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_init"));
     61 
     62 	return (status);
     63 }
     64 
     65 hxge_status_t
     66 hxge_fzc_intr_ldg_num_set(p_hxge_t hxgep)
     67 {
     68 	p_hxge_ldg_t	ldgp;
     69 	p_hxge_ldv_t	ldvp;
     70 	hpi_handle_t	handle;
     71 	int		i, j;
     72 	hpi_status_t	rs = HPI_SUCCESS;
     73 
     74 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_ldg_num_set"));
     75 
     76 	if (hxgep->ldgvp == NULL) {
     77 		return (HXGE_ERROR);
     78 	}
     79 
     80 	ldgp = hxgep->ldgvp->ldgp;
     81 	ldvp = hxgep->ldgvp->ldvp;
     82 	if (ldgp == NULL || ldvp == NULL) {
     83 		return (HXGE_ERROR);
     84 	}
     85 
     86 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
     87 
     88 	for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) {
     89 		HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_ldg_num_set "
     90 		    "<== hxge_f(Hydra): # ldv %d in group %d", ldgp->nldvs,
     91 		    ldgp->ldg));
     92 
     93 		for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
     94 			rs = hpi_fzc_ldg_num_set(handle, ldvp->ldv,
     95 			    ldvp->ldg_assigned);
     96 			if (rs != HPI_SUCCESS) {
     97 				HXGE_DEBUG_MSG((hxgep, INT_CTL,
     98 				    "<== hxge_fzc_intr_ldg_num_set failed "
     99 				    " rs 0x%x ldv %d ldg %d",
    100 				    rs, ldvp->ldv, ldvp->ldg_assigned));
    101 				return (HXGE_ERROR | rs);
    102 			}
    103 			HXGE_DEBUG_MSG((hxgep, INT_CTL,
    104 			    "<== hxge_fzc_intr_ldg_num_set OK ldv %d ldg %d",
    105 			    ldvp->ldv, ldvp->ldg_assigned));
    106 		}
    107 	}
    108 
    109 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_ldg_num_set"));
    110 	return (HXGE_OK);
    111 }
    112 
    113 hxge_status_t
    114 hxge_fzc_intr_tmres_set(p_hxge_t hxgep)
    115 {
    116 	hpi_handle_t	handle;
    117 	hpi_status_t	rs = HPI_SUCCESS;
    118 
    119 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_tmrese_set"));
    120 	if (hxgep->ldgvp == NULL) {
    121 		return (HXGE_ERROR);
    122 	}
    123 
    124 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
    125 	if ((rs = hpi_fzc_ldg_timer_res_set(handle, hxgep->ldgvp->tmres))) {
    126 		return (HXGE_ERROR | rs);
    127 	}
    128 
    129 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_tmrese_set"));
    130 	return (HXGE_OK);
    131 }
    132 
    133 hxge_status_t
    134 hxge_fzc_intr_sid_set(p_hxge_t hxgep)
    135 {
    136 	hpi_handle_t	handle;
    137 	p_hxge_ldg_t	ldgp;
    138 	fzc_sid_t	sid;
    139 	int		i;
    140 	hpi_status_t	rs = HPI_SUCCESS;
    141 
    142 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_sid_set"));
    143 	if (hxgep->ldgvp == NULL) {
    144 		HXGE_DEBUG_MSG((hxgep, INT_CTL,
    145 		    "<== hxge_fzc_intr_sid_set: no ldg"));
    146 		return (HXGE_ERROR);
    147 	}
    148 
    149 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
    150 	ldgp = hxgep->ldgvp->ldgp;
    151 	HXGE_DEBUG_MSG((hxgep, INT_CTL,
    152 	    "==> hxge_fzc_intr_sid_set: #int %d", hxgep->ldgvp->ldg_intrs));
    153 	for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) {
    154 		sid.ldg = ldgp->ldg;
    155 		sid.vector = ldgp->vector;
    156 		HXGE_DEBUG_MSG((hxgep, INT_CTL,
    157 		    "==> hxge_fzc_intr_sid_set(%d): group %d vector %d",
    158 		    i, sid.ldg, sid.vector));
    159 		rs = hpi_fzc_sid_set(handle, sid);
    160 		if (rs != HPI_SUCCESS) {
    161 			HXGE_DEBUG_MSG((hxgep, INT_CTL,
    162 			    "<== hxge_fzc_intr_sid_set:failed 0x%x", rs));
    163 			return (HXGE_ERROR | rs);
    164 		}
    165 	}
    166 
    167 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_sid_set"));
    168 	return (HXGE_OK);
    169 }
    170 
    171 /*
    172  * Receive DMA registers that are under function zero management.
    173  */
    174 /*ARGSUSED*/
    175 hxge_status_t
    176 hxge_init_fzc_rxdma_channel(p_hxge_t hxgep, uint16_t channel,
    177 	p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p)
    178 {
    179 	hxge_status_t status = HXGE_OK;
    180 
    181 	HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_init_fzc_rxdma_channel"));
    182 
    183 	/* Initialize the RXDMA logical pages */
    184 	status = hxge_init_fzc_rxdma_channel_pages(hxgep, channel, rbr_p);
    185 	if (status != HXGE_OK)
    186 		return (status);
    187 
    188 	HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_init_fzc_rxdma_channel"));
    189 	return (status);
    190 }
    191 
    192 /*ARGSUSED*/
    193 hxge_status_t
    194 hxge_init_fzc_rxdma_channel_pages(p_hxge_t hxgep,
    195 	uint16_t channel, p_rx_rbr_ring_t rbrp)
    196 {
    197 	hpi_handle_t handle;
    198 	hpi_status_t rs = HPI_SUCCESS;
    199 
    200 	HXGE_DEBUG_MSG((hxgep, DMA_CTL,
    201 	    "==> hxge_init_fzc_rxdma_channel_pages"));
    202 
    203 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
    204 
    205 	/* Initialize the page handle */
    206 	rs = hpi_rxdma_cfg_logical_page_handle(handle, channel,
    207 	    rbrp->page_hdl.bits.handle);
    208 	if (rs != HPI_SUCCESS)
    209 		return (HXGE_ERROR | rs);
    210 
    211 	HXGE_DEBUG_MSG((hxgep, DMA_CTL,
    212 	    "<== hxge_init_fzc_rxdma_channel_pages"));
    213 	return (HXGE_OK);
    214 }
    215 
    216 /*ARGSUSED*/
    217 hxge_status_t
    218 hxge_init_fzc_txdma_channel(p_hxge_t hxgep, uint16_t channel,
    219 	p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p)
    220 {
    221 	hxge_status_t status = HXGE_OK;
    222 
    223 	HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_txdma_channel"));
    224 
    225 	/* Initialize the TXDMA logical pages */
    226 	(void) hxge_init_fzc_txdma_channel_pages(hxgep, channel, tx_ring_p);
    227 
    228 	HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_init_fzc_txdma_channel"));
    229 	return (status);
    230 }
    231 
    232 hxge_status_t
    233 hxge_init_fzc_rx_common(p_hxge_t hxgep)
    234 {
    235 	hpi_handle_t	handle;
    236 	hpi_status_t	rs = HPI_SUCCESS;
    237 	hxge_status_t	status = HXGE_OK;
    238 
    239 	HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_rx_common"));
    240 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
    241 
    242 	/*
    243 	 * Configure the rxdma clock divider
    244 	 * This is the granularity counter based on
    245 	 * the hardware system clock (i.e. 300 Mhz) and
    246 	 * it is running around 3 nanoseconds.
    247 	 * So, set the clock divider counter to 1000 to get
    248 	 * microsecond granularity.
    249 	 * For example, for a 3 microsecond timeout, the timeout
    250 	 * will be set to 1.
    251 	 */
    252 	rs = hpi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT);
    253 	if (rs != HPI_SUCCESS)
    254 		return (HXGE_ERROR | rs);
    255 
    256 	HXGE_DEBUG_MSG((hxgep, DMA_CTL,
    257 	    "<== hxge_init_fzc_rx_common:status 0x%08x", status));
    258 	return (status);
    259 }
    260 
    261 hxge_status_t
    262 hxge_init_fzc_txdma_channel_pages(p_hxge_t hxgep, uint16_t channel,
    263 	p_tx_ring_t tx_ring_p)
    264 {
    265 	hpi_handle_t		handle;
    266 	hpi_status_t		rs = HPI_SUCCESS;
    267 
    268 	HXGE_DEBUG_MSG((hxgep, DMA_CTL,
    269 	    "==> hxge_init_fzc_txdma_channel_pages"));
    270 
    271 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
    272 
    273 	/* Initialize the page handle */
    274 	rs = hpi_txdma_log_page_handle_set(handle, channel,
    275 	    &tx_ring_p->page_hdl);
    276 
    277 	if (rs == HPI_SUCCESS)
    278 		return (HXGE_OK);
    279 	else
    280 		return (HXGE_ERROR | rs);
    281 }
    282 
    283 hxge_status_t
    284 hxge_fzc_sys_err_mask_set(p_hxge_t hxgep, boolean_t mask)
    285 {
    286 	hpi_status_t	rs = HPI_SUCCESS;
    287 	hpi_handle_t	handle;
    288 
    289 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
    290 	rs = hpi_fzc_sys_err_mask_set(handle, mask);
    291 	if (rs == HPI_SUCCESS)
    292 		return (HXGE_OK);
    293 	else
    294 		return (HXGE_ERROR | rs);
    295 }
    296