xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_fzc.c (revision 11304:3092d1e303d6)
13859Sml29623 /*
23859Sml29623  * CDDL HEADER START
33859Sml29623  *
43859Sml29623  * The contents of this file are subject to the terms of the
53859Sml29623  * Common Development and Distribution License (the "License").
63859Sml29623  * You may not use this file except in compliance with the License.
73859Sml29623  *
83859Sml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623  * or http://www.opensolaris.org/os/licensing.
103859Sml29623  * See the License for the specific language governing permissions
113859Sml29623  * and limitations under the License.
123859Sml29623  *
133859Sml29623  * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623  * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623  * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623  *
193859Sml29623  * CDDL HEADER END
203859Sml29623  */
219047SMichael.Speer@Sun.COM 
223859Sml29623 /*
239047SMichael.Speer@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
243859Sml29623  * Use is subject to license terms.
253859Sml29623  */
263859Sml29623 
273859Sml29623 #include	<nxge_impl.h>
283859Sml29623 #include	<npi_mac.h>
293859Sml29623 #include	<npi_rxdma.h>
306495Sspeer #include	<nxge_hio.h>
313859Sml29623 
323859Sml29623 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
333859Sml29623 static int	nxge_herr2kerr(uint64_t);
34*11304SJanie.Lu@Sun.COM static uint64_t nxge_init_hv_fzc_lp_op(p_nxge_t, uint64_t,
35*11304SJanie.Lu@Sun.COM     uint64_t, uint64_t, uint64_t, uint64_t);
363859Sml29623 #endif
373859Sml29623 
386495Sspeer static nxge_status_t nxge_init_fzc_rdc_pages(p_nxge_t,
396495Sspeer     uint16_t, dma_log_page_t *, dma_log_page_t *);
406495Sspeer 
416495Sspeer static nxge_status_t nxge_init_fzc_tdc_pages(p_nxge_t,
426495Sspeer     uint16_t, dma_log_page_t *, dma_log_page_t *);
436495Sspeer 
443859Sml29623 /*
453859Sml29623  * The following interfaces are controlled by the
463859Sml29623  * function control registers. Some global registers
473859Sml29623  * are to be initialized by only byt one of the 2/4 functions.
483859Sml29623  * Use the test and set register.
493859Sml29623  */
503859Sml29623 /*ARGSUSED*/
513859Sml29623 nxge_status_t
nxge_test_and_set(p_nxge_t nxgep,uint8_t tas)523859Sml29623 nxge_test_and_set(p_nxge_t nxgep, uint8_t tas)
533859Sml29623 {
543859Sml29623 	npi_handle_t		handle;
553859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
563859Sml29623 
573859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
583859Sml29623 	if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas))
596929Smisaki 	    != NPI_SUCCESS) {
603859Sml29623 		return (NXGE_ERROR | rs);
613859Sml29623 	}
623859Sml29623 
633859Sml29623 	return (NXGE_OK);
643859Sml29623 }
653859Sml29623 
663859Sml29623 nxge_status_t
nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep,boolean_t mpc)673859Sml29623 nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc)
683859Sml29623 {
693859Sml29623 	npi_handle_t		handle;
703859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
713859Sml29623 
723859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl"));
733859Sml29623 
743859Sml29623 	/*
753859Sml29623 	 * In multi-partitioning, the partition manager
763859Sml29623 	 * who owns function zero should set this multi-partition
773859Sml29623 	 * control bit.
783859Sml29623 	 */
793859Sml29623 	if (nxgep->use_partition && nxgep->function_num) {
803859Sml29623 		return (NXGE_ERROR);
813859Sml29623 	}
823859Sml29623 
833859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
843859Sml29623 	if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) {
853859Sml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
866929Smisaki 		    "<== nxge_set_fzc_multi_part_ctl"));
873859Sml29623 		return (NXGE_ERROR | rs);
883859Sml29623 	}
893859Sml29623 
903859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl"));
913859Sml29623 
923859Sml29623 	return (NXGE_OK);
933859Sml29623 }
943859Sml29623 
953859Sml29623 nxge_status_t
nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep,boolean_t * mpc_p)963859Sml29623 nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p)
973859Sml29623 {
983859Sml29623 	npi_handle_t		handle;
993859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
1003859Sml29623 
1013859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
1023859Sml29623 
1033859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
1043859Sml29623 	if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) {
1053859Sml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1066929Smisaki 		    "<== nxge_set_fzc_multi_part_ctl"));
1073859Sml29623 		return (NXGE_ERROR | rs);
1083859Sml29623 	}
1093859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
1103859Sml29623 
1113859Sml29623 	return (NXGE_OK);
1123859Sml29623 }
1133859Sml29623 
1143859Sml29623 /*
1153859Sml29623  * System interrupt registers that are under function zero
1163859Sml29623  * management.
1173859Sml29623  */
1183859Sml29623 nxge_status_t
nxge_fzc_intr_init(p_nxge_t nxgep)1193859Sml29623 nxge_fzc_intr_init(p_nxge_t nxgep)
1203859Sml29623 {
1213859Sml29623 	nxge_status_t	status = NXGE_OK;
1223859Sml29623 
1233859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init"));
1243859Sml29623 
1253859Sml29623 	/* Configure the initial timer resolution */
1263859Sml29623 	if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) {
1273859Sml29623 		return (status);
1283859Sml29623 	}
1293859Sml29623 
1304977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
1313859Sml29623 		/*
1323859Sml29623 		 * Set up the logical device group's logical devices that
1333859Sml29623 		 * the group owns.
1343859Sml29623 		 */
1354732Sdavemq 		if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK)
1364732Sdavemq 			goto fzc_intr_init_exit;
1373859Sml29623 
1383859Sml29623 		/* Configure the system interrupt data */
1394732Sdavemq 		if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK)
1404732Sdavemq 			goto fzc_intr_init_exit;
1414732Sdavemq 	}
1423859Sml29623 
1434732Sdavemq fzc_intr_init_exit:
1443859Sml29623 
1453859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init"));
1463859Sml29623 
1473859Sml29623 	return (status);
1483859Sml29623 }
1493859Sml29623 
1503859Sml29623 nxge_status_t
nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)1513859Sml29623 nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)
1523859Sml29623 {
1533859Sml29623 	p_nxge_ldg_t	ldgp;
1543859Sml29623 	p_nxge_ldv_t	ldvp;
1553859Sml29623 	npi_handle_t	handle;
1563859Sml29623 	int		i, j;
1573859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
1583859Sml29623 
1593859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set"));
1603859Sml29623 
1613859Sml29623 	if (nxgep->ldgvp == NULL) {
1623859Sml29623 		return (NXGE_ERROR);
1633859Sml29623 	}
1643859Sml29623 
1653859Sml29623 	ldgp = nxgep->ldgvp->ldgp;
1663859Sml29623 	ldvp = nxgep->ldgvp->ldvp;
1673859Sml29623 	if (ldgp == NULL || ldvp == NULL) {
1683859Sml29623 		return (NXGE_ERROR);
1693859Sml29623 	}
1703859Sml29623 
1713859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
1723859Sml29623 
1733859Sml29623 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
1743859Sml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
1756929Smisaki 		    "==> nxge_fzc_intr_ldg_num_set "
1766929Smisaki 		    "<== nxge_f(Neptune): # ldv %d "
1776929Smisaki 		    "in group %d", ldgp->nldvs, ldgp->ldg));
1783859Sml29623 
1793859Sml29623 		for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
1803859Sml29623 			rs = npi_fzc_ldg_num_set(handle, ldvp->ldv,
1816929Smisaki 			    ldvp->ldg_assigned);
1823859Sml29623 			if (rs != NPI_SUCCESS) {
1833859Sml29623 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
1846929Smisaki 				    "<== nxge_fzc_intr_ldg_num_set failed "
1856929Smisaki 				    " rs 0x%x ldv %d ldg %d",
1866929Smisaki 				    rs, ldvp->ldv, ldvp->ldg_assigned));
1873859Sml29623 				return (NXGE_ERROR | rs);
1883859Sml29623 			}
1893859Sml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
1906929Smisaki 			    "<== nxge_fzc_intr_ldg_num_set OK "
1916929Smisaki 			    " ldv %d ldg %d",
1926929Smisaki 			    ldvp->ldv, ldvp->ldg_assigned));
1933859Sml29623 		}
1943859Sml29623 	}
1953859Sml29623 
1963859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set"));
1973859Sml29623 
1983859Sml29623 	return (NXGE_OK);
1993859Sml29623 }
2003859Sml29623 
2013859Sml29623 nxge_status_t
nxge_fzc_intr_tmres_set(p_nxge_t nxgep)2023859Sml29623 nxge_fzc_intr_tmres_set(p_nxge_t nxgep)
2033859Sml29623 {
2043859Sml29623 	npi_handle_t	handle;
2053859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
2063859Sml29623 
2073859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set"));
2083859Sml29623 	if (nxgep->ldgvp == NULL) {
2093859Sml29623 		return (NXGE_ERROR);
2103859Sml29623 	}
2113859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
2123859Sml29623 	if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) {
2133859Sml29623 		return (NXGE_ERROR | rs);
2143859Sml29623 	}
2153859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set"));
2163859Sml29623 
2173859Sml29623 	return (NXGE_OK);
2183859Sml29623 }
2193859Sml29623 
2203859Sml29623 nxge_status_t
nxge_fzc_intr_sid_set(p_nxge_t nxgep)2213859Sml29623 nxge_fzc_intr_sid_set(p_nxge_t nxgep)
2223859Sml29623 {
2233859Sml29623 	npi_handle_t	handle;
2243859Sml29623 	p_nxge_ldg_t	ldgp;
2253859Sml29623 	fzc_sid_t	sid;
2263859Sml29623 	int		i;
2273859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
2283859Sml29623 
2293859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set"));
2303859Sml29623 	if (nxgep->ldgvp == NULL) {
2313859Sml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
2326929Smisaki 		    "<== nxge_fzc_intr_sid_set: no ldg"));
2333859Sml29623 		return (NXGE_ERROR);
2343859Sml29623 	}
2353859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
2363859Sml29623 	ldgp = nxgep->ldgvp->ldgp;
2373859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
2386929Smisaki 	    "==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs));
2393859Sml29623 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
2403859Sml29623 		sid.ldg = ldgp->ldg;
2413859Sml29623 		sid.niu = B_FALSE;
2423859Sml29623 		sid.func = ldgp->func;
2433859Sml29623 		sid.vector = ldgp->vector;
2443859Sml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
2456929Smisaki 		    "==> nxge_fzc_intr_sid_set(%d): func %d group %d "
2466929Smisaki 		    "vector %d",
2476929Smisaki 		    i, sid.func, sid.ldg, sid.vector));
2483859Sml29623 		rs = npi_fzc_sid_set(handle, sid);
2493859Sml29623 		if (rs != NPI_SUCCESS) {
2503859Sml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
2516929Smisaki 			    "<== nxge_fzc_intr_sid_set:failed 0x%x",
2526929Smisaki 			    rs));
2533859Sml29623 			return (NXGE_ERROR | rs);
2543859Sml29623 		}
2553859Sml29623 	}
2563859Sml29623 
2573859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set"));
2583859Sml29623 
2593859Sml29623 	return (NXGE_OK);
2603859Sml29623 
2613859Sml29623 }
2623859Sml29623 
2633859Sml29623 /*
2646495Sspeer  * nxge_init_fzc_rdc
2656495Sspeer  *
2666495Sspeer  *	Initialize all of a RDC's FZC_DMC registers.
2676495Sspeer  *	This is executed by the service domain, on behalf of a
2686495Sspeer  *	guest domain, who cannot access these registers.
2696495Sspeer  *
2706495Sspeer  * Arguments:
2716495Sspeer  * 	nxgep
2726495Sspeer  * 	channel		The channel to initialize.
2736495Sspeer  *
2746495Sspeer  * NPI_NXGE function calls:
2756495Sspeer  *	nxge_init_fzc_rdc_pages()
2766495Sspeer  *
2776495Sspeer  * Context:
2786495Sspeer  *	Service Domain
2793859Sml29623  */
2803859Sml29623 /*ARGSUSED*/
2813859Sml29623 nxge_status_t
nxge_init_fzc_rdc(p_nxge_t nxgep,uint16_t channel)2826495Sspeer nxge_init_fzc_rdc(p_nxge_t nxgep, uint16_t channel)
2833859Sml29623 {
2843859Sml29623 	nxge_status_t	status = NXGE_OK;
2856495Sspeer 
2866495Sspeer 	dma_log_page_t	page1, page2;
2876495Sspeer 	npi_handle_t	handle;
2886495Sspeer 	rdc_red_para_t	red;
2896495Sspeer 
2906495Sspeer 	/*
2916495Sspeer 	 * Initialize the RxDMA channel-specific FZC control
2926495Sspeer 	 * registers.
2936495Sspeer 	 */
2946495Sspeer 
2956495Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc"));
2966495Sspeer 
2976495Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
2986495Sspeer 
2996495Sspeer 	/* Reset RXDMA channel */
3006495Sspeer 	status = npi_rxdma_cfg_rdc_reset(handle, channel);
3016495Sspeer 	if (status != NPI_SUCCESS) {
3026495Sspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3036495Sspeer 		    "==> nxge_init_fzc_rdc: npi_rxdma_cfg_rdc_reset(%d) "
3046495Sspeer 		    "returned 0x%08x", channel, status));
3056495Sspeer 		return (NXGE_ERROR | status);
3066495Sspeer 	}
3076495Sspeer 
3086495Sspeer 	/*
3096495Sspeer 	 * These values have been copied from
3106495Sspeer 	 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring().
3116495Sspeer 	 */
3126495Sspeer 	page1.page_num = 0;
3136495Sspeer 	page1.valid = 1;
3146495Sspeer 	page1.func_num = nxgep->function_num;
3156495Sspeer 	page1.mask = 0;
3166495Sspeer 	page1.value = 0;
3176495Sspeer 	page1.reloc = 0;
3186495Sspeer 
3196495Sspeer 	page2.page_num = 1;
3206495Sspeer 	page2.valid = 1;
3216495Sspeer 	page2.func_num = nxgep->function_num;
3226495Sspeer 	page2.mask = 0;
3236495Sspeer 	page2.value = 0;
3246495Sspeer 	page2.reloc = 0;
3256495Sspeer 
3266495Sspeer 	if (nxgep->niu_type == N2_NIU) {
3276495Sspeer #if !defined(NIU_HV_WORKAROUND)
3286495Sspeer 		status = NXGE_OK;
3296495Sspeer #else
3306495Sspeer 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
3316495Sspeer 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
3326495Sspeer 		    "set up logical pages"));
3336495Sspeer 		/* Initialize the RXDMA logical pages */
3346495Sspeer 		status = nxge_init_fzc_rdc_pages(nxgep, channel,
3356495Sspeer 		    &page1, &page2);
3366495Sspeer 		if (status != NXGE_OK) {
3376495Sspeer 			return (status);
3386495Sspeer 		}
3396495Sspeer #endif
3406495Sspeer 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
3416495Sspeer 		/* Initialize the RXDMA logical pages */
3426495Sspeer 		status = nxge_init_fzc_rdc_pages(nxgep, channel,
3436495Sspeer 		    &page1, &page2);
3446495Sspeer 		if (status != NXGE_OK) {
3456495Sspeer 			return (status);
3466495Sspeer 		}
3476495Sspeer 	} else {
3486495Sspeer 		return (NXGE_ERROR);
3496495Sspeer 	}
3506495Sspeer 
3516495Sspeer 	/*
3526495Sspeer 	 * Configure RED parameters
3536495Sspeer 	 */
3546495Sspeer 	red.value = 0;
3556495Sspeer 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
3566495Sspeer 	red.bits.ldw.thre =
3576495Sspeer 	    (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES);
3586495Sspeer 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
3596495Sspeer 	red.bits.ldw.thre_sync =
3606495Sspeer 	    (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES);
3616495Sspeer 
3626495Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
3636929Smisaki 	    "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
3646929Smisaki 	    red.bits.ldw.thre_sync,
3656929Smisaki 	    red.bits.ldw.thre_sync));
3666495Sspeer 
3676495Sspeer 	status |= npi_rxdma_cfg_wred_param(handle, channel, &red);
3686495Sspeer 
3696495Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc"));
3706495Sspeer 
3716495Sspeer 	return (status);
3726495Sspeer }
3736495Sspeer 
3746495Sspeer /*
3756495Sspeer  * nxge_init_fzc_rxdma_channel
3766495Sspeer  *
3776495Sspeer  *	Initialize all per-channel FZC_DMC registers.
3786495Sspeer  *
3796495Sspeer  * Arguments:
3806495Sspeer  * 	nxgep
3816495Sspeer  * 	channel		The channel to start
3826495Sspeer  *
3836495Sspeer  * NPI_NXGE function calls:
3846495Sspeer  *	nxge_init_hv_fzc_rxdma_channel_pages()
3856495Sspeer  *	nxge_init_fzc_rxdma_channel_pages()
3866495Sspeer  *	nxge_init_fzc_rxdma_channel_red()
3876495Sspeer  *
3886495Sspeer  * Context:
3896495Sspeer  *	Service Domain
3906495Sspeer  */
3916495Sspeer /*ARGSUSED*/
3926495Sspeer nxge_status_t
nxge_init_fzc_rxdma_channel(p_nxge_t nxgep,uint16_t channel)3936495Sspeer nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel)
3946495Sspeer {
3956495Sspeer 	rx_rbr_ring_t		*rbr_ring;
3966495Sspeer 	rx_rcr_ring_t		*rcr_ring;
3976495Sspeer 
3986495Sspeer 	nxge_status_t		status = NXGE_OK;
3996495Sspeer 
4003859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel"));
4013859Sml29623 
4026495Sspeer 	rbr_ring = nxgep->rx_rbr_rings->rbr_rings[channel];
4036495Sspeer 	rcr_ring = nxgep->rx_rcr_rings->rcr_rings[channel];
4046495Sspeer 
4054732Sdavemq 	if (nxgep->niu_type == N2_NIU) {
4063859Sml29623 #ifndef	NIU_HV_WORKAROUND
4073859Sml29623 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
4083859Sml29623 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
4094732Sdavemq 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV "
4104732Sdavemq 		    "set up logical pages"));
4113859Sml29623 		/* Initialize the RXDMA logical pages */
4123859Sml29623 		status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel,
4136495Sspeer 		    rbr_ring);
4143859Sml29623 		if (status != NXGE_OK) {
4153859Sml29623 			return (status);
4163859Sml29623 		}
4173859Sml29623 #endif
4184732Sdavemq 		status = NXGE_OK;
4193859Sml29623 #else
4203859Sml29623 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
4214732Sdavemq 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
4224732Sdavemq 		    "set up logical pages"));
4233859Sml29623 		/* Initialize the RXDMA logical pages */
4243859Sml29623 		status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel,
4256495Sspeer 		    rbr_ring);
4263859Sml29623 		if (status != NXGE_OK) {
4273859Sml29623 			return (status);
4283859Sml29623 		}
4293859Sml29623 #endif
4304977Sraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
4314732Sdavemq 		/* Initialize the RXDMA logical pages */
4324732Sdavemq 		status = nxge_init_fzc_rxdma_channel_pages(nxgep,
4336495Sspeer 		    channel, rbr_ring);
4344732Sdavemq 		if (status != NXGE_OK) {
4354732Sdavemq 			return (status);
4364732Sdavemq 		}
4374732Sdavemq 	} else {
4384732Sdavemq 		return (NXGE_ERROR);
4393859Sml29623 	}
4403859Sml29623 
4413859Sml29623 	/* Configure RED parameters */
4426495Sspeer 	status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_ring);
4433859Sml29623 
4443859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel"));
4453859Sml29623 	return (status);
4463859Sml29623 }
4473859Sml29623 
4486495Sspeer /*
4496495Sspeer  * nxge_init_fzc_rdc_pages
4506495Sspeer  *
4516495Sspeer  *	Configure a TDC's logical pages.
4526495Sspeer  *
4536495Sspeer  *	This function is executed by the service domain, on behalf of
4546495Sspeer  *	a guest domain, to whom this RDC has been loaned.
4556495Sspeer  *
4566495Sspeer  * Arguments:
4576495Sspeer  * 	nxgep
4586495Sspeer  * 	channel		The channel to initialize.
4596495Sspeer  * 	page0		Logical page 0 definition.
4606495Sspeer  * 	page1		Logical page 1 definition.
4616495Sspeer  *
4626495Sspeer  * Notes:
4636495Sspeer  *	I think that this function can be called from any
4646495Sspeer  *	domain, but I need to check.
4656495Sspeer  *
4666495Sspeer  * NPI/NXGE function calls:
4676495Sspeer  *	hv_niu_tx_logical_page_conf()
4686495Sspeer  *	hv_niu_tx_logical_page_info()
4696495Sspeer  *
4706495Sspeer  * Context:
4716495Sspeer  *	Any domain
4726495Sspeer  */
4736495Sspeer nxge_status_t
nxge_init_fzc_rdc_pages(p_nxge_t nxgep,uint16_t channel,dma_log_page_t * page0,dma_log_page_t * page1)4746495Sspeer nxge_init_fzc_rdc_pages(
4756495Sspeer 	p_nxge_t nxgep,
4766495Sspeer 	uint16_t channel,
4776495Sspeer 	dma_log_page_t *page0,
4786495Sspeer 	dma_log_page_t *page1)
4796495Sspeer {
4806495Sspeer 	npi_handle_t handle;
4816495Sspeer 	npi_status_t rs;
4826495Sspeer 
4836495Sspeer 	uint64_t page_handle;
4846495Sspeer 
4856495Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
4866929Smisaki 	    "==> nxge_init_fzc_txdma_channel_pages"));
4876495Sspeer 
4886495Sspeer #ifndef	NIU_HV_WORKAROUND
4896495Sspeer 	if (nxgep->niu_type == N2_NIU) {
4906495Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
4916929Smisaki 		    "<== nxge_init_fzc_rdc_pages: "
4926929Smisaki 		    "N2_NIU: no need to set rxdma logical pages"));
4936495Sspeer 		return (NXGE_OK);
4946495Sspeer 	}
4956495Sspeer #else
4966495Sspeer 	if (nxgep->niu_type == N2_NIU) {
4976495Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
4986929Smisaki 		    "<== nxge_init_fzc_rdc_pages: "
4996929Smisaki 		    "N2_NIU: NEED to set rxdma logical pages"));
5006495Sspeer 	}
5016495Sspeer #endif
5026495Sspeer 
5036495Sspeer 	/*
5046495Sspeer 	 * Initialize logical page 1.
5056495Sspeer 	 */
5066495Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5076495Sspeer 	if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page0))
5086495Sspeer 	    != NPI_SUCCESS)
5096495Sspeer 		return (NXGE_ERROR | rs);
5106495Sspeer 
5116495Sspeer 	/*
5126495Sspeer 	 * Initialize logical page 2.
5136495Sspeer 	 */
5146495Sspeer 	if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page1))
5156495Sspeer 	    != NPI_SUCCESS)
5166495Sspeer 		return (NXGE_ERROR | rs);
5176495Sspeer 
5186495Sspeer 	/*
5196495Sspeer 	 * Initialize the page handle.
5206495Sspeer 	 * (In the current driver, this is always set to 0.)
5216495Sspeer 	 */
5226495Sspeer 	page_handle = 0;
5236495Sspeer 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel, page_handle);
5246495Sspeer 	if (rs == NPI_SUCCESS) {
5256495Sspeer 		return (NXGE_OK);
5266495Sspeer 	} else {
5276495Sspeer 		return (NXGE_ERROR | rs);
5286495Sspeer 	}
5296495Sspeer }
5306495Sspeer 
5313859Sml29623 /*ARGSUSED*/
5323859Sml29623 nxge_status_t
nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_rx_rbr_ring_t rbrp)5333859Sml29623 nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,
5343859Sml29623 		uint16_t channel, p_rx_rbr_ring_t rbrp)
5353859Sml29623 {
5363859Sml29623 	npi_handle_t		handle;
5373859Sml29623 	dma_log_page_t		cfg;
5383859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
5393859Sml29623 
5403859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
5416929Smisaki 	    "==> nxge_init_fzc_rxdma_channel_pages"));
5423859Sml29623 
5433859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5443859Sml29623 	/*
5453859Sml29623 	 * Initialize logical page 1.
5463859Sml29623 	 */
5473859Sml29623 	cfg.func_num = nxgep->function_num;
5483859Sml29623 	cfg.page_num = 0;
5493859Sml29623 	cfg.valid = rbrp->page_valid.bits.ldw.page0;
5503859Sml29623 	cfg.value = rbrp->page_value_1.value;
5513859Sml29623 	cfg.mask = rbrp->page_mask_1.value;
5523859Sml29623 	cfg.reloc = rbrp->page_reloc_1.value;
5533859Sml29623 	rs = npi_rxdma_cfg_logical_page(handle, channel,
5546929Smisaki 	    (p_dma_log_page_t)&cfg);
5553859Sml29623 	if (rs != NPI_SUCCESS) {
5563859Sml29623 		return (NXGE_ERROR | rs);
5573859Sml29623 	}
5583859Sml29623 
5593859Sml29623 	/*
5603859Sml29623 	 * Initialize logical page 2.
5613859Sml29623 	 */
5623859Sml29623 	cfg.page_num = 1;
5633859Sml29623 	cfg.valid = rbrp->page_valid.bits.ldw.page1;
5643859Sml29623 	cfg.value = rbrp->page_value_2.value;
5653859Sml29623 	cfg.mask = rbrp->page_mask_2.value;
5663859Sml29623 	cfg.reloc = rbrp->page_reloc_2.value;
5673859Sml29623 
5683859Sml29623 	rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg);
5693859Sml29623 	if (rs != NPI_SUCCESS) {
5703859Sml29623 		return (NXGE_ERROR | rs);
5713859Sml29623 	}
5723859Sml29623 
5733859Sml29623 	/* Initialize the page handle */
5743859Sml29623 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel,
5756929Smisaki 	    rbrp->page_hdl.bits.ldw.handle);
5763859Sml29623 
5773859Sml29623 	if (rs != NPI_SUCCESS) {
5783859Sml29623 		return (NXGE_ERROR | rs);
5793859Sml29623 	}
5803859Sml29623 
5813859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
5826929Smisaki 	    "<== nxge_init_fzc_rxdma_channel_pages"));
5833859Sml29623 
5843859Sml29623 	return (NXGE_OK);
5853859Sml29623 }
5863859Sml29623 
5873859Sml29623 /*ARGSUSED*/
5883859Sml29623 nxge_status_t
nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,uint16_t channel,p_rx_rcr_ring_t rcr_p)5893859Sml29623 nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,
5903859Sml29623 	uint16_t channel, p_rx_rcr_ring_t rcr_p)
5913859Sml29623 {
5923859Sml29623 	npi_handle_t		handle;
5933859Sml29623 	rdc_red_para_t		red;
5943859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
5953859Sml29623 
5963859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red"));
5973859Sml29623 
5983859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5993859Sml29623 	red.value = 0;
6003859Sml29623 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
6013859Sml29623 	red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
6023859Sml29623 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
6033859Sml29623 	red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
6043859Sml29623 
6053859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
6066929Smisaki 	    "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
6076929Smisaki 	    red.bits.ldw.thre_sync,
6086929Smisaki 	    red.bits.ldw.thre_sync));
6093859Sml29623 
6103859Sml29623 	rs = npi_rxdma_cfg_wred_param(handle, channel, &red);
6113859Sml29623 	if (rs != NPI_SUCCESS) {
6123859Sml29623 		return (NXGE_ERROR | rs);
6133859Sml29623 	}
6143859Sml29623 
6153859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
6166929Smisaki 	    "<== nxge_init_fzc_rxdma_channel_red"));
6173859Sml29623 
6183859Sml29623 	return (NXGE_OK);
6193859Sml29623 }
6203859Sml29623 
6216495Sspeer /*
6226495Sspeer  * nxge_init_fzc_tdc
6236495Sspeer  *
6246495Sspeer  *	Initialize all of a TDC's FZC_DMC registers.
6256495Sspeer  *	This is executed by the service domain, on behalf of a
6266495Sspeer  *	guest domain, who cannot access these registers.
6276495Sspeer  *
6286495Sspeer  * Arguments:
6296495Sspeer  * 	nxgep
6306495Sspeer  * 	channel		The channel to initialize.
6316495Sspeer  *
6326495Sspeer  * NPI_NXGE function calls:
6336495Sspeer  *	nxge_init_fzc_tdc_pages()
6346495Sspeer  *	npi_txc_dma_max_burst_set()
6356495Sspeer  *
6366495Sspeer  * Registers accessed:
6376495Sspeer  *	TXC_DMA_MAX_BURST
6386495Sspeer  *
6396495Sspeer  * Context:
6406495Sspeer  *	Service Domain
6416495Sspeer  */
6426495Sspeer /*ARGSUSED*/
6436495Sspeer nxge_status_t
nxge_init_fzc_tdc(p_nxge_t nxgep,uint16_t channel)6446495Sspeer nxge_init_fzc_tdc(p_nxge_t nxgep, uint16_t channel)
6456495Sspeer {
6466495Sspeer 	nxge_status_t	status = NXGE_OK;
6476495Sspeer 
6486495Sspeer 	dma_log_page_t	page1, page2;
6496495Sspeer 	npi_handle_t	handle;
6506495Sspeer 
6516495Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc"));
6526495Sspeer 
6536495Sspeer 	/*
6546495Sspeer 	 * These values have been copied from
6556495Sspeer 	 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring().
6566495Sspeer 	 */
6576495Sspeer 	page1.page_num = 0;
6586495Sspeer 	page1.valid = 1;
6596495Sspeer 	page1.func_num = nxgep->function_num;
6606495Sspeer 	page1.mask = 0;
6616495Sspeer 	page1.value = 0;
6626495Sspeer 	page1.reloc = 0;
6636495Sspeer 
6646495Sspeer 	page1.page_num = 1;
6656495Sspeer 	page1.valid = 1;
6666495Sspeer 	page1.func_num = nxgep->function_num;
6676495Sspeer 	page1.mask = 0;
6686495Sspeer 	page1.value = 0;
6696495Sspeer 	page1.reloc = 0;
6706495Sspeer 
6716495Sspeer #ifdef	NIU_HV_WORKAROUND
6726495Sspeer 	if (nxgep->niu_type == N2_NIU) {
6736495Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
6746495Sspeer 		    "==> nxge_init_fzc_txdma_channel "
6756495Sspeer 		    "N2_NIU: NEED to set up txdma logical pages"));
6766495Sspeer 		/* Initialize the TXDMA logical pages */
6776495Sspeer 		(void) nxge_init_fzc_tdc_pages(nxgep, channel,
6786495Sspeer 		    &page1, &page2);
6796495Sspeer 	}
6806495Sspeer #endif
6816495Sspeer 	if (nxgep->niu_type != N2_NIU) {
6826495Sspeer 		if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6836495Sspeer 			/* Initialize the TXDMA logical pages */
6846495Sspeer 			(void) nxge_init_fzc_tdc_pages(nxgep, channel,
6856495Sspeer 			    &page1, &page2);
6866495Sspeer 		} else
6876495Sspeer 			return (NXGE_ERROR);
6886495Sspeer 	}
6896495Sspeer 
6906495Sspeer 	/*
6916495Sspeer 	 * Configure the TXC DMA Max Burst value.
6926495Sspeer 	 *
6936495Sspeer 	 * PRM.13.5
6946495Sspeer 	 *
6956495Sspeer 	 * TXC DMA Max Burst. TXC_DMA_MAX (FZC_TXC + 0000016)
6966495Sspeer 	 * 19:0		dma_max_burst		RW
6976495Sspeer 	 * Max burst value associated with DMA. Used by DRR engine
6986495Sspeer 	 * for computing when DMA has gone into deficit.
6996495Sspeer 	 */
7006495Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
7016495Sspeer 	(void) npi_txc_dma_max_burst_set(
7026929Smisaki 	    handle, channel, TXC_DMA_MAX_BURST_DEFAULT);
7036495Sspeer 
7046495Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_tdc"));
7056495Sspeer 
7066495Sspeer 	return (status);
7076495Sspeer }
7086495Sspeer 
7093859Sml29623 /*ARGSUSED*/
7103859Sml29623 nxge_status_t
nxge_init_fzc_txdma_channel(p_nxge_t nxgep,uint16_t channel,p_tx_ring_t tx_ring_p,p_tx_mbox_t mbox_p)7113859Sml29623 nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel,
7123859Sml29623 	p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p)
7133859Sml29623 {
7143859Sml29623 	nxge_status_t	status = NXGE_OK;
7153859Sml29623 
7163859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7176929Smisaki 	    "==> nxge_init_fzc_txdma_channel"));
7183859Sml29623 
7194732Sdavemq 	if (nxgep->niu_type == N2_NIU) {
7203859Sml29623 #ifndef	NIU_HV_WORKAROUND
7213859Sml29623 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
7223859Sml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7234732Sdavemq 		    "==> nxge_init_fzc_txdma_channel "
7244732Sdavemq 		    "N2_NIU: call HV to set up txdma logical pages"));
7253859Sml29623 		status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel,
7264732Sdavemq 		    tx_ring_p);
7273859Sml29623 		if (status != NXGE_OK) {
7283859Sml29623 			return (status);
7293859Sml29623 		}
7303859Sml29623 #endif
7314732Sdavemq 		status = NXGE_OK;
7323859Sml29623 #else
7333859Sml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7344732Sdavemq 		    "==> nxge_init_fzc_txdma_channel "
7354732Sdavemq 		    "N2_NIU: NEED to set up txdma logical pages"));
7363859Sml29623 		/* Initialize the TXDMA logical pages */
7373859Sml29623 		(void) nxge_init_fzc_txdma_channel_pages(nxgep, channel,
7384732Sdavemq 		    tx_ring_p);
7393859Sml29623 #endif
7404977Sraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
7414732Sdavemq 		/* Initialize the TXDMA logical pages */
7424732Sdavemq 		(void) nxge_init_fzc_txdma_channel_pages(nxgep,
7434732Sdavemq 		    channel, tx_ring_p);
7444732Sdavemq 	} else {
7454732Sdavemq 		return (NXGE_ERROR);
7463859Sml29623 	}
7473859Sml29623 
7483859Sml29623 	/*
7493859Sml29623 	 * Configure Transmit DRR Weight parameters
7503859Sml29623 	 * (It actually programs the TXC max burst register).
7513859Sml29623 	 */
7523859Sml29623 	(void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p);
7533859Sml29623 
7543859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7556929Smisaki 	    "<== nxge_init_fzc_txdma_channel"));
7563859Sml29623 	return (status);
7573859Sml29623 }
7583859Sml29623 
7593859Sml29623 
7603859Sml29623 nxge_status_t
nxge_init_fzc_rx_common(p_nxge_t nxgep)7613859Sml29623 nxge_init_fzc_rx_common(p_nxge_t nxgep)
7623859Sml29623 {
7633859Sml29623 	npi_handle_t	handle;
7643859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
7653859Sml29623 	nxge_status_t	status = NXGE_OK;
7669047SMichael.Speer@Sun.COM 	nxge_rdc_grp_t	*rdc_grp_p;
7673859Sml29623 	clock_t		lbolt;
7686495Sspeer 	int		table;
7696495Sspeer 
7706495Sspeer 	nxge_hw_pt_cfg_t *hardware;
7713859Sml29623 
7723859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common"));
7733859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
7743859Sml29623 	if (!handle.regp) {
7753859Sml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7766929Smisaki 		    "==> nxge_init_fzc_rx_common null ptr"));
7773859Sml29623 		return (NXGE_ERROR);
7783859Sml29623 	}
7793859Sml29623 
7803859Sml29623 	/*
7813859Sml29623 	 * Configure the rxdma clock divider
7823859Sml29623 	 * This is the granularity counter based on
7833859Sml29623 	 * the hardware system clock (i.e. 300 Mhz) and
7843859Sml29623 	 * it is running around 3 nanoseconds.
7853859Sml29623 	 * So, set the clock divider counter to 1000 to get
7863859Sml29623 	 * microsecond granularity.
7873859Sml29623 	 * For example, for a 3 microsecond timeout, the timeout
7883859Sml29623 	 * will be set to 1.
7893859Sml29623 	 */
7903859Sml29623 	rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT);
7913859Sml29623 	if (rs != NPI_SUCCESS)
7923859Sml29623 		return (NXGE_ERROR | rs);
7933859Sml29623 
7943859Sml29623 #if defined(__i386)
7953859Sml29623 	rs = npi_rxdma_cfg_32bitmode_enable(handle);
7963859Sml29623 	if (rs != NPI_SUCCESS)
7973859Sml29623 		return (NXGE_ERROR | rs);
7983859Sml29623 	rs = npi_txdma_mode32_set(handle, B_TRUE);
7993859Sml29623 	if (rs != NPI_SUCCESS)
8003859Sml29623 		return (NXGE_ERROR | rs);
8013859Sml29623 #endif
8023859Sml29623 
8033859Sml29623 	/*
8043859Sml29623 	 * Enable WRED and program an initial value.
8053859Sml29623 	 * Use time to set the initial random number.
8063859Sml29623 	 */
8073859Sml29623 	(void) drv_getparm(LBOLT, &lbolt);
8083859Sml29623 	rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt);
8093859Sml29623 	if (rs != NPI_SUCCESS)
8103859Sml29623 		return (NXGE_ERROR | rs);
8113859Sml29623 
8126495Sspeer 	hardware = &nxgep->pt_config.hw_config;
8136495Sspeer 	for (table = 0; table < NXGE_MAX_RDC_GRPS; table++) {
8146495Sspeer 		/* Does this table belong to <nxgep>? */
8159047SMichael.Speer@Sun.COM 		if (hardware->grpids[table] == (nxgep->function_num + 256)) {
8169047SMichael.Speer@Sun.COM 			rdc_grp_p = &nxgep->pt_config.rdc_grps[table];
8179047SMichael.Speer@Sun.COM 			status = nxge_init_fzc_rdc_tbl(nxgep, rdc_grp_p, table);
8189047SMichael.Speer@Sun.COM 		}
8196495Sspeer 	}
8203859Sml29623 
8213859Sml29623 	/* Ethernet Timeout Counter (?) */
8223859Sml29623 
8233859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
8246929Smisaki 	    "<== nxge_init_fzc_rx_common:status 0x%08x", status));
8253859Sml29623 
8263859Sml29623 	return (status);
8273859Sml29623 }
8283859Sml29623 
8293859Sml29623 nxge_status_t
nxge_init_fzc_rdc_tbl(p_nxge_t nxge,nxge_rdc_grp_t * group,int rdc_tbl)8309047SMichael.Speer@Sun.COM nxge_init_fzc_rdc_tbl(p_nxge_t nxge, nxge_rdc_grp_t *group, int rdc_tbl)
8313859Sml29623 {
8326495Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
8336495Sspeer 	nx_rdc_tbl_t	*table;
8346495Sspeer 	npi_handle_t	handle;
8356495Sspeer 
8366495Sspeer 	npi_status_t	rs = NPI_SUCCESS;
8376495Sspeer 	nxge_status_t	status = NXGE_OK;
8386495Sspeer 
8396495Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_init_fzc_rdc_tbl(%d)", table));
8406495Sspeer 
8416495Sspeer 	/* This RDC table must have been previously bound to <nxge>. */
8426495Sspeer 	MUTEX_ENTER(&nhd->lock);
8436495Sspeer 	table = &nhd->rdc_tbl[rdc_tbl];
8446495Sspeer 	if (table->nxge != (uintptr_t)nxge) {
8456495Sspeer 		MUTEX_EXIT(&nhd->lock);
8466495Sspeer 		NXGE_ERROR_MSG((nxge, DMA_CTL,
8476495Sspeer 		    "nxge_init_fzc_rdc_tbl(%d): not owner", table));
8486495Sspeer 		return (NXGE_ERROR);
8496495Sspeer 	} else {
8506495Sspeer 		table->map = group->map;
8516495Sspeer 	}
8526495Sspeer 	MUTEX_EXIT(&nhd->lock);
8536495Sspeer 
8546495Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxge);
8556495Sspeer 
8566495Sspeer 	rs = npi_rxdma_rdc_table_config(handle, rdc_tbl,
8576495Sspeer 	    group->map, group->max_rdcs);
8586495Sspeer 
8596495Sspeer 	if (rs != NPI_SUCCESS) {
8606495Sspeer 		status = NXGE_ERROR | rs;
8616495Sspeer 	}
8626495Sspeer 
8636495Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_init_fzc_rdc_tbl(%d)", table));
8646495Sspeer 	return (status);
8656495Sspeer }
8666495Sspeer 
8676495Sspeer static
8686495Sspeer int
rdc_tbl_bind(p_nxge_t nxge,int rdc_tbl)8696495Sspeer rdc_tbl_bind(p_nxge_t nxge, int rdc_tbl)
8706495Sspeer {
8716495Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
8726495Sspeer 	nx_rdc_tbl_t *table;
8736495Sspeer 	int i;
8746495Sspeer 
8756495Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_bind"));
8763859Sml29623 
8776495Sspeer 	MUTEX_ENTER(&nhd->lock);
8786495Sspeer 	/* is the caller asking for a particular table? */
8796495Sspeer 	if (rdc_tbl >= 0 && rdc_tbl < NXGE_MAX_RDC_GROUPS) {
8806495Sspeer 		table = &nhd->rdc_tbl[rdc_tbl];
8816495Sspeer 		if (table->nxge == 0) {
8826495Sspeer 			table->nxge = (uintptr_t)nxge; /* It is now bound. */
8836495Sspeer 			NXGE_DEBUG_MSG((nxge, DMA_CTL,
8846495Sspeer 			    "<== nxge_fzc_rdc_tbl_bind(%d)", rdc_tbl));
8856495Sspeer 			MUTEX_EXIT(&nhd->lock);
8866495Sspeer 			return (rdc_tbl);
8876495Sspeer 		}
8886495Sspeer 	} else {	/* The caller will take any old RDC table. */
8896495Sspeer 		for (i = 0; i < NXGE_MAX_RDC_GROUPS; i++) {
8906495Sspeer 			nx_rdc_tbl_t *table = &nhd->rdc_tbl[i];
8916495Sspeer 			if (table->nxge == 0) {
8926495Sspeer 				table->nxge = (uintptr_t)nxge;
8936495Sspeer 				/* It is now bound. */
8946495Sspeer 				MUTEX_EXIT(&nhd->lock);
8956495Sspeer 				NXGE_DEBUG_MSG((nxge, DMA_CTL,
8966495Sspeer 				    "<== nxge_fzc_rdc_tbl_bind: %d", i));
8976495Sspeer 				return (i);
8986495Sspeer 			}
8996495Sspeer 		}
9006495Sspeer 	}
9016495Sspeer 	MUTEX_EXIT(&nhd->lock);
9023859Sml29623 
9036495Sspeer 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_fzc_rdc_tbl_bind"));
9046495Sspeer 
9056495Sspeer 	return (-EBUSY);	/* RDC tables are bound. */
9066495Sspeer }
9076495Sspeer 
9086495Sspeer int
nxge_fzc_rdc_tbl_bind(nxge_t * nxge,int grp_index,int acceptNoSubstitutes)9096495Sspeer nxge_fzc_rdc_tbl_bind(
9106495Sspeer 	nxge_t *nxge,
9116495Sspeer 	int grp_index,
9126495Sspeer 	int acceptNoSubstitutes)
9136495Sspeer {
9146495Sspeer 	nxge_hw_pt_cfg_t *hardware;
9156495Sspeer 	int index;
9166495Sspeer 
9176495Sspeer 	hardware = &nxge->pt_config.hw_config;
9186495Sspeer 
9196495Sspeer 	if ((index = rdc_tbl_bind(nxge, grp_index)) < 0) {
9206495Sspeer 		if (acceptNoSubstitutes)
9216495Sspeer 			return (index);
9226495Sspeer 		index = rdc_tbl_bind(nxge, grp_index);
9236495Sspeer 		if (index < 0) {
9246495Sspeer 			NXGE_ERROR_MSG((nxge, OBP_CTL,
9256495Sspeer 			    "nxge_fzc_rdc_tbl_init: "
9266495Sspeer 			    "there are no free RDC tables!"));
9276495Sspeer 			return (index);
9283859Sml29623 		}
9293859Sml29623 	}
9303859Sml29623 
9316495Sspeer 	hardware->grpids[index] = nxge->function_num + 256;
9326495Sspeer 
9336495Sspeer 	return (index);
9346495Sspeer }
9356495Sspeer 
9366495Sspeer int
nxge_fzc_rdc_tbl_unbind(p_nxge_t nxge,int rdc_tbl)9376495Sspeer nxge_fzc_rdc_tbl_unbind(p_nxge_t nxge, int rdc_tbl)
9386495Sspeer {
9396495Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
9406495Sspeer 	nx_rdc_tbl_t *table;
9416495Sspeer 
9427976SMichael.Speer@Sun.COM 	if (nhd == NULL)
9437976SMichael.Speer@Sun.COM 		return (0);
9447976SMichael.Speer@Sun.COM 
9456495Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_unbind(%d)",
9466495Sspeer 	    rdc_tbl));
9476495Sspeer 
9488275SEric Cheng 	MUTEX_ENTER(&nhd->lock);
9496495Sspeer 	table = &nhd->rdc_tbl[rdc_tbl];
9506495Sspeer 	if (table->nxge != (uintptr_t)nxge) {
9516495Sspeer 		NXGE_ERROR_MSG((nxge, DMA_CTL,
9526495Sspeer 		    "nxge_fzc_rdc_tbl_unbind(%d): func%d not owner",
9536495Sspeer 		    nxge->function_num, rdc_tbl));
9548275SEric Cheng 		MUTEX_EXIT(&nhd->lock);
9556495Sspeer 		return (EINVAL);
9566495Sspeer 	} else {
9576495Sspeer 		bzero(table, sizeof (*table));
9586495Sspeer 	}
9598275SEric Cheng 	MUTEX_EXIT(&nhd->lock);
9606495Sspeer 
9616495Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_fzc_rdc_tbl_unbind(%d)",
9626495Sspeer 	    rdc_tbl));
9636495Sspeer 
9646495Sspeer 	return (0);
9653859Sml29623 }
9663859Sml29623 
9673859Sml29623 nxge_status_t
nxge_init_fzc_rxdma_port(p_nxge_t nxgep)9683859Sml29623 nxge_init_fzc_rxdma_port(p_nxge_t nxgep)
9693859Sml29623 {
9703859Sml29623 	npi_handle_t		handle;
9713859Sml29623 	p_nxge_dma_pt_cfg_t	p_all_cfgp;
9723859Sml29623 	p_nxge_hw_pt_cfg_t	p_cfgp;
9733859Sml29623 	hostinfo_t 		hostinfo;
9743859Sml29623 	int			i;
9753859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
9763859Sml29623 	p_nxge_class_pt_cfg_t 	p_class_cfgp;
9773859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port"));
9783859Sml29623 
9793859Sml29623 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
9803859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
9813859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
9823859Sml29623 	/*
9833859Sml29623 	 * Initialize the port scheduler DRR weight.
9843859Sml29623 	 * npi_rxdma_cfg_port_ddr_weight();
9853859Sml29623 	 */
9863859Sml29623 
9874977Sraghus 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
9884977Sraghus 	    (nxgep->mac.portmode == PORT_1G_FIBER) ||
9896835Syc148097 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
9904977Sraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
9914977Sraghus 		rs = npi_rxdma_cfg_port_ddr_weight(handle,
9924977Sraghus 		    nxgep->function_num, NXGE_RX_DRR_WT_1G);
9934977Sraghus 		if (rs != NPI_SUCCESS) {
9944977Sraghus 			return (NXGE_ERROR | rs);
9953859Sml29623 		}
9963859Sml29623 	}
9973859Sml29623 
9983859Sml29623 	/* Program the default RDC of a port */
9993859Sml29623 	rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num,
10006495Sspeer 	    p_cfgp->def_rdc);
10013859Sml29623 	if (rs != NPI_SUCCESS) {
10023859Sml29623 		return (NXGE_ERROR | rs);
10033859Sml29623 	}
10043859Sml29623 
10053859Sml29623 	/*
10063859Sml29623 	 * Configure the MAC host info table with RDC tables
10073859Sml29623 	 */
10083859Sml29623 	hostinfo.value = 0;
10093859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10103859Sml29623 	for (i = 0; i < p_cfgp->max_macs; i++) {
10116495Sspeer 		hostinfo.bits.w0.rdc_tbl_num = p_cfgp->def_mac_rxdma_grpid;
10123859Sml29623 		hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref;
10133859Sml29623 		if (p_class_cfgp->mac_host_info[i].flag) {
10143859Sml29623 			hostinfo.bits.w0.rdc_tbl_num =
10156929Smisaki 			    p_class_cfgp->mac_host_info[i].rdctbl;
10163859Sml29623 			hostinfo.bits.w0.mac_pref =
10176929Smisaki 			    p_class_cfgp->mac_host_info[i].mpr_npr;
10183859Sml29623 		}
10193859Sml29623 
10203859Sml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
10216929Smisaki 		    nxgep->function_num, i, &hostinfo);
10223859Sml29623 		if (rs != NPI_SUCCESS)
10233859Sml29623 			return (NXGE_ERROR | rs);
10243859Sml29623 	}
10253859Sml29623 
10263859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
10276929Smisaki 	    "<== nxge_init_fzc_rxdma_port rs 0x%08x", rs));
10283859Sml29623 
10293859Sml29623 	return (NXGE_OK);
10303859Sml29623 
10313859Sml29623 }
10323859Sml29623 
10333859Sml29623 nxge_status_t
nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep,uint8_t port,uint16_t rdc)10343859Sml29623 nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc)
10353859Sml29623 {
10363859Sml29623 	npi_status_t rs = NPI_SUCCESS;
10373859Sml29623 	rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle,
10386929Smisaki 	    port, rdc);
10393859Sml29623 	if (rs & NPI_FAILURE)
10403859Sml29623 		return (NXGE_ERROR | rs);
10413859Sml29623 	return (NXGE_OK);
10423859Sml29623 }
10433859Sml29623 
10446495Sspeer /*
10456495Sspeer  * nxge_init_fzc_tdc_pages
10466495Sspeer  *
10476495Sspeer  *	Configure a TDC's logical pages.
10486495Sspeer  *
10496495Sspeer  *	This function is executed by the service domain, on behalf of
10506495Sspeer  *	a guest domain, to whom this TDC has been loaned.
10516495Sspeer  *
10526495Sspeer  * Arguments:
10536495Sspeer  * 	nxgep
10546495Sspeer  * 	channel		The channel to initialize.
10556495Sspeer  * 	page0		Logical page 0 definition.
10566495Sspeer  * 	page1		Logical page 1 definition.
10576495Sspeer  *
10586495Sspeer  * Notes:
10596495Sspeer  *	I think that this function can be called from any
10606495Sspeer  *	domain, but I need to check.
10616495Sspeer  *
10626495Sspeer  * NPI/NXGE function calls:
10636495Sspeer  *	hv_niu_tx_logical_page_conf()
10646495Sspeer  *	hv_niu_tx_logical_page_info()
10656495Sspeer  *
10666495Sspeer  * Context:
10676495Sspeer  *	Any domain
10686495Sspeer  */
10696495Sspeer nxge_status_t
nxge_init_fzc_tdc_pages(p_nxge_t nxgep,uint16_t channel,dma_log_page_t * page0,dma_log_page_t * page1)10706495Sspeer nxge_init_fzc_tdc_pages(
10716495Sspeer 	p_nxge_t nxgep,
10726495Sspeer 	uint16_t channel,
10736495Sspeer 	dma_log_page_t *page0,
10746495Sspeer 	dma_log_page_t *page1)
10756495Sspeer {
10766495Sspeer 	npi_handle_t handle;
10776495Sspeer 	npi_status_t rs;
10786495Sspeer 
10796495Sspeer 	log_page_hdl_t page_handle;
10806495Sspeer 
10816495Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
10826929Smisaki 	    "==> nxge_init_fzc_txdma_channel_pages"));
10836495Sspeer 
10846495Sspeer #ifndef	NIU_HV_WORKAROUND
10856495Sspeer 	if (nxgep->niu_type == N2_NIU) {
10866495Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
10876929Smisaki 		    "<== nxge_init_fzc_tdc_pages: "
10886929Smisaki 		    "N2_NIU: no need to set txdma logical pages"));
10896495Sspeer 		return (NXGE_OK);
10906495Sspeer 	}
10916495Sspeer #else
10926495Sspeer 	if (nxgep->niu_type == N2_NIU) {
10936495Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
10946929Smisaki 		    "<== nxge_init_fzc_tdc_pages: "
10956929Smisaki 		    "N2_NIU: NEED to set txdma logical pages"));
10966495Sspeer 	}
10976495Sspeer #endif
10986495Sspeer 
10996495Sspeer 	/*
11006495Sspeer 	 * Initialize logical page 1.
11016495Sspeer 	 */
11026495Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
11036495Sspeer 	if ((rs = npi_txdma_log_page_set(handle, channel, page0))
11046495Sspeer 	    != NPI_SUCCESS)
11056495Sspeer 		return (NXGE_ERROR | rs);
11066495Sspeer 
11076495Sspeer 	/*
11086495Sspeer 	 * Initialize logical page 2.
11096495Sspeer 	 */
11106495Sspeer 	if ((rs = npi_txdma_log_page_set(handle, channel, page1))
11116495Sspeer 	    != NPI_SUCCESS)
11126495Sspeer 		return (NXGE_ERROR | rs);
11136495Sspeer 
11146495Sspeer 	/*
11156495Sspeer 	 * Initialize the page handle.
11166495Sspeer 	 * (In the current driver, this is always set to 0.)
11176495Sspeer 	 */
11186495Sspeer 	page_handle.value = 0;
11196495Sspeer 	rs = npi_txdma_log_page_handle_set(handle, channel, &page_handle);
11206495Sspeer 	if (rs == NPI_SUCCESS) {
11216495Sspeer 		return (NXGE_OK);
11226495Sspeer 	} else {
11236495Sspeer 		return (NXGE_ERROR | rs);
11246495Sspeer 	}
11256495Sspeer }
11266495Sspeer 
11273859Sml29623 nxge_status_t
nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_tx_ring_t tx_ring_p)11283859Sml29623 nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
11293859Sml29623 	p_tx_ring_t tx_ring_p)
11303859Sml29623 {
11313859Sml29623 	npi_handle_t		handle;
11323859Sml29623 	dma_log_page_t		cfg;
11333859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
11343859Sml29623 
11353859Sml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
11366929Smisaki 	    "==> nxge_init_fzc_txdma_channel_pages"));
11373859Sml29623 
11383859Sml29623 #ifndef	NIU_HV_WORKAROUND
11393859Sml29623 	if (nxgep->niu_type == N2_NIU) {
11403859Sml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
11416929Smisaki 		    "<== nxge_init_fzc_txdma_channel_pages: "
11426929Smisaki 		    "N2_NIU: no need to set txdma logical pages"));
11433859Sml29623 		return (NXGE_OK);
11443859Sml29623 	}
11453859Sml29623 #else
11463859Sml29623 	if (nxgep->niu_type == N2_NIU) {
11473859Sml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
11486929Smisaki 		    "<== nxge_init_fzc_txdma_channel_pages: "
11496929Smisaki 		    "N2_NIU: NEED to set txdma logical pages"));
11503859Sml29623 	}
11513859Sml29623 #endif
11523859Sml29623 
11533859Sml29623 	/*
11543859Sml29623 	 * Initialize logical page 1.
11553859Sml29623 	 */
11563859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
11573859Sml29623 	cfg.func_num = nxgep->function_num;
11583859Sml29623 	cfg.page_num = 0;
11593859Sml29623 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page0;
11603859Sml29623 	cfg.value = tx_ring_p->page_value_1.value;
11613859Sml29623 	cfg.mask = tx_ring_p->page_mask_1.value;
11623859Sml29623 	cfg.reloc = tx_ring_p->page_reloc_1.value;
11633859Sml29623 
11643859Sml29623 	rs = npi_txdma_log_page_set(handle, channel,
11656929Smisaki 	    (p_dma_log_page_t)&cfg);
11663859Sml29623 	if (rs != NPI_SUCCESS) {
11673859Sml29623 		return (NXGE_ERROR | rs);
11683859Sml29623 	}
11693859Sml29623 
11703859Sml29623 	/*
11713859Sml29623 	 * Initialize logical page 2.
11723859Sml29623 	 */
11733859Sml29623 	cfg.page_num = 1;
11743859Sml29623 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page1;
11753859Sml29623 	cfg.value = tx_ring_p->page_value_2.value;
11763859Sml29623 	cfg.mask = tx_ring_p->page_mask_2.value;
11773859Sml29623 	cfg.reloc = tx_ring_p->page_reloc_2.value;
11783859Sml29623 
11793859Sml29623 	rs = npi_txdma_log_page_set(handle, channel, &cfg);
11803859Sml29623 	if (rs != NPI_SUCCESS) {
11813859Sml29623 		return (NXGE_ERROR | rs);
11823859Sml29623 	}
11833859Sml29623 
11843859Sml29623 	/* Initialize the page handle */
11853859Sml29623 	rs = npi_txdma_log_page_handle_set(handle, channel,
11866929Smisaki 	    &tx_ring_p->page_hdl);
11873859Sml29623 
11883859Sml29623 	if (rs == NPI_SUCCESS) {
11893859Sml29623 		return (NXGE_OK);
11903859Sml29623 	} else {
11913859Sml29623 		return (NXGE_ERROR | rs);
11923859Sml29623 	}
11933859Sml29623 }
11943859Sml29623 
11953859Sml29623 
11963859Sml29623 nxge_status_t
nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep,uint16_t channel,p_tx_ring_t tx_ring_p)11973859Sml29623 nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel,
11983859Sml29623 	p_tx_ring_t tx_ring_p)
11993859Sml29623 {
12003859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
12013859Sml29623 	npi_handle_t	handle;
12023859Sml29623 
12033859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
12043859Sml29623 	rs = npi_txc_dma_max_burst_set(handle, channel,
12056929Smisaki 	    tx_ring_p->max_burst.value);
12063859Sml29623 	if (rs == NPI_SUCCESS) {
12073859Sml29623 		return (NXGE_OK);
12083859Sml29623 	} else {
12093859Sml29623 		return (NXGE_ERROR | rs);
12103859Sml29623 	}
12113859Sml29623 }
12123859Sml29623 
12133859Sml29623 nxge_status_t
nxge_fzc_sys_err_mask_set(p_nxge_t nxgep,uint64_t mask)12143859Sml29623 nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask)
12153859Sml29623 {
12163859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
12173859Sml29623 	npi_handle_t	handle;
12183859Sml29623 
12193859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
12203859Sml29623 	rs = npi_fzc_sys_err_mask_set(handle, mask);
12213859Sml29623 	if (rs == NPI_SUCCESS) {
12223859Sml29623 		return (NXGE_OK);
12233859Sml29623 	} else {
12243859Sml29623 		return (NXGE_ERROR | rs);
12253859Sml29623 	}
12263859Sml29623 }
12273859Sml29623 
12286495Sspeer /*
12296495Sspeer  * nxge_init_hv_fzc_txdma_channel_pages
12306495Sspeer  *
12316495Sspeer  *	Configure a TDC's logical pages.
12326495Sspeer  *
12336495Sspeer  * Arguments:
12346495Sspeer  * 	nxgep
12356495Sspeer  * 	channel		The channel to initialize.
12366495Sspeer  * 	tx_ring_p	The transmit ring.
12376495Sspeer  *
12386495Sspeer  * Notes:
12396495Sspeer  *	I think that this function can be called from any
12406495Sspeer  *	domain, but I need to check.
12416495Sspeer  *
12426495Sspeer  * NPI/NXGE function calls:
12436495Sspeer  *	hv_niu_tx_logical_page_conf()
12446495Sspeer  *	hv_niu_tx_logical_page_info()
12456495Sspeer  *
12466495Sspeer  * Context:
12476495Sspeer  *	Any domain
12486495Sspeer  */
12496495Sspeer #if defined(sun4v) && defined(NIU_LP_WORKAROUND)
12503859Sml29623 nxge_status_t
nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_tx_ring_t tx_ring_p)12513859Sml29623 nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
12523859Sml29623 	p_tx_ring_t tx_ring_p)
12533859Sml29623 {
12543859Sml29623 	int			err;
12553859Sml29623 	uint64_t		hverr;
12563859Sml29623 #ifdef	DEBUG
12573859Sml29623 	uint64_t		ra, size;
12583859Sml29623 #endif
12593859Sml29623 
12603859Sml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
12616929Smisaki 	    "==> nxge_init_hv_fzc_txdma_channel_pages"));
12623859Sml29623 
12633859Sml29623 	if (tx_ring_p->hv_set) {
12643859Sml29623 		return (NXGE_OK);
12653859Sml29623 	}
12663859Sml29623 
12673859Sml29623 	/*
12683859Sml29623 	 * Initialize logical page 1 for data buffers.
12693859Sml29623 	 */
1270*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1271*11304SJanie.Lu@Sun.COM 	    (uint64_t)0, N2NIU_TX_LP_CONF,
12726929Smisaki 	    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
12736929Smisaki 	    tx_ring_p->hv_tx_buf_ioaddr_size);
12743859Sml29623 
12753859Sml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
12763859Sml29623 	if (err != 0) {
12773859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12786929Smisaki 		    "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d "
12796929Smisaki 		    "error status 0x%x "
12806929Smisaki 		    "(page 0 data buf) hverr 0x%llx "
12816929Smisaki 		    "ioaddr_pp $%p "
12826929Smisaki 		    "size 0x%llx ",
12836929Smisaki 		    channel,
12846929Smisaki 		    err,
12856929Smisaki 		    hverr,
12866929Smisaki 		    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
12876929Smisaki 		    tx_ring_p->hv_tx_buf_ioaddr_size));
12883859Sml29623 		return (NXGE_ERROR | err);
12893859Sml29623 	}
12903859Sml29623 
12913859Sml29623 #ifdef	DEBUG
12923859Sml29623 	ra = size = 0;
1293*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1294*11304SJanie.Lu@Sun.COM 	    (uint64_t)0, N2NIU_TX_LP_INFO,
1295*11304SJanie.Lu@Sun.COM 	    (uint64_t)&ra, (uint64_t)&size);
12963859Sml29623 
12973859Sml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
12986929Smisaki 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
12996929Smisaki 	    "ok status 0x%x "
13006929Smisaki 	    "(page 0 data buf) hverr 0x%llx "
13016929Smisaki 	    "set ioaddr_pp $%p "
13026929Smisaki 	    "set size 0x%llx "
13036929Smisaki 	    "get ra ioaddr_pp $%p "
13046929Smisaki 	    "get size 0x%llx ",
13056929Smisaki 	    channel,
13066929Smisaki 	    err,
13076929Smisaki 	    hverr,
13086929Smisaki 	    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
13096929Smisaki 	    tx_ring_p->hv_tx_buf_ioaddr_size,
13106929Smisaki 	    ra,
13116929Smisaki 	    size));
13123859Sml29623 #endif
13133859Sml29623 
13143859Sml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13156929Smisaki 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
13166929Smisaki 	    "(page 0 data buf) hverr 0x%llx "
13176929Smisaki 	    "ioaddr_pp $%p "
13186929Smisaki 	    "size 0x%llx ",
13196929Smisaki 	    channel,
13206929Smisaki 	    hverr,
13216929Smisaki 	    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
13226929Smisaki 	    tx_ring_p->hv_tx_buf_ioaddr_size));
13233859Sml29623 
13243859Sml29623 	/*
13253859Sml29623 	 * Initialize logical page 2 for control buffers.
13263859Sml29623 	 */
1327*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1328*11304SJanie.Lu@Sun.COM 	    (uint64_t)1, N2NIU_TX_LP_CONF,
13296929Smisaki 	    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13306929Smisaki 	    tx_ring_p->hv_tx_cntl_ioaddr_size);
13313859Sml29623 
13323859Sml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
13333859Sml29623 
13343859Sml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13356929Smisaki 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d"
13366929Smisaki 	    "ok status 0x%x "
13376929Smisaki 	    "(page 1 cntl buf) hverr 0x%llx "
13386929Smisaki 	    "ioaddr_pp $%p "
13396929Smisaki 	    "size 0x%llx ",
13406929Smisaki 	    channel,
13416929Smisaki 	    err,
13426929Smisaki 	    hverr,
13436929Smisaki 	    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13446929Smisaki 	    tx_ring_p->hv_tx_cntl_ioaddr_size));
13453859Sml29623 
13463859Sml29623 	if (err != 0) {
13473859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13486929Smisaki 		    "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d"
13496929Smisaki 		    "error status 0x%x "
13506929Smisaki 		    "(page 1 cntl buf) hverr 0x%llx "
13516929Smisaki 		    "ioaddr_pp $%p "
13526929Smisaki 		    "size 0x%llx ",
13536929Smisaki 		    channel,
13546929Smisaki 		    err,
13556929Smisaki 		    hverr,
13566929Smisaki 		    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13576929Smisaki 		    tx_ring_p->hv_tx_cntl_ioaddr_size));
13583859Sml29623 		return (NXGE_ERROR | err);
13593859Sml29623 	}
13603859Sml29623 
13613859Sml29623 #ifdef	DEBUG
13623859Sml29623 	ra = size = 0;
1363*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1364*11304SJanie.Lu@Sun.COM 	    (uint64_t)1, N2NIU_TX_LP_INFO,
1365*11304SJanie.Lu@Sun.COM 	    (uint64_t)&ra, (uint64_t)&size);
13663859Sml29623 
13673859Sml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13686929Smisaki 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
13696929Smisaki 	    "(page 1 cntl buf) hverr 0x%llx "
13706929Smisaki 	    "set ioaddr_pp $%p "
13716929Smisaki 	    "set size 0x%llx "
13726929Smisaki 	    "get ra ioaddr_pp $%p "
13736929Smisaki 	    "get size 0x%llx ",
13746929Smisaki 	    channel,
13756929Smisaki 	    hverr,
13766929Smisaki 	    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13776929Smisaki 	    tx_ring_p->hv_tx_cntl_ioaddr_size,
13786929Smisaki 	    ra,
13796929Smisaki 	    size));
13803859Sml29623 #endif
13813859Sml29623 
13823859Sml29623 	tx_ring_p->hv_set = B_TRUE;
13833859Sml29623 
13843859Sml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13856929Smisaki 	    "<== nxge_init_hv_fzc_txdma_channel_pages"));
13863859Sml29623 
13873859Sml29623 	return (NXGE_OK);
13883859Sml29623 }
13893859Sml29623 
13903859Sml29623 /*ARGSUSED*/
13913859Sml29623 nxge_status_t
nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_rx_rbr_ring_t rbrp)13923859Sml29623 nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep,
13933859Sml29623 		uint16_t channel, p_rx_rbr_ring_t rbrp)
13943859Sml29623 {
13953859Sml29623 	int			err;
13963859Sml29623 	uint64_t		hverr;
13973859Sml29623 #ifdef	DEBUG
13983859Sml29623 	uint64_t		ra, size;
13993859Sml29623 #endif
14003859Sml29623 
14013859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
14026929Smisaki 	    "==> nxge_init_hv_fzc_rxdma_channel_pages"));
14033859Sml29623 
14043859Sml29623 	if (rbrp->hv_set) {
14053859Sml29623 		return (NXGE_OK);
14063859Sml29623 	}
14073859Sml29623 
14083859Sml29623 	/* Initialize data buffers for page 0 */
1409*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1410*11304SJanie.Lu@Sun.COM 	    (uint64_t)0, N2NIU_RX_LP_CONF,
14116929Smisaki 	    rbrp->hv_rx_buf_base_ioaddr_pp,
14126929Smisaki 	    rbrp->hv_rx_buf_ioaddr_size);
1413*11304SJanie.Lu@Sun.COM 
14143859Sml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
14153859Sml29623 	if (err != 0) {
14163859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14176929Smisaki 		    "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
14186929Smisaki 		    "error status 0x%x "
14196929Smisaki 		    "(page 0 data buf) hverr 0x%llx "
14206929Smisaki 		    "ioaddr_pp $%p "
14216929Smisaki 		    "size 0x%llx ",
14226929Smisaki 		    channel,
14236929Smisaki 		    err,
14246929Smisaki 		    hverr,
14256929Smisaki 		    rbrp->hv_rx_buf_base_ioaddr_pp,
14266929Smisaki 		    rbrp->hv_rx_buf_ioaddr_size));
14273859Sml29623 
14283859Sml29623 		return (NXGE_ERROR | err);
14293859Sml29623 	}
14303859Sml29623 
14313859Sml29623 #ifdef	DEBUG
14323859Sml29623 	ra = size = 0;
1433*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1434*11304SJanie.Lu@Sun.COM 	    (uint64_t)0, N2NIU_RX_LP_INFO,
1435*11304SJanie.Lu@Sun.COM 	    (uint64_t)&ra, (uint64_t)&size);
14363859Sml29623 
14373859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
14386929Smisaki 	    "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
14396929Smisaki 	    "ok status 0x%x "
14406929Smisaki 	    "(page 0 data buf) hverr 0x%llx "
14416929Smisaki 	    "set databuf ioaddr_pp $%p "
14426929Smisaki 	    "set databuf size 0x%llx "
14436929Smisaki 	    "get databuf ra ioaddr_pp %p "
14446929Smisaki 	    "get databuf size 0x%llx",
14456929Smisaki 	    channel,
14466929Smisaki 	    err,
14476929Smisaki 	    hverr,
14486929Smisaki 	    rbrp->hv_rx_buf_base_ioaddr_pp,
14496929Smisaki 	    rbrp->hv_rx_buf_ioaddr_size,
14506929Smisaki 	    ra,
14516929Smisaki 	    size));
14523859Sml29623 #endif
14533859Sml29623 
14543859Sml29623 	/* Initialize control buffers for logical page 1.  */
1455*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1456*11304SJanie.Lu@Sun.COM 	    (uint64_t)1, N2NIU_RX_LP_CONF,
14576929Smisaki 	    rbrp->hv_rx_cntl_base_ioaddr_pp,
14586929Smisaki 	    rbrp->hv_rx_cntl_ioaddr_size);
14593859Sml29623 
14603859Sml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
14613859Sml29623 	if (err != 0) {
14623859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14636929Smisaki 		    "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
14646929Smisaki 		    "error status 0x%x "
14656929Smisaki 		    "(page 1 cntl buf) hverr 0x%llx "
14666929Smisaki 		    "ioaddr_pp $%p "
14676929Smisaki 		    "size 0x%llx ",
14686929Smisaki 		    channel,
14696929Smisaki 		    err,
14706929Smisaki 		    hverr,
14716929Smisaki 		    rbrp->hv_rx_buf_base_ioaddr_pp,
14726929Smisaki 		    rbrp->hv_rx_buf_ioaddr_size));
14733859Sml29623 
14743859Sml29623 		return (NXGE_ERROR | err);
14753859Sml29623 	}
14763859Sml29623 
14773859Sml29623 #ifdef	DEBUG
14783859Sml29623 	ra = size = 0;
1479*11304SJanie.Lu@Sun.COM 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1480*11304SJanie.Lu@Sun.COM 	    (uint64_t)1, N2NIU_RX_LP_INFO,
1481*11304SJanie.Lu@Sun.COM 	    (uint64_t)&ra, (uint64_t)&size);
14823859Sml29623 
14833859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
14846929Smisaki 	    "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
14856929Smisaki 	    "error status 0x%x "
14866929Smisaki 	    "(page 1 cntl buf) hverr 0x%llx "
14876929Smisaki 	    "set cntl ioaddr_pp $%p "
14886929Smisaki 	    "set cntl size 0x%llx "
14896929Smisaki 	    "get cntl ioaddr_pp $%p "
14906929Smisaki 	    "get cntl size 0x%llx ",
14916929Smisaki 	    channel,
14926929Smisaki 	    err,
14936929Smisaki 	    hverr,
14946929Smisaki 	    rbrp->hv_rx_cntl_base_ioaddr_pp,
14956929Smisaki 	    rbrp->hv_rx_cntl_ioaddr_size,
14966929Smisaki 	    ra,
14976929Smisaki 	    size));
14983859Sml29623 #endif
14993859Sml29623 
15003859Sml29623 	rbrp->hv_set = B_FALSE;
15013859Sml29623 
15023859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
15036929Smisaki 	    "<== nxge_init_hv_fzc_rxdma_channel_pages"));
15043859Sml29623 
15053859Sml29623 	return (NXGE_OK);
15063859Sml29623 }
15073859Sml29623 
15083859Sml29623 /*
15093859Sml29623  * Map hypervisor error code to errno. Only
15103859Sml29623  * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful
15113859Sml29623  * for niu driver. Any other error codes are mapped to EINVAL.
15123859Sml29623  */
15133859Sml29623 static int
nxge_herr2kerr(uint64_t hv_errcode)15143859Sml29623 nxge_herr2kerr(uint64_t hv_errcode)
15153859Sml29623 {
15163859Sml29623 	int	s_errcode;
15173859Sml29623 
15183859Sml29623 	switch (hv_errcode) {
15193859Sml29623 	case H_ENORADDR:
15203859Sml29623 	case H_EBADALIGN:
15213859Sml29623 		s_errcode = EFAULT;
15223859Sml29623 		break;
15233859Sml29623 	case H_EOK:
15243859Sml29623 		s_errcode = 0;
15253859Sml29623 		break;
15263859Sml29623 	default:
15273859Sml29623 		s_errcode = EINVAL;
15283859Sml29623 		break;
15293859Sml29623 	}
15303859Sml29623 	return (s_errcode);
15313859Sml29623 }
15323859Sml29623 
1533*11304SJanie.Lu@Sun.COM uint64_t
nxge_init_hv_fzc_lp_op(p_nxge_t nxgep,uint64_t channel,uint64_t page_no,uint64_t op_type,uint64_t ioaddr_pp,uint64_t ioaddr_size)1534*11304SJanie.Lu@Sun.COM nxge_init_hv_fzc_lp_op(p_nxge_t nxgep, uint64_t channel,
1535*11304SJanie.Lu@Sun.COM     uint64_t page_no, uint64_t op_type,
1536*11304SJanie.Lu@Sun.COM     uint64_t ioaddr_pp, uint64_t ioaddr_size)
1537*11304SJanie.Lu@Sun.COM {
1538*11304SJanie.Lu@Sun.COM 	uint64_t		hverr;
1539*11304SJanie.Lu@Sun.COM 	uint64_t		major;
1540*11304SJanie.Lu@Sun.COM 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxgep->nxge_hw_p->hio;
1541*11304SJanie.Lu@Sun.COM 	nxhv_dc_fp_t		*io_fp;
1542*11304SJanie.Lu@Sun.COM 
1543*11304SJanie.Lu@Sun.COM 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1544*11304SJanie.Lu@Sun.COM 	    "==> nxge_init_hv_fzc_lp_op"));
1545*11304SJanie.Lu@Sun.COM 
1546*11304SJanie.Lu@Sun.COM 	major = nxgep->niu_hsvc.hsvc_major;
1547*11304SJanie.Lu@Sun.COM 	NXGE_DEBUG_MSG((nxgep, NXGE_ERR_CTL,
1548*11304SJanie.Lu@Sun.COM 	    "==> nxge_init_hv_fzc_lp_op (major %d): channel %d op_type 0x%x "
1549*11304SJanie.Lu@Sun.COM 	    "page_no %d ioaddr_pp $%p ioaddr_size 0x%llx",
1550*11304SJanie.Lu@Sun.COM 	    major, channel, op_type, page_no, ioaddr_pp, ioaddr_size));
1551*11304SJanie.Lu@Sun.COM 
1552*11304SJanie.Lu@Sun.COM 	/* Call the transmit conf function. */
1553*11304SJanie.Lu@Sun.COM 	switch (major) {
1554*11304SJanie.Lu@Sun.COM 	case NIU_MAJOR_VER: /* 1 */
1555*11304SJanie.Lu@Sun.COM 		switch (op_type) {
1556*11304SJanie.Lu@Sun.COM 		case N2NIU_TX_LP_CONF:
1557*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.tx;
1558*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_conf)((uint64_t)channel,
1559*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no,
1560*11304SJanie.Lu@Sun.COM 			    (uint64_t)ioaddr_pp,
1561*11304SJanie.Lu@Sun.COM 			    (uint64_t)ioaddr_size);
1562*11304SJanie.Lu@Sun.COM 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1563*11304SJanie.Lu@Sun.COM 			    "==> nxge_init_hv_fzc_lp_op(tx_conf): major %d "
1564*11304SJanie.Lu@Sun.COM 			    "op 0x%x hverr 0x%x", major, op_type, hverr));
1565*11304SJanie.Lu@Sun.COM 			break;
1566*11304SJanie.Lu@Sun.COM 
1567*11304SJanie.Lu@Sun.COM 		case N2NIU_TX_LP_INFO:
1568*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.tx;
1569*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_info)((uint64_t)channel,
1570*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no,
1571*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_pp,
1572*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_size);
1573*11304SJanie.Lu@Sun.COM 			break;
1574*11304SJanie.Lu@Sun.COM 
1575*11304SJanie.Lu@Sun.COM 		case N2NIU_RX_LP_CONF:
1576*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.rx;
1577*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_conf)((uint64_t)channel,
1578*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no,
1579*11304SJanie.Lu@Sun.COM 			    (uint64_t)ioaddr_pp,
1580*11304SJanie.Lu@Sun.COM 			    (uint64_t)ioaddr_size);
1581*11304SJanie.Lu@Sun.COM 			break;
1582*11304SJanie.Lu@Sun.COM 
1583*11304SJanie.Lu@Sun.COM 		case N2NIU_RX_LP_INFO:
1584*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.rx;
1585*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_info)((uint64_t)channel,
1586*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no,
1587*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_pp,
1588*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_size);
1589*11304SJanie.Lu@Sun.COM 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1590*11304SJanie.Lu@Sun.COM 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1591*11304SJanie.Lu@Sun.COM 			    "op 0x%x hverr 0x%x", major, op_type, hverr));
1592*11304SJanie.Lu@Sun.COM 			break;
1593*11304SJanie.Lu@Sun.COM 
1594*11304SJanie.Lu@Sun.COM 		default:
1595*11304SJanie.Lu@Sun.COM 			hverr = EINVAL;
1596*11304SJanie.Lu@Sun.COM 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1597*11304SJanie.Lu@Sun.COM 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1598*11304SJanie.Lu@Sun.COM 			    "invalid op 0x%x hverr 0x%x", major,
1599*11304SJanie.Lu@Sun.COM 			    op_type, hverr));
1600*11304SJanie.Lu@Sun.COM 			break;
1601*11304SJanie.Lu@Sun.COM 		}
1602*11304SJanie.Lu@Sun.COM 
1603*11304SJanie.Lu@Sun.COM 		break;
1604*11304SJanie.Lu@Sun.COM 
1605*11304SJanie.Lu@Sun.COM 	case NIU_MAJOR_VER_2: /* 2 */
1606*11304SJanie.Lu@Sun.COM 		switch (op_type) {
1607*11304SJanie.Lu@Sun.COM 		case N2NIU_TX_LP_CONF:
1608*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.tx;
1609*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_cfgh_conf)(nxgep->niu_cfg_hdl,
1610*11304SJanie.Lu@Sun.COM 			    (uint64_t)channel,
1611*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no, ioaddr_pp, ioaddr_size);
1612*11304SJanie.Lu@Sun.COM 
1613*11304SJanie.Lu@Sun.COM 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1614*11304SJanie.Lu@Sun.COM 			    "==> nxge_init_hv_fzc_lp_op(tx_conf): major %d "
1615*11304SJanie.Lu@Sun.COM 			    "op 0x%x hverr 0x%x", major, op_type, hverr));
1616*11304SJanie.Lu@Sun.COM 			break;
1617*11304SJanie.Lu@Sun.COM 
1618*11304SJanie.Lu@Sun.COM 		case N2NIU_TX_LP_INFO:
1619*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.tx;
1620*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_cfgh_info)(nxgep->niu_cfg_hdl,
1621*11304SJanie.Lu@Sun.COM 			    (uint64_t)channel,
1622*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no,
1623*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_pp,
1624*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_size);
1625*11304SJanie.Lu@Sun.COM 			break;
1626*11304SJanie.Lu@Sun.COM 
1627*11304SJanie.Lu@Sun.COM 		case N2NIU_RX_LP_CONF:
1628*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.rx;
1629*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_cfgh_conf)(nxgep->niu_cfg_hdl,
1630*11304SJanie.Lu@Sun.COM 			    (uint64_t)channel,
1631*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no,
1632*11304SJanie.Lu@Sun.COM 			    (uint64_t)ioaddr_pp,
1633*11304SJanie.Lu@Sun.COM 			    (uint64_t)ioaddr_size);
1634*11304SJanie.Lu@Sun.COM 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1635*11304SJanie.Lu@Sun.COM 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1636*11304SJanie.Lu@Sun.COM 			    "hverr 0x%x", major, hverr));
1637*11304SJanie.Lu@Sun.COM 			break;
1638*11304SJanie.Lu@Sun.COM 
1639*11304SJanie.Lu@Sun.COM 		case N2NIU_RX_LP_INFO:
1640*11304SJanie.Lu@Sun.COM 			io_fp = &nhd->hio.rx;
1641*11304SJanie.Lu@Sun.COM 			hverr = (*io_fp->lp_cfgh_info)(nxgep->niu_cfg_hdl,
1642*11304SJanie.Lu@Sun.COM 			    (uint64_t)channel,
1643*11304SJanie.Lu@Sun.COM 			    (uint64_t)page_no,
1644*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_pp,
1645*11304SJanie.Lu@Sun.COM 			    (uint64_t *)ioaddr_size);
1646*11304SJanie.Lu@Sun.COM 			break;
1647*11304SJanie.Lu@Sun.COM 
1648*11304SJanie.Lu@Sun.COM 		default:
1649*11304SJanie.Lu@Sun.COM 			hverr = EINVAL;
1650*11304SJanie.Lu@Sun.COM 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1651*11304SJanie.Lu@Sun.COM 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1652*11304SJanie.Lu@Sun.COM 			    "invalid op 0x%x hverr 0x%x", major,
1653*11304SJanie.Lu@Sun.COM 			    op_type, hverr));
1654*11304SJanie.Lu@Sun.COM 			break;
1655*11304SJanie.Lu@Sun.COM 		}
1656*11304SJanie.Lu@Sun.COM 
1657*11304SJanie.Lu@Sun.COM 		break;
1658*11304SJanie.Lu@Sun.COM 
1659*11304SJanie.Lu@Sun.COM 	default:
1660*11304SJanie.Lu@Sun.COM 		hverr = EINVAL;
1661*11304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1662*11304SJanie.Lu@Sun.COM 		    "==> nxge_init_hv_fzc_lp_op(rx_conf): invalid major %d "
1663*11304SJanie.Lu@Sun.COM 		    "op 0x%x hverr 0x%x", major, op_type, hverr));
1664*11304SJanie.Lu@Sun.COM 		break;
1665*11304SJanie.Lu@Sun.COM 	}
1666*11304SJanie.Lu@Sun.COM 
1667*11304SJanie.Lu@Sun.COM 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1668*11304SJanie.Lu@Sun.COM 	    "<== nxge_init_hv_fzc_lp_op: 0x%x", hverr));
1669*11304SJanie.Lu@Sun.COM 
1670*11304SJanie.Lu@Sun.COM 	return (hverr);
1671*11304SJanie.Lu@Sun.COM }
1672*11304SJanie.Lu@Sun.COM 
16733859Sml29623 #endif	/* sun4v and NIU_LP_WORKAROUND */
1674