xref: /titanic_50/usr/src/uts/common/io/nxge/nxge_fzc.c (revision 4df55fde49134f9735f84011f23a767c75e393c7)
16f45ec7bSml29623 /*
26f45ec7bSml29623  * CDDL HEADER START
36f45ec7bSml29623  *
46f45ec7bSml29623  * The contents of this file are subject to the terms of the
56f45ec7bSml29623  * Common Development and Distribution License (the "License").
66f45ec7bSml29623  * You may not use this file except in compliance with the License.
76f45ec7bSml29623  *
86f45ec7bSml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96f45ec7bSml29623  * or http://www.opensolaris.org/os/licensing.
106f45ec7bSml29623  * See the License for the specific language governing permissions
116f45ec7bSml29623  * and limitations under the License.
126f45ec7bSml29623  *
136f45ec7bSml29623  * When distributing Covered Code, include this CDDL HEADER in each
146f45ec7bSml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156f45ec7bSml29623  * If applicable, add the following below this CDDL HEADER, with the
166f45ec7bSml29623  * fields enclosed by brackets "[]" replaced with your own identifying
176f45ec7bSml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
186f45ec7bSml29623  *
196f45ec7bSml29623  * CDDL HEADER END
206f45ec7bSml29623  */
214ba491f5SMichael Speer 
226f45ec7bSml29623 /*
234ba491f5SMichael Speer  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
246f45ec7bSml29623  * Use is subject to license terms.
256f45ec7bSml29623  */
266f45ec7bSml29623 
276f45ec7bSml29623 #include	<nxge_impl.h>
286f45ec7bSml29623 #include	<npi_mac.h>
296f45ec7bSml29623 #include	<npi_rxdma.h>
30678453a8Sspeer #include	<nxge_hio.h>
316f45ec7bSml29623 
326f45ec7bSml29623 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
336f45ec7bSml29623 static int	nxge_herr2kerr(uint64_t);
34*4df55fdeSJanie Lu static uint64_t nxge_init_hv_fzc_lp_op(p_nxge_t, uint64_t,
35*4df55fdeSJanie Lu     uint64_t, uint64_t, uint64_t, uint64_t);
366f45ec7bSml29623 #endif
376f45ec7bSml29623 
38678453a8Sspeer static nxge_status_t nxge_init_fzc_rdc_pages(p_nxge_t,
39678453a8Sspeer     uint16_t, dma_log_page_t *, dma_log_page_t *);
40678453a8Sspeer 
41678453a8Sspeer static nxge_status_t nxge_init_fzc_tdc_pages(p_nxge_t,
42678453a8Sspeer     uint16_t, dma_log_page_t *, dma_log_page_t *);
43678453a8Sspeer 
446f45ec7bSml29623 /*
456f45ec7bSml29623  * The following interfaces are controlled by the
466f45ec7bSml29623  * function control registers. Some global registers
476f45ec7bSml29623  * are to be initialized by only byt one of the 2/4 functions.
486f45ec7bSml29623  * Use the test and set register.
496f45ec7bSml29623  */
506f45ec7bSml29623 /*ARGSUSED*/
516f45ec7bSml29623 nxge_status_t
nxge_test_and_set(p_nxge_t nxgep,uint8_t tas)526f45ec7bSml29623 nxge_test_and_set(p_nxge_t nxgep, uint8_t tas)
536f45ec7bSml29623 {
546f45ec7bSml29623 	npi_handle_t		handle;
556f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
566f45ec7bSml29623 
576f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
586f45ec7bSml29623 	if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas))
596f45ec7bSml29623 	    != NPI_SUCCESS) {
606f45ec7bSml29623 		return (NXGE_ERROR | rs);
616f45ec7bSml29623 	}
626f45ec7bSml29623 
636f45ec7bSml29623 	return (NXGE_OK);
646f45ec7bSml29623 }
656f45ec7bSml29623 
666f45ec7bSml29623 nxge_status_t
nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep,boolean_t mpc)676f45ec7bSml29623 nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc)
686f45ec7bSml29623 {
696f45ec7bSml29623 	npi_handle_t		handle;
706f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
716f45ec7bSml29623 
726f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl"));
736f45ec7bSml29623 
746f45ec7bSml29623 	/*
756f45ec7bSml29623 	 * In multi-partitioning, the partition manager
766f45ec7bSml29623 	 * who owns function zero should set this multi-partition
776f45ec7bSml29623 	 * control bit.
786f45ec7bSml29623 	 */
796f45ec7bSml29623 	if (nxgep->use_partition && nxgep->function_num) {
806f45ec7bSml29623 		return (NXGE_ERROR);
816f45ec7bSml29623 	}
826f45ec7bSml29623 
836f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
846f45ec7bSml29623 	if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) {
856f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
866f45ec7bSml29623 		    "<== nxge_set_fzc_multi_part_ctl"));
876f45ec7bSml29623 		return (NXGE_ERROR | rs);
886f45ec7bSml29623 	}
896f45ec7bSml29623 
906f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl"));
916f45ec7bSml29623 
926f45ec7bSml29623 	return (NXGE_OK);
936f45ec7bSml29623 }
946f45ec7bSml29623 
956f45ec7bSml29623 nxge_status_t
nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep,boolean_t * mpc_p)966f45ec7bSml29623 nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p)
976f45ec7bSml29623 {
986f45ec7bSml29623 	npi_handle_t		handle;
996f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
1006f45ec7bSml29623 
1016f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
1026f45ec7bSml29623 
1036f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
1046f45ec7bSml29623 	if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) {
1056f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1066f45ec7bSml29623 		    "<== nxge_set_fzc_multi_part_ctl"));
1076f45ec7bSml29623 		return (NXGE_ERROR | rs);
1086f45ec7bSml29623 	}
1096f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
1106f45ec7bSml29623 
1116f45ec7bSml29623 	return (NXGE_OK);
1126f45ec7bSml29623 }
1136f45ec7bSml29623 
1146f45ec7bSml29623 /*
1156f45ec7bSml29623  * System interrupt registers that are under function zero
1166f45ec7bSml29623  * management.
1176f45ec7bSml29623  */
1186f45ec7bSml29623 nxge_status_t
nxge_fzc_intr_init(p_nxge_t nxgep)1196f45ec7bSml29623 nxge_fzc_intr_init(p_nxge_t nxgep)
1206f45ec7bSml29623 {
1216f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
1226f45ec7bSml29623 
1236f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init"));
1246f45ec7bSml29623 
1256f45ec7bSml29623 	/* Configure the initial timer resolution */
1266f45ec7bSml29623 	if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) {
1276f45ec7bSml29623 		return (status);
1286f45ec7bSml29623 	}
1296f45ec7bSml29623 
1302e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
1316f45ec7bSml29623 		/*
1326f45ec7bSml29623 		 * Set up the logical device group's logical devices that
1336f45ec7bSml29623 		 * the group owns.
1346f45ec7bSml29623 		 */
13559ac0c16Sdavemq 		if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK)
13659ac0c16Sdavemq 			goto fzc_intr_init_exit;
1376f45ec7bSml29623 
1386f45ec7bSml29623 		/* Configure the system interrupt data */
13959ac0c16Sdavemq 		if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK)
14059ac0c16Sdavemq 			goto fzc_intr_init_exit;
1416f45ec7bSml29623 	}
1426f45ec7bSml29623 
14359ac0c16Sdavemq fzc_intr_init_exit:
1446f45ec7bSml29623 
1456f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init"));
1466f45ec7bSml29623 
1476f45ec7bSml29623 	return (status);
1486f45ec7bSml29623 }
1496f45ec7bSml29623 
1506f45ec7bSml29623 nxge_status_t
nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)1516f45ec7bSml29623 nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)
1526f45ec7bSml29623 {
1536f45ec7bSml29623 	p_nxge_ldg_t	ldgp;
1546f45ec7bSml29623 	p_nxge_ldv_t	ldvp;
1556f45ec7bSml29623 	npi_handle_t	handle;
1566f45ec7bSml29623 	int		i, j;
1576f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
1586f45ec7bSml29623 
1596f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set"));
1606f45ec7bSml29623 
1616f45ec7bSml29623 	if (nxgep->ldgvp == NULL) {
1626f45ec7bSml29623 		return (NXGE_ERROR);
1636f45ec7bSml29623 	}
1646f45ec7bSml29623 
1656f45ec7bSml29623 	ldgp = nxgep->ldgvp->ldgp;
1666f45ec7bSml29623 	ldvp = nxgep->ldgvp->ldvp;
1676f45ec7bSml29623 	if (ldgp == NULL || ldvp == NULL) {
1686f45ec7bSml29623 		return (NXGE_ERROR);
1696f45ec7bSml29623 	}
1706f45ec7bSml29623 
1716f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
1726f45ec7bSml29623 
1736f45ec7bSml29623 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
1746f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
1756f45ec7bSml29623 		    "==> nxge_fzc_intr_ldg_num_set "
1766f45ec7bSml29623 		    "<== nxge_f(Neptune): # ldv %d "
1776f45ec7bSml29623 		    "in group %d", ldgp->nldvs, ldgp->ldg));
1786f45ec7bSml29623 
1796f45ec7bSml29623 		for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
1806f45ec7bSml29623 			rs = npi_fzc_ldg_num_set(handle, ldvp->ldv,
1816f45ec7bSml29623 			    ldvp->ldg_assigned);
1826f45ec7bSml29623 			if (rs != NPI_SUCCESS) {
1836f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
1846f45ec7bSml29623 				    "<== nxge_fzc_intr_ldg_num_set failed "
1856f45ec7bSml29623 				    " rs 0x%x ldv %d ldg %d",
1866f45ec7bSml29623 				    rs, ldvp->ldv, ldvp->ldg_assigned));
1876f45ec7bSml29623 				return (NXGE_ERROR | rs);
1886f45ec7bSml29623 			}
1896f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
1906f45ec7bSml29623 			    "<== nxge_fzc_intr_ldg_num_set OK "
1916f45ec7bSml29623 			    " ldv %d ldg %d",
1926f45ec7bSml29623 			    ldvp->ldv, ldvp->ldg_assigned));
1936f45ec7bSml29623 		}
1946f45ec7bSml29623 	}
1956f45ec7bSml29623 
1966f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set"));
1976f45ec7bSml29623 
1986f45ec7bSml29623 	return (NXGE_OK);
1996f45ec7bSml29623 }
2006f45ec7bSml29623 
2016f45ec7bSml29623 nxge_status_t
nxge_fzc_intr_tmres_set(p_nxge_t nxgep)2026f45ec7bSml29623 nxge_fzc_intr_tmres_set(p_nxge_t nxgep)
2036f45ec7bSml29623 {
2046f45ec7bSml29623 	npi_handle_t	handle;
2056f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
2066f45ec7bSml29623 
2076f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set"));
2086f45ec7bSml29623 	if (nxgep->ldgvp == NULL) {
2096f45ec7bSml29623 		return (NXGE_ERROR);
2106f45ec7bSml29623 	}
2116f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
2126f45ec7bSml29623 	if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) {
2136f45ec7bSml29623 		return (NXGE_ERROR | rs);
2146f45ec7bSml29623 	}
2156f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set"));
2166f45ec7bSml29623 
2176f45ec7bSml29623 	return (NXGE_OK);
2186f45ec7bSml29623 }
2196f45ec7bSml29623 
2206f45ec7bSml29623 nxge_status_t
nxge_fzc_intr_sid_set(p_nxge_t nxgep)2216f45ec7bSml29623 nxge_fzc_intr_sid_set(p_nxge_t nxgep)
2226f45ec7bSml29623 {
2236f45ec7bSml29623 	npi_handle_t	handle;
2246f45ec7bSml29623 	p_nxge_ldg_t	ldgp;
2256f45ec7bSml29623 	fzc_sid_t	sid;
2266f45ec7bSml29623 	int		i;
2276f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
2286f45ec7bSml29623 
2296f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set"));
2306f45ec7bSml29623 	if (nxgep->ldgvp == NULL) {
2316f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
2326f45ec7bSml29623 		    "<== nxge_fzc_intr_sid_set: no ldg"));
2336f45ec7bSml29623 		return (NXGE_ERROR);
2346f45ec7bSml29623 	}
2356f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
2366f45ec7bSml29623 	ldgp = nxgep->ldgvp->ldgp;
2376f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
2386f45ec7bSml29623 	    "==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs));
2396f45ec7bSml29623 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
2406f45ec7bSml29623 		sid.ldg = ldgp->ldg;
2416f45ec7bSml29623 		sid.niu = B_FALSE;
2426f45ec7bSml29623 		sid.func = ldgp->func;
2436f45ec7bSml29623 		sid.vector = ldgp->vector;
2446f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
2456f45ec7bSml29623 		    "==> nxge_fzc_intr_sid_set(%d): func %d group %d "
2466f45ec7bSml29623 		    "vector %d",
2476f45ec7bSml29623 		    i, sid.func, sid.ldg, sid.vector));
2486f45ec7bSml29623 		rs = npi_fzc_sid_set(handle, sid);
2496f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
2506f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
2516f45ec7bSml29623 			    "<== nxge_fzc_intr_sid_set:failed 0x%x",
2526f45ec7bSml29623 			    rs));
2536f45ec7bSml29623 			return (NXGE_ERROR | rs);
2546f45ec7bSml29623 		}
2556f45ec7bSml29623 	}
2566f45ec7bSml29623 
2576f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set"));
2586f45ec7bSml29623 
2596f45ec7bSml29623 	return (NXGE_OK);
2606f45ec7bSml29623 
2616f45ec7bSml29623 }
2626f45ec7bSml29623 
2636f45ec7bSml29623 /*
264678453a8Sspeer  * nxge_init_fzc_rdc
265678453a8Sspeer  *
266678453a8Sspeer  *	Initialize all of a RDC's FZC_DMC registers.
267678453a8Sspeer  *	This is executed by the service domain, on behalf of a
268678453a8Sspeer  *	guest domain, who cannot access these registers.
269678453a8Sspeer  *
270678453a8Sspeer  * Arguments:
271678453a8Sspeer  * 	nxgep
272678453a8Sspeer  * 	channel		The channel to initialize.
273678453a8Sspeer  *
274678453a8Sspeer  * NPI_NXGE function calls:
275678453a8Sspeer  *	nxge_init_fzc_rdc_pages()
276678453a8Sspeer  *
277678453a8Sspeer  * Context:
278678453a8Sspeer  *	Service Domain
2796f45ec7bSml29623  */
2806f45ec7bSml29623 /*ARGSUSED*/
2816f45ec7bSml29623 nxge_status_t
nxge_init_fzc_rdc(p_nxge_t nxgep,uint16_t channel)282678453a8Sspeer nxge_init_fzc_rdc(p_nxge_t nxgep, uint16_t channel)
2836f45ec7bSml29623 {
2846f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
285678453a8Sspeer 
286678453a8Sspeer 	dma_log_page_t	page1, page2;
287678453a8Sspeer 	npi_handle_t	handle;
288678453a8Sspeer 	rdc_red_para_t	red;
289678453a8Sspeer 
290678453a8Sspeer 	/*
291678453a8Sspeer 	 * Initialize the RxDMA channel-specific FZC control
292678453a8Sspeer 	 * registers.
293678453a8Sspeer 	 */
294678453a8Sspeer 
295678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc"));
296678453a8Sspeer 
297678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
298678453a8Sspeer 
299678453a8Sspeer 	/* Reset RXDMA channel */
300678453a8Sspeer 	status = npi_rxdma_cfg_rdc_reset(handle, channel);
301678453a8Sspeer 	if (status != NPI_SUCCESS) {
302678453a8Sspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
303678453a8Sspeer 		    "==> nxge_init_fzc_rdc: npi_rxdma_cfg_rdc_reset(%d) "
304678453a8Sspeer 		    "returned 0x%08x", channel, status));
305678453a8Sspeer 		return (NXGE_ERROR | status);
306678453a8Sspeer 	}
307678453a8Sspeer 
308678453a8Sspeer 	/*
309678453a8Sspeer 	 * These values have been copied from
310678453a8Sspeer 	 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring().
311678453a8Sspeer 	 */
312678453a8Sspeer 	page1.page_num = 0;
313678453a8Sspeer 	page1.valid = 1;
314678453a8Sspeer 	page1.func_num = nxgep->function_num;
315678453a8Sspeer 	page1.mask = 0;
316678453a8Sspeer 	page1.value = 0;
317678453a8Sspeer 	page1.reloc = 0;
318678453a8Sspeer 
319678453a8Sspeer 	page2.page_num = 1;
320678453a8Sspeer 	page2.valid = 1;
321678453a8Sspeer 	page2.func_num = nxgep->function_num;
322678453a8Sspeer 	page2.mask = 0;
323678453a8Sspeer 	page2.value = 0;
324678453a8Sspeer 	page2.reloc = 0;
325678453a8Sspeer 
326678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
327678453a8Sspeer #if !defined(NIU_HV_WORKAROUND)
328678453a8Sspeer 		status = NXGE_OK;
329678453a8Sspeer #else
330678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
331678453a8Sspeer 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
332678453a8Sspeer 		    "set up logical pages"));
333678453a8Sspeer 		/* Initialize the RXDMA logical pages */
334678453a8Sspeer 		status = nxge_init_fzc_rdc_pages(nxgep, channel,
335678453a8Sspeer 		    &page1, &page2);
336678453a8Sspeer 		if (status != NXGE_OK) {
337678453a8Sspeer 			return (status);
338678453a8Sspeer 		}
339678453a8Sspeer #endif
340678453a8Sspeer 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
341678453a8Sspeer 		/* Initialize the RXDMA logical pages */
342678453a8Sspeer 		status = nxge_init_fzc_rdc_pages(nxgep, channel,
343678453a8Sspeer 		    &page1, &page2);
344678453a8Sspeer 		if (status != NXGE_OK) {
345678453a8Sspeer 			return (status);
346678453a8Sspeer 		}
347678453a8Sspeer 	} else {
348678453a8Sspeer 		return (NXGE_ERROR);
349678453a8Sspeer 	}
350678453a8Sspeer 
351678453a8Sspeer 	/*
352678453a8Sspeer 	 * Configure RED parameters
353678453a8Sspeer 	 */
354678453a8Sspeer 	red.value = 0;
355678453a8Sspeer 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
356678453a8Sspeer 	red.bits.ldw.thre =
357678453a8Sspeer 	    (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES);
358678453a8Sspeer 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
359678453a8Sspeer 	red.bits.ldw.thre_sync =
360678453a8Sspeer 	    (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES);
361678453a8Sspeer 
362678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
363678453a8Sspeer 	    "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
364678453a8Sspeer 	    red.bits.ldw.thre_sync,
365678453a8Sspeer 	    red.bits.ldw.thre_sync));
366678453a8Sspeer 
367678453a8Sspeer 	status |= npi_rxdma_cfg_wred_param(handle, channel, &red);
368678453a8Sspeer 
369678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc"));
370678453a8Sspeer 
371678453a8Sspeer 	return (status);
372678453a8Sspeer }
373678453a8Sspeer 
374678453a8Sspeer /*
375678453a8Sspeer  * nxge_init_fzc_rxdma_channel
376678453a8Sspeer  *
377678453a8Sspeer  *	Initialize all per-channel FZC_DMC registers.
378678453a8Sspeer  *
379678453a8Sspeer  * Arguments:
380678453a8Sspeer  * 	nxgep
381678453a8Sspeer  * 	channel		The channel to start
382678453a8Sspeer  *
383678453a8Sspeer  * NPI_NXGE function calls:
384678453a8Sspeer  *	nxge_init_hv_fzc_rxdma_channel_pages()
385678453a8Sspeer  *	nxge_init_fzc_rxdma_channel_pages()
386678453a8Sspeer  *	nxge_init_fzc_rxdma_channel_red()
387678453a8Sspeer  *
388678453a8Sspeer  * Context:
389678453a8Sspeer  *	Service Domain
390678453a8Sspeer  */
391678453a8Sspeer /*ARGSUSED*/
392678453a8Sspeer nxge_status_t
nxge_init_fzc_rxdma_channel(p_nxge_t nxgep,uint16_t channel)393678453a8Sspeer nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel)
394678453a8Sspeer {
395678453a8Sspeer 	rx_rbr_ring_t		*rbr_ring;
396678453a8Sspeer 	rx_rcr_ring_t		*rcr_ring;
397678453a8Sspeer 
398678453a8Sspeer 	nxge_status_t		status = NXGE_OK;
399678453a8Sspeer 
4006f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel"));
4016f45ec7bSml29623 
402678453a8Sspeer 	rbr_ring = nxgep->rx_rbr_rings->rbr_rings[channel];
403678453a8Sspeer 	rcr_ring = nxgep->rx_rcr_rings->rcr_rings[channel];
404678453a8Sspeer 
40559ac0c16Sdavemq 	if (nxgep->niu_type == N2_NIU) {
4066f45ec7bSml29623 #ifndef	NIU_HV_WORKAROUND
4076f45ec7bSml29623 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
4086f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
4096f45ec7bSml29623 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV "
4106f45ec7bSml29623 		    "set up logical pages"));
4116f45ec7bSml29623 		/* Initialize the RXDMA logical pages */
4126f45ec7bSml29623 		status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel,
413678453a8Sspeer 		    rbr_ring);
4146f45ec7bSml29623 		if (status != NXGE_OK) {
4156f45ec7bSml29623 			return (status);
4166f45ec7bSml29623 		}
4176f45ec7bSml29623 #endif
41859ac0c16Sdavemq 		status = NXGE_OK;
4196f45ec7bSml29623 #else
4206f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
4216f45ec7bSml29623 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
4226f45ec7bSml29623 		    "set up logical pages"));
4236f45ec7bSml29623 		/* Initialize the RXDMA logical pages */
4246f45ec7bSml29623 		status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel,
425678453a8Sspeer 		    rbr_ring);
4266f45ec7bSml29623 		if (status != NXGE_OK) {
4276f45ec7bSml29623 			return (status);
4286f45ec7bSml29623 		}
4296f45ec7bSml29623 #endif
4302e59129aSraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
43159ac0c16Sdavemq 		/* Initialize the RXDMA logical pages */
43259ac0c16Sdavemq 		status = nxge_init_fzc_rxdma_channel_pages(nxgep,
433678453a8Sspeer 		    channel, rbr_ring);
43459ac0c16Sdavemq 		if (status != NXGE_OK) {
43559ac0c16Sdavemq 			return (status);
43659ac0c16Sdavemq 		}
43759ac0c16Sdavemq 	} else {
43859ac0c16Sdavemq 		return (NXGE_ERROR);
4396f45ec7bSml29623 	}
4406f45ec7bSml29623 
4416f45ec7bSml29623 	/* Configure RED parameters */
442678453a8Sspeer 	status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_ring);
4436f45ec7bSml29623 
4446f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel"));
4456f45ec7bSml29623 	return (status);
4466f45ec7bSml29623 }
4476f45ec7bSml29623 
448678453a8Sspeer /*
449678453a8Sspeer  * nxge_init_fzc_rdc_pages
450678453a8Sspeer  *
451678453a8Sspeer  *	Configure a TDC's logical pages.
452678453a8Sspeer  *
453678453a8Sspeer  *	This function is executed by the service domain, on behalf of
454678453a8Sspeer  *	a guest domain, to whom this RDC has been loaned.
455678453a8Sspeer  *
456678453a8Sspeer  * Arguments:
457678453a8Sspeer  * 	nxgep
458678453a8Sspeer  * 	channel		The channel to initialize.
459678453a8Sspeer  * 	page0		Logical page 0 definition.
460678453a8Sspeer  * 	page1		Logical page 1 definition.
461678453a8Sspeer  *
462678453a8Sspeer  * Notes:
463678453a8Sspeer  *	I think that this function can be called from any
464678453a8Sspeer  *	domain, but I need to check.
465678453a8Sspeer  *
466678453a8Sspeer  * NPI/NXGE function calls:
467678453a8Sspeer  *	hv_niu_tx_logical_page_conf()
468678453a8Sspeer  *	hv_niu_tx_logical_page_info()
469678453a8Sspeer  *
470678453a8Sspeer  * Context:
471678453a8Sspeer  *	Any domain
472678453a8Sspeer  */
473678453a8Sspeer 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)474678453a8Sspeer nxge_init_fzc_rdc_pages(
475678453a8Sspeer 	p_nxge_t nxgep,
476678453a8Sspeer 	uint16_t channel,
477678453a8Sspeer 	dma_log_page_t *page0,
478678453a8Sspeer 	dma_log_page_t *page1)
479678453a8Sspeer {
480678453a8Sspeer 	npi_handle_t handle;
481678453a8Sspeer 	npi_status_t rs;
482678453a8Sspeer 
483678453a8Sspeer 	uint64_t page_handle;
484678453a8Sspeer 
485678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
486678453a8Sspeer 	    "==> nxge_init_fzc_txdma_channel_pages"));
487678453a8Sspeer 
488678453a8Sspeer #ifndef	NIU_HV_WORKAROUND
489678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
490678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
491678453a8Sspeer 		    "<== nxge_init_fzc_rdc_pages: "
492678453a8Sspeer 		    "N2_NIU: no need to set rxdma logical pages"));
493678453a8Sspeer 		return (NXGE_OK);
494678453a8Sspeer 	}
495678453a8Sspeer #else
496678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
497678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
498678453a8Sspeer 		    "<== nxge_init_fzc_rdc_pages: "
499678453a8Sspeer 		    "N2_NIU: NEED to set rxdma logical pages"));
500678453a8Sspeer 	}
501678453a8Sspeer #endif
502678453a8Sspeer 
503678453a8Sspeer 	/*
504678453a8Sspeer 	 * Initialize logical page 1.
505678453a8Sspeer 	 */
506678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
507678453a8Sspeer 	if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page0))
508678453a8Sspeer 	    != NPI_SUCCESS)
509678453a8Sspeer 		return (NXGE_ERROR | rs);
510678453a8Sspeer 
511678453a8Sspeer 	/*
512678453a8Sspeer 	 * Initialize logical page 2.
513678453a8Sspeer 	 */
514678453a8Sspeer 	if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page1))
515678453a8Sspeer 	    != NPI_SUCCESS)
516678453a8Sspeer 		return (NXGE_ERROR | rs);
517678453a8Sspeer 
518678453a8Sspeer 	/*
519678453a8Sspeer 	 * Initialize the page handle.
520678453a8Sspeer 	 * (In the current driver, this is always set to 0.)
521678453a8Sspeer 	 */
522678453a8Sspeer 	page_handle = 0;
523678453a8Sspeer 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel, page_handle);
524678453a8Sspeer 	if (rs == NPI_SUCCESS) {
525678453a8Sspeer 		return (NXGE_OK);
526678453a8Sspeer 	} else {
527678453a8Sspeer 		return (NXGE_ERROR | rs);
528678453a8Sspeer 	}
529678453a8Sspeer }
530678453a8Sspeer 
5316f45ec7bSml29623 /*ARGSUSED*/
5326f45ec7bSml29623 nxge_status_t
nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_rx_rbr_ring_t rbrp)5336f45ec7bSml29623 nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,
5346f45ec7bSml29623 		uint16_t channel, p_rx_rbr_ring_t rbrp)
5356f45ec7bSml29623 {
5366f45ec7bSml29623 	npi_handle_t		handle;
5376f45ec7bSml29623 	dma_log_page_t		cfg;
5386f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
5396f45ec7bSml29623 
5406f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
5416f45ec7bSml29623 	    "==> nxge_init_fzc_rxdma_channel_pages"));
5426f45ec7bSml29623 
5436f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5446f45ec7bSml29623 	/*
5456f45ec7bSml29623 	 * Initialize logical page 1.
5466f45ec7bSml29623 	 */
5476f45ec7bSml29623 	cfg.func_num = nxgep->function_num;
5486f45ec7bSml29623 	cfg.page_num = 0;
5496f45ec7bSml29623 	cfg.valid = rbrp->page_valid.bits.ldw.page0;
5506f45ec7bSml29623 	cfg.value = rbrp->page_value_1.value;
5516f45ec7bSml29623 	cfg.mask = rbrp->page_mask_1.value;
5526f45ec7bSml29623 	cfg.reloc = rbrp->page_reloc_1.value;
5536f45ec7bSml29623 	rs = npi_rxdma_cfg_logical_page(handle, channel,
5546f45ec7bSml29623 	    (p_dma_log_page_t)&cfg);
5556f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5566f45ec7bSml29623 		return (NXGE_ERROR | rs);
5576f45ec7bSml29623 	}
5586f45ec7bSml29623 
5596f45ec7bSml29623 	/*
5606f45ec7bSml29623 	 * Initialize logical page 2.
5616f45ec7bSml29623 	 */
5626f45ec7bSml29623 	cfg.page_num = 1;
5636f45ec7bSml29623 	cfg.valid = rbrp->page_valid.bits.ldw.page1;
5646f45ec7bSml29623 	cfg.value = rbrp->page_value_2.value;
5656f45ec7bSml29623 	cfg.mask = rbrp->page_mask_2.value;
5666f45ec7bSml29623 	cfg.reloc = rbrp->page_reloc_2.value;
5676f45ec7bSml29623 
5686f45ec7bSml29623 	rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg);
5696f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5706f45ec7bSml29623 		return (NXGE_ERROR | rs);
5716f45ec7bSml29623 	}
5726f45ec7bSml29623 
5736f45ec7bSml29623 	/* Initialize the page handle */
5746f45ec7bSml29623 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel,
5756f45ec7bSml29623 	    rbrp->page_hdl.bits.ldw.handle);
5766f45ec7bSml29623 
5776f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5786f45ec7bSml29623 		return (NXGE_ERROR | rs);
5796f45ec7bSml29623 	}
5806f45ec7bSml29623 
5816f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
5826f45ec7bSml29623 	    "<== nxge_init_fzc_rxdma_channel_pages"));
5836f45ec7bSml29623 
5846f45ec7bSml29623 	return (NXGE_OK);
5856f45ec7bSml29623 }
5866f45ec7bSml29623 
5876f45ec7bSml29623 /*ARGSUSED*/
5886f45ec7bSml29623 nxge_status_t
nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,uint16_t channel,p_rx_rcr_ring_t rcr_p)5896f45ec7bSml29623 nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,
5906f45ec7bSml29623 	uint16_t channel, p_rx_rcr_ring_t rcr_p)
5916f45ec7bSml29623 {
5926f45ec7bSml29623 	npi_handle_t		handle;
5936f45ec7bSml29623 	rdc_red_para_t		red;
5946f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
5956f45ec7bSml29623 
5966f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red"));
5976f45ec7bSml29623 
5986f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5996f45ec7bSml29623 	red.value = 0;
6006f45ec7bSml29623 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
6016f45ec7bSml29623 	red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
6026f45ec7bSml29623 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
6036f45ec7bSml29623 	red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
6046f45ec7bSml29623 
6056f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
6066f45ec7bSml29623 	    "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
6076f45ec7bSml29623 	    red.bits.ldw.thre_sync,
6086f45ec7bSml29623 	    red.bits.ldw.thre_sync));
6096f45ec7bSml29623 
6106f45ec7bSml29623 	rs = npi_rxdma_cfg_wred_param(handle, channel, &red);
6116f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
6126f45ec7bSml29623 		return (NXGE_ERROR | rs);
6136f45ec7bSml29623 	}
6146f45ec7bSml29623 
6156f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
6166f45ec7bSml29623 	    "<== nxge_init_fzc_rxdma_channel_red"));
6176f45ec7bSml29623 
6186f45ec7bSml29623 	return (NXGE_OK);
6196f45ec7bSml29623 }
6206f45ec7bSml29623 
621678453a8Sspeer /*
622678453a8Sspeer  * nxge_init_fzc_tdc
623678453a8Sspeer  *
624678453a8Sspeer  *	Initialize all of a TDC's FZC_DMC registers.
625678453a8Sspeer  *	This is executed by the service domain, on behalf of a
626678453a8Sspeer  *	guest domain, who cannot access these registers.
627678453a8Sspeer  *
628678453a8Sspeer  * Arguments:
629678453a8Sspeer  * 	nxgep
630678453a8Sspeer  * 	channel		The channel to initialize.
631678453a8Sspeer  *
632678453a8Sspeer  * NPI_NXGE function calls:
633678453a8Sspeer  *	nxge_init_fzc_tdc_pages()
634678453a8Sspeer  *	npi_txc_dma_max_burst_set()
635678453a8Sspeer  *
636678453a8Sspeer  * Registers accessed:
637678453a8Sspeer  *	TXC_DMA_MAX_BURST
638678453a8Sspeer  *
639678453a8Sspeer  * Context:
640678453a8Sspeer  *	Service Domain
641678453a8Sspeer  */
642678453a8Sspeer /*ARGSUSED*/
643678453a8Sspeer nxge_status_t
nxge_init_fzc_tdc(p_nxge_t nxgep,uint16_t channel)644678453a8Sspeer nxge_init_fzc_tdc(p_nxge_t nxgep, uint16_t channel)
645678453a8Sspeer {
646678453a8Sspeer 	nxge_status_t	status = NXGE_OK;
647678453a8Sspeer 
648678453a8Sspeer 	dma_log_page_t	page1, page2;
649678453a8Sspeer 	npi_handle_t	handle;
650678453a8Sspeer 
651678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc"));
652678453a8Sspeer 
653678453a8Sspeer 	/*
654678453a8Sspeer 	 * These values have been copied from
655678453a8Sspeer 	 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring().
656678453a8Sspeer 	 */
657678453a8Sspeer 	page1.page_num = 0;
658678453a8Sspeer 	page1.valid = 1;
659678453a8Sspeer 	page1.func_num = nxgep->function_num;
660678453a8Sspeer 	page1.mask = 0;
661678453a8Sspeer 	page1.value = 0;
662678453a8Sspeer 	page1.reloc = 0;
663678453a8Sspeer 
664678453a8Sspeer 	page1.page_num = 1;
665678453a8Sspeer 	page1.valid = 1;
666678453a8Sspeer 	page1.func_num = nxgep->function_num;
667678453a8Sspeer 	page1.mask = 0;
668678453a8Sspeer 	page1.value = 0;
669678453a8Sspeer 	page1.reloc = 0;
670678453a8Sspeer 
671678453a8Sspeer #ifdef	NIU_HV_WORKAROUND
672678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
673678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
674678453a8Sspeer 		    "==> nxge_init_fzc_txdma_channel "
675678453a8Sspeer 		    "N2_NIU: NEED to set up txdma logical pages"));
676678453a8Sspeer 		/* Initialize the TXDMA logical pages */
677678453a8Sspeer 		(void) nxge_init_fzc_tdc_pages(nxgep, channel,
678678453a8Sspeer 		    &page1, &page2);
679678453a8Sspeer 	}
680678453a8Sspeer #endif
681678453a8Sspeer 	if (nxgep->niu_type != N2_NIU) {
682678453a8Sspeer 		if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
683678453a8Sspeer 			/* Initialize the TXDMA logical pages */
684678453a8Sspeer 			(void) nxge_init_fzc_tdc_pages(nxgep, channel,
685678453a8Sspeer 			    &page1, &page2);
686678453a8Sspeer 		} else
687678453a8Sspeer 			return (NXGE_ERROR);
688678453a8Sspeer 	}
689678453a8Sspeer 
690678453a8Sspeer 	/*
691678453a8Sspeer 	 * Configure the TXC DMA Max Burst value.
692678453a8Sspeer 	 *
693678453a8Sspeer 	 * PRM.13.5
694678453a8Sspeer 	 *
695678453a8Sspeer 	 * TXC DMA Max Burst. TXC_DMA_MAX (FZC_TXC + 0000016)
696678453a8Sspeer 	 * 19:0		dma_max_burst		RW
697678453a8Sspeer 	 * Max burst value associated with DMA. Used by DRR engine
698678453a8Sspeer 	 * for computing when DMA has gone into deficit.
699678453a8Sspeer 	 */
700678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
701678453a8Sspeer 	(void) npi_txc_dma_max_burst_set(
702678453a8Sspeer 	    handle, channel, TXC_DMA_MAX_BURST_DEFAULT);
703678453a8Sspeer 
704678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_tdc"));
705678453a8Sspeer 
706678453a8Sspeer 	return (status);
707678453a8Sspeer }
708678453a8Sspeer 
7096f45ec7bSml29623 /*ARGSUSED*/
7106f45ec7bSml29623 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)7116f45ec7bSml29623 nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel,
7126f45ec7bSml29623 	p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p)
7136f45ec7bSml29623 {
7146f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
7156f45ec7bSml29623 
7166f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7176f45ec7bSml29623 	    "==> nxge_init_fzc_txdma_channel"));
7186f45ec7bSml29623 
71959ac0c16Sdavemq 	if (nxgep->niu_type == N2_NIU) {
7206f45ec7bSml29623 #ifndef	NIU_HV_WORKAROUND
7216f45ec7bSml29623 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
7226f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7236f45ec7bSml29623 		    "==> nxge_init_fzc_txdma_channel "
7246f45ec7bSml29623 		    "N2_NIU: call HV to set up txdma logical pages"));
7256f45ec7bSml29623 		status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel,
7266f45ec7bSml29623 		    tx_ring_p);
7276f45ec7bSml29623 		if (status != NXGE_OK) {
7286f45ec7bSml29623 			return (status);
7296f45ec7bSml29623 		}
7306f45ec7bSml29623 #endif
73159ac0c16Sdavemq 		status = NXGE_OK;
7326f45ec7bSml29623 #else
7336f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7346f45ec7bSml29623 		    "==> nxge_init_fzc_txdma_channel "
7356f45ec7bSml29623 		    "N2_NIU: NEED to set up txdma logical pages"));
7366f45ec7bSml29623 		/* Initialize the TXDMA logical pages */
7376f45ec7bSml29623 		(void) nxge_init_fzc_txdma_channel_pages(nxgep, channel,
7386f45ec7bSml29623 		    tx_ring_p);
7396f45ec7bSml29623 #endif
7402e59129aSraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
74159ac0c16Sdavemq 		/* Initialize the TXDMA logical pages */
74259ac0c16Sdavemq 		(void) nxge_init_fzc_txdma_channel_pages(nxgep,
74359ac0c16Sdavemq 		    channel, tx_ring_p);
74459ac0c16Sdavemq 	} else {
74559ac0c16Sdavemq 		return (NXGE_ERROR);
7466f45ec7bSml29623 	}
7476f45ec7bSml29623 
7486f45ec7bSml29623 	/*
7496f45ec7bSml29623 	 * Configure Transmit DRR Weight parameters
7506f45ec7bSml29623 	 * (It actually programs the TXC max burst register).
7516f45ec7bSml29623 	 */
7526f45ec7bSml29623 	(void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p);
7536f45ec7bSml29623 
7546f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7556f45ec7bSml29623 	    "<== nxge_init_fzc_txdma_channel"));
7566f45ec7bSml29623 	return (status);
7576f45ec7bSml29623 }
7586f45ec7bSml29623 
7596f45ec7bSml29623 
7606f45ec7bSml29623 nxge_status_t
nxge_init_fzc_rx_common(p_nxge_t nxgep)7616f45ec7bSml29623 nxge_init_fzc_rx_common(p_nxge_t nxgep)
7626f45ec7bSml29623 {
7636f45ec7bSml29623 	npi_handle_t	handle;
7646f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
7656f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
7664ba491f5SMichael Speer 	nxge_rdc_grp_t	*rdc_grp_p;
7676f45ec7bSml29623 	clock_t		lbolt;
768678453a8Sspeer 	int		table;
769678453a8Sspeer 
770678453a8Sspeer 	nxge_hw_pt_cfg_t *hardware;
7716f45ec7bSml29623 
7726f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common"));
7736f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
7746f45ec7bSml29623 	if (!handle.regp) {
7756f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
7766f45ec7bSml29623 		    "==> nxge_init_fzc_rx_common null ptr"));
7776f45ec7bSml29623 		return (NXGE_ERROR);
7786f45ec7bSml29623 	}
7796f45ec7bSml29623 
7806f45ec7bSml29623 	/*
7816f45ec7bSml29623 	 * Configure the rxdma clock divider
7826f45ec7bSml29623 	 * This is the granularity counter based on
7836f45ec7bSml29623 	 * the hardware system clock (i.e. 300 Mhz) and
7846f45ec7bSml29623 	 * it is running around 3 nanoseconds.
7856f45ec7bSml29623 	 * So, set the clock divider counter to 1000 to get
7866f45ec7bSml29623 	 * microsecond granularity.
7876f45ec7bSml29623 	 * For example, for a 3 microsecond timeout, the timeout
7886f45ec7bSml29623 	 * will be set to 1.
7896f45ec7bSml29623 	 */
7906f45ec7bSml29623 	rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT);
7916f45ec7bSml29623 	if (rs != NPI_SUCCESS)
7926f45ec7bSml29623 		return (NXGE_ERROR | rs);
7936f45ec7bSml29623 
7946f45ec7bSml29623 #if defined(__i386)
7956f45ec7bSml29623 	rs = npi_rxdma_cfg_32bitmode_enable(handle);
7966f45ec7bSml29623 	if (rs != NPI_SUCCESS)
7976f45ec7bSml29623 		return (NXGE_ERROR | rs);
7986f45ec7bSml29623 	rs = npi_txdma_mode32_set(handle, B_TRUE);
7996f45ec7bSml29623 	if (rs != NPI_SUCCESS)
8006f45ec7bSml29623 		return (NXGE_ERROR | rs);
8016f45ec7bSml29623 #endif
8026f45ec7bSml29623 
8036f45ec7bSml29623 	/*
8046f45ec7bSml29623 	 * Enable WRED and program an initial value.
8056f45ec7bSml29623 	 * Use time to set the initial random number.
8066f45ec7bSml29623 	 */
8076f45ec7bSml29623 	(void) drv_getparm(LBOLT, &lbolt);
8086f45ec7bSml29623 	rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt);
8096f45ec7bSml29623 	if (rs != NPI_SUCCESS)
8106f45ec7bSml29623 		return (NXGE_ERROR | rs);
8116f45ec7bSml29623 
812678453a8Sspeer 	hardware = &nxgep->pt_config.hw_config;
813678453a8Sspeer 	for (table = 0; table < NXGE_MAX_RDC_GRPS; table++) {
814678453a8Sspeer 		/* Does this table belong to <nxgep>? */
8154ba491f5SMichael Speer 		if (hardware->grpids[table] == (nxgep->function_num + 256)) {
8164ba491f5SMichael Speer 			rdc_grp_p = &nxgep->pt_config.rdc_grps[table];
8174ba491f5SMichael Speer 			status = nxge_init_fzc_rdc_tbl(nxgep, rdc_grp_p, table);
8184ba491f5SMichael Speer 		}
819678453a8Sspeer 	}
8206f45ec7bSml29623 
8216f45ec7bSml29623 	/* Ethernet Timeout Counter (?) */
8226f45ec7bSml29623 
8236f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
8246f45ec7bSml29623 	    "<== nxge_init_fzc_rx_common:status 0x%08x", status));
8256f45ec7bSml29623 
8266f45ec7bSml29623 	return (status);
8276f45ec7bSml29623 }
8286f45ec7bSml29623 
8296f45ec7bSml29623 nxge_status_t
nxge_init_fzc_rdc_tbl(p_nxge_t nxge,nxge_rdc_grp_t * group,int rdc_tbl)8304ba491f5SMichael Speer nxge_init_fzc_rdc_tbl(p_nxge_t nxge, nxge_rdc_grp_t *group, int rdc_tbl)
8316f45ec7bSml29623 {
832678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
833678453a8Sspeer 	nx_rdc_tbl_t	*table;
8346f45ec7bSml29623 	npi_handle_t	handle;
835678453a8Sspeer 
8366f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
8376f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
8386f45ec7bSml29623 
839678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_init_fzc_rdc_tbl(%d)", table));
8406f45ec7bSml29623 
841678453a8Sspeer 	/* This RDC table must have been previously bound to <nxge>. */
842678453a8Sspeer 	MUTEX_ENTER(&nhd->lock);
843678453a8Sspeer 	table = &nhd->rdc_tbl[rdc_tbl];
844678453a8Sspeer 	if (table->nxge != (uintptr_t)nxge) {
845678453a8Sspeer 		MUTEX_EXIT(&nhd->lock);
846678453a8Sspeer 		NXGE_ERROR_MSG((nxge, DMA_CTL,
847678453a8Sspeer 		    "nxge_init_fzc_rdc_tbl(%d): not owner", table));
848678453a8Sspeer 		return (NXGE_ERROR);
849678453a8Sspeer 	} else {
850678453a8Sspeer 		table->map = group->map;
851678453a8Sspeer 	}
852678453a8Sspeer 	MUTEX_EXIT(&nhd->lock);
853678453a8Sspeer 
854678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxge);
855678453a8Sspeer 
856678453a8Sspeer 	rs = npi_rxdma_rdc_table_config(handle, rdc_tbl,
857678453a8Sspeer 	    group->map, group->max_rdcs);
858678453a8Sspeer 
8596f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
8606f45ec7bSml29623 		status = NXGE_ERROR | rs;
861678453a8Sspeer 	}
862678453a8Sspeer 
863678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_init_fzc_rdc_tbl(%d)", table));
864678453a8Sspeer 	return (status);
865678453a8Sspeer }
866678453a8Sspeer 
867678453a8Sspeer static
868678453a8Sspeer int
rdc_tbl_bind(p_nxge_t nxge,int rdc_tbl)869678453a8Sspeer rdc_tbl_bind(p_nxge_t nxge, int rdc_tbl)
870678453a8Sspeer {
871678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
872678453a8Sspeer 	nx_rdc_tbl_t *table;
873678453a8Sspeer 	int i;
874678453a8Sspeer 
875678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_bind"));
876678453a8Sspeer 
877678453a8Sspeer 	MUTEX_ENTER(&nhd->lock);
878678453a8Sspeer 	/* is the caller asking for a particular table? */
879678453a8Sspeer 	if (rdc_tbl >= 0 && rdc_tbl < NXGE_MAX_RDC_GROUPS) {
880678453a8Sspeer 		table = &nhd->rdc_tbl[rdc_tbl];
881678453a8Sspeer 		if (table->nxge == 0) {
882678453a8Sspeer 			table->nxge = (uintptr_t)nxge; /* It is now bound. */
883678453a8Sspeer 			NXGE_DEBUG_MSG((nxge, DMA_CTL,
884678453a8Sspeer 			    "<== nxge_fzc_rdc_tbl_bind(%d)", rdc_tbl));
885678453a8Sspeer 			MUTEX_EXIT(&nhd->lock);
886678453a8Sspeer 			return (rdc_tbl);
887678453a8Sspeer 		}
888678453a8Sspeer 	} else {	/* The caller will take any old RDC table. */
889678453a8Sspeer 		for (i = 0; i < NXGE_MAX_RDC_GROUPS; i++) {
890678453a8Sspeer 			nx_rdc_tbl_t *table = &nhd->rdc_tbl[i];
891678453a8Sspeer 			if (table->nxge == 0) {
892678453a8Sspeer 				table->nxge = (uintptr_t)nxge;
893678453a8Sspeer 				/* It is now bound. */
894678453a8Sspeer 				MUTEX_EXIT(&nhd->lock);
895678453a8Sspeer 				NXGE_DEBUG_MSG((nxge, DMA_CTL,
896678453a8Sspeer 				    "<== nxge_fzc_rdc_tbl_bind: %d", i));
897678453a8Sspeer 				return (i);
898678453a8Sspeer 			}
899678453a8Sspeer 		}
900678453a8Sspeer 	}
901678453a8Sspeer 	MUTEX_EXIT(&nhd->lock);
902678453a8Sspeer 
903678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_fzc_rdc_tbl_bind"));
904678453a8Sspeer 
905678453a8Sspeer 	return (-EBUSY);	/* RDC tables are bound. */
906678453a8Sspeer }
907678453a8Sspeer 
908678453a8Sspeer int
nxge_fzc_rdc_tbl_bind(nxge_t * nxge,int grp_index,int acceptNoSubstitutes)909678453a8Sspeer nxge_fzc_rdc_tbl_bind(
910678453a8Sspeer 	nxge_t *nxge,
911678453a8Sspeer 	int grp_index,
912678453a8Sspeer 	int acceptNoSubstitutes)
913678453a8Sspeer {
914678453a8Sspeer 	nxge_hw_pt_cfg_t *hardware;
915678453a8Sspeer 	int index;
916678453a8Sspeer 
917678453a8Sspeer 	hardware = &nxge->pt_config.hw_config;
918678453a8Sspeer 
919678453a8Sspeer 	if ((index = rdc_tbl_bind(nxge, grp_index)) < 0) {
920678453a8Sspeer 		if (acceptNoSubstitutes)
921678453a8Sspeer 			return (index);
922678453a8Sspeer 		index = rdc_tbl_bind(nxge, grp_index);
923678453a8Sspeer 		if (index < 0) {
924678453a8Sspeer 			NXGE_ERROR_MSG((nxge, OBP_CTL,
925678453a8Sspeer 			    "nxge_fzc_rdc_tbl_init: "
926678453a8Sspeer 			    "there are no free RDC tables!"));
927678453a8Sspeer 			return (index);
9286f45ec7bSml29623 		}
9296f45ec7bSml29623 	}
9306f45ec7bSml29623 
931678453a8Sspeer 	hardware->grpids[index] = nxge->function_num + 256;
932678453a8Sspeer 
933678453a8Sspeer 	return (index);
934678453a8Sspeer }
935678453a8Sspeer 
936678453a8Sspeer int
nxge_fzc_rdc_tbl_unbind(p_nxge_t nxge,int rdc_tbl)937678453a8Sspeer nxge_fzc_rdc_tbl_unbind(p_nxge_t nxge, int rdc_tbl)
938678453a8Sspeer {
939678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
940678453a8Sspeer 	nx_rdc_tbl_t *table;
941678453a8Sspeer 
9428838ec3aSMichael Speer 	if (nhd == NULL)
9438838ec3aSMichael Speer 		return (0);
9448838ec3aSMichael Speer 
945678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_unbind(%d)",
946678453a8Sspeer 	    rdc_tbl));
947678453a8Sspeer 
948da14cebeSEric Cheng 	MUTEX_ENTER(&nhd->lock);
949678453a8Sspeer 	table = &nhd->rdc_tbl[rdc_tbl];
950678453a8Sspeer 	if (table->nxge != (uintptr_t)nxge) {
951678453a8Sspeer 		NXGE_ERROR_MSG((nxge, DMA_CTL,
952678453a8Sspeer 		    "nxge_fzc_rdc_tbl_unbind(%d): func%d not owner",
953678453a8Sspeer 		    nxge->function_num, rdc_tbl));
954da14cebeSEric Cheng 		MUTEX_EXIT(&nhd->lock);
955678453a8Sspeer 		return (EINVAL);
956678453a8Sspeer 	} else {
957678453a8Sspeer 		bzero(table, sizeof (*table));
958678453a8Sspeer 	}
959da14cebeSEric Cheng 	MUTEX_EXIT(&nhd->lock);
960678453a8Sspeer 
961678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_fzc_rdc_tbl_unbind(%d)",
962678453a8Sspeer 	    rdc_tbl));
963678453a8Sspeer 
964678453a8Sspeer 	return (0);
9656f45ec7bSml29623 }
9666f45ec7bSml29623 
9676f45ec7bSml29623 nxge_status_t
nxge_init_fzc_rxdma_port(p_nxge_t nxgep)9686f45ec7bSml29623 nxge_init_fzc_rxdma_port(p_nxge_t nxgep)
9696f45ec7bSml29623 {
9706f45ec7bSml29623 	npi_handle_t		handle;
9716f45ec7bSml29623 	p_nxge_dma_pt_cfg_t	p_all_cfgp;
9726f45ec7bSml29623 	p_nxge_hw_pt_cfg_t	p_cfgp;
9736f45ec7bSml29623 	hostinfo_t 		hostinfo;
9746f45ec7bSml29623 	int			i;
9756f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
9766f45ec7bSml29623 	p_nxge_class_pt_cfg_t 	p_class_cfgp;
9776f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port"));
9786f45ec7bSml29623 
9796f45ec7bSml29623 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
9806f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
9816f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
9826f45ec7bSml29623 	/*
9836f45ec7bSml29623 	 * Initialize the port scheduler DRR weight.
9846f45ec7bSml29623 	 * npi_rxdma_cfg_port_ddr_weight();
9856f45ec7bSml29623 	 */
9866f45ec7bSml29623 
9876f45ec7bSml29623 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
9882e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_FIBER) ||
98900161856Syc148097 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
9902e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
9916f45ec7bSml29623 		rs = npi_rxdma_cfg_port_ddr_weight(handle,
9922e59129aSraghus 		    nxgep->function_num, NXGE_RX_DRR_WT_1G);
9936f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
9946f45ec7bSml29623 			return (NXGE_ERROR | rs);
9956f45ec7bSml29623 		}
9966f45ec7bSml29623 	}
9976f45ec7bSml29623 
9986f45ec7bSml29623 	/* Program the default RDC of a port */
9996f45ec7bSml29623 	rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num,
10006f45ec7bSml29623 	    p_cfgp->def_rdc);
10016f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
10026f45ec7bSml29623 		return (NXGE_ERROR | rs);
10036f45ec7bSml29623 	}
10046f45ec7bSml29623 
10056f45ec7bSml29623 	/*
10066f45ec7bSml29623 	 * Configure the MAC host info table with RDC tables
10076f45ec7bSml29623 	 */
10086f45ec7bSml29623 	hostinfo.value = 0;
10096f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10106f45ec7bSml29623 	for (i = 0; i < p_cfgp->max_macs; i++) {
1011678453a8Sspeer 		hostinfo.bits.w0.rdc_tbl_num = p_cfgp->def_mac_rxdma_grpid;
10126f45ec7bSml29623 		hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref;
10136f45ec7bSml29623 		if (p_class_cfgp->mac_host_info[i].flag) {
10146f45ec7bSml29623 			hostinfo.bits.w0.rdc_tbl_num =
10156f45ec7bSml29623 			    p_class_cfgp->mac_host_info[i].rdctbl;
10166f45ec7bSml29623 			hostinfo.bits.w0.mac_pref =
10176f45ec7bSml29623 			    p_class_cfgp->mac_host_info[i].mpr_npr;
10186f45ec7bSml29623 		}
10196f45ec7bSml29623 
10206f45ec7bSml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
10216f45ec7bSml29623 		    nxgep->function_num, i, &hostinfo);
10226f45ec7bSml29623 		if (rs != NPI_SUCCESS)
10236f45ec7bSml29623 			return (NXGE_ERROR | rs);
10246f45ec7bSml29623 	}
10256f45ec7bSml29623 
10266f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
10276f45ec7bSml29623 	    "<== nxge_init_fzc_rxdma_port rs 0x%08x", rs));
10286f45ec7bSml29623 
10296f45ec7bSml29623 	return (NXGE_OK);
10306f45ec7bSml29623 
10316f45ec7bSml29623 }
10326f45ec7bSml29623 
10336f45ec7bSml29623 nxge_status_t
nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep,uint8_t port,uint16_t rdc)10346f45ec7bSml29623 nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc)
10356f45ec7bSml29623 {
10366f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
10376f45ec7bSml29623 	rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle,
10386f45ec7bSml29623 	    port, rdc);
10396f45ec7bSml29623 	if (rs & NPI_FAILURE)
10406f45ec7bSml29623 		return (NXGE_ERROR | rs);
10416f45ec7bSml29623 	return (NXGE_OK);
10426f45ec7bSml29623 }
10436f45ec7bSml29623 
1044678453a8Sspeer /*
1045678453a8Sspeer  * nxge_init_fzc_tdc_pages
1046678453a8Sspeer  *
1047678453a8Sspeer  *	Configure a TDC's logical pages.
1048678453a8Sspeer  *
1049678453a8Sspeer  *	This function is executed by the service domain, on behalf of
1050678453a8Sspeer  *	a guest domain, to whom this TDC has been loaned.
1051678453a8Sspeer  *
1052678453a8Sspeer  * Arguments:
1053678453a8Sspeer  * 	nxgep
1054678453a8Sspeer  * 	channel		The channel to initialize.
1055678453a8Sspeer  * 	page0		Logical page 0 definition.
1056678453a8Sspeer  * 	page1		Logical page 1 definition.
1057678453a8Sspeer  *
1058678453a8Sspeer  * Notes:
1059678453a8Sspeer  *	I think that this function can be called from any
1060678453a8Sspeer  *	domain, but I need to check.
1061678453a8Sspeer  *
1062678453a8Sspeer  * NPI/NXGE function calls:
1063678453a8Sspeer  *	hv_niu_tx_logical_page_conf()
1064678453a8Sspeer  *	hv_niu_tx_logical_page_info()
1065678453a8Sspeer  *
1066678453a8Sspeer  * Context:
1067678453a8Sspeer  *	Any domain
1068678453a8Sspeer  */
1069678453a8Sspeer 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)1070678453a8Sspeer nxge_init_fzc_tdc_pages(
1071678453a8Sspeer 	p_nxge_t nxgep,
1072678453a8Sspeer 	uint16_t channel,
1073678453a8Sspeer 	dma_log_page_t *page0,
1074678453a8Sspeer 	dma_log_page_t *page1)
1075678453a8Sspeer {
1076678453a8Sspeer 	npi_handle_t handle;
1077678453a8Sspeer 	npi_status_t rs;
1078678453a8Sspeer 
1079678453a8Sspeer 	log_page_hdl_t page_handle;
1080678453a8Sspeer 
1081678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1082678453a8Sspeer 	    "==> nxge_init_fzc_txdma_channel_pages"));
1083678453a8Sspeer 
1084678453a8Sspeer #ifndef	NIU_HV_WORKAROUND
1085678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
1086678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1087678453a8Sspeer 		    "<== nxge_init_fzc_tdc_pages: "
1088678453a8Sspeer 		    "N2_NIU: no need to set txdma logical pages"));
1089678453a8Sspeer 		return (NXGE_OK);
1090678453a8Sspeer 	}
1091678453a8Sspeer #else
1092678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
1093678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1094678453a8Sspeer 		    "<== nxge_init_fzc_tdc_pages: "
1095678453a8Sspeer 		    "N2_NIU: NEED to set txdma logical pages"));
1096678453a8Sspeer 	}
1097678453a8Sspeer #endif
1098678453a8Sspeer 
1099678453a8Sspeer 	/*
1100678453a8Sspeer 	 * Initialize logical page 1.
1101678453a8Sspeer 	 */
1102678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
1103678453a8Sspeer 	if ((rs = npi_txdma_log_page_set(handle, channel, page0))
1104678453a8Sspeer 	    != NPI_SUCCESS)
1105678453a8Sspeer 		return (NXGE_ERROR | rs);
1106678453a8Sspeer 
1107678453a8Sspeer 	/*
1108678453a8Sspeer 	 * Initialize logical page 2.
1109678453a8Sspeer 	 */
1110678453a8Sspeer 	if ((rs = npi_txdma_log_page_set(handle, channel, page1))
1111678453a8Sspeer 	    != NPI_SUCCESS)
1112678453a8Sspeer 		return (NXGE_ERROR | rs);
1113678453a8Sspeer 
1114678453a8Sspeer 	/*
1115678453a8Sspeer 	 * Initialize the page handle.
1116678453a8Sspeer 	 * (In the current driver, this is always set to 0.)
1117678453a8Sspeer 	 */
1118678453a8Sspeer 	page_handle.value = 0;
1119678453a8Sspeer 	rs = npi_txdma_log_page_handle_set(handle, channel, &page_handle);
1120678453a8Sspeer 	if (rs == NPI_SUCCESS) {
1121678453a8Sspeer 		return (NXGE_OK);
1122678453a8Sspeer 	} else {
1123678453a8Sspeer 		return (NXGE_ERROR | rs);
1124678453a8Sspeer 	}
1125678453a8Sspeer }
1126678453a8Sspeer 
11276f45ec7bSml29623 nxge_status_t
nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_tx_ring_t tx_ring_p)11286f45ec7bSml29623 nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
11296f45ec7bSml29623 	p_tx_ring_t tx_ring_p)
11306f45ec7bSml29623 {
11316f45ec7bSml29623 	npi_handle_t		handle;
11326f45ec7bSml29623 	dma_log_page_t		cfg;
11336f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
11346f45ec7bSml29623 
11356f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
11366f45ec7bSml29623 	    "==> nxge_init_fzc_txdma_channel_pages"));
11376f45ec7bSml29623 
11386f45ec7bSml29623 #ifndef	NIU_HV_WORKAROUND
11396f45ec7bSml29623 	if (nxgep->niu_type == N2_NIU) {
11406f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
11416f45ec7bSml29623 		    "<== nxge_init_fzc_txdma_channel_pages: "
11426f45ec7bSml29623 		    "N2_NIU: no need to set txdma logical pages"));
11436f45ec7bSml29623 		return (NXGE_OK);
11446f45ec7bSml29623 	}
11456f45ec7bSml29623 #else
11466f45ec7bSml29623 	if (nxgep->niu_type == N2_NIU) {
11476f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
11486f45ec7bSml29623 		    "<== nxge_init_fzc_txdma_channel_pages: "
11496f45ec7bSml29623 		    "N2_NIU: NEED to set txdma logical pages"));
11506f45ec7bSml29623 	}
11516f45ec7bSml29623 #endif
11526f45ec7bSml29623 
11536f45ec7bSml29623 	/*
11546f45ec7bSml29623 	 * Initialize logical page 1.
11556f45ec7bSml29623 	 */
11566f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
11576f45ec7bSml29623 	cfg.func_num = nxgep->function_num;
11586f45ec7bSml29623 	cfg.page_num = 0;
11596f45ec7bSml29623 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page0;
11606f45ec7bSml29623 	cfg.value = tx_ring_p->page_value_1.value;
11616f45ec7bSml29623 	cfg.mask = tx_ring_p->page_mask_1.value;
11626f45ec7bSml29623 	cfg.reloc = tx_ring_p->page_reloc_1.value;
11636f45ec7bSml29623 
11646f45ec7bSml29623 	rs = npi_txdma_log_page_set(handle, channel,
11656f45ec7bSml29623 	    (p_dma_log_page_t)&cfg);
11666f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
11676f45ec7bSml29623 		return (NXGE_ERROR | rs);
11686f45ec7bSml29623 	}
11696f45ec7bSml29623 
11706f45ec7bSml29623 	/*
11716f45ec7bSml29623 	 * Initialize logical page 2.
11726f45ec7bSml29623 	 */
11736f45ec7bSml29623 	cfg.page_num = 1;
11746f45ec7bSml29623 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page1;
11756f45ec7bSml29623 	cfg.value = tx_ring_p->page_value_2.value;
11766f45ec7bSml29623 	cfg.mask = tx_ring_p->page_mask_2.value;
11776f45ec7bSml29623 	cfg.reloc = tx_ring_p->page_reloc_2.value;
11786f45ec7bSml29623 
11796f45ec7bSml29623 	rs = npi_txdma_log_page_set(handle, channel, &cfg);
11806f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
11816f45ec7bSml29623 		return (NXGE_ERROR | rs);
11826f45ec7bSml29623 	}
11836f45ec7bSml29623 
11846f45ec7bSml29623 	/* Initialize the page handle */
11856f45ec7bSml29623 	rs = npi_txdma_log_page_handle_set(handle, channel,
11866f45ec7bSml29623 	    &tx_ring_p->page_hdl);
11876f45ec7bSml29623 
11886f45ec7bSml29623 	if (rs == NPI_SUCCESS) {
11896f45ec7bSml29623 		return (NXGE_OK);
11906f45ec7bSml29623 	} else {
11916f45ec7bSml29623 		return (NXGE_ERROR | rs);
11926f45ec7bSml29623 	}
11936f45ec7bSml29623 }
11946f45ec7bSml29623 
11956f45ec7bSml29623 
11966f45ec7bSml29623 nxge_status_t
nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep,uint16_t channel,p_tx_ring_t tx_ring_p)11976f45ec7bSml29623 nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel,
11986f45ec7bSml29623 	p_tx_ring_t tx_ring_p)
11996f45ec7bSml29623 {
12006f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
12016f45ec7bSml29623 	npi_handle_t	handle;
12026f45ec7bSml29623 
12036f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
12046f45ec7bSml29623 	rs = npi_txc_dma_max_burst_set(handle, channel,
12056f45ec7bSml29623 	    tx_ring_p->max_burst.value);
12066f45ec7bSml29623 	if (rs == NPI_SUCCESS) {
12076f45ec7bSml29623 		return (NXGE_OK);
12086f45ec7bSml29623 	} else {
12096f45ec7bSml29623 		return (NXGE_ERROR | rs);
12106f45ec7bSml29623 	}
12116f45ec7bSml29623 }
12126f45ec7bSml29623 
12136f45ec7bSml29623 nxge_status_t
nxge_fzc_sys_err_mask_set(p_nxge_t nxgep,uint64_t mask)12146f45ec7bSml29623 nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask)
12156f45ec7bSml29623 {
12166f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
12176f45ec7bSml29623 	npi_handle_t	handle;
12186f45ec7bSml29623 
12196f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
12206f45ec7bSml29623 	rs = npi_fzc_sys_err_mask_set(handle, mask);
12216f45ec7bSml29623 	if (rs == NPI_SUCCESS) {
12226f45ec7bSml29623 		return (NXGE_OK);
12236f45ec7bSml29623 	} else {
12246f45ec7bSml29623 		return (NXGE_ERROR | rs);
12256f45ec7bSml29623 	}
12266f45ec7bSml29623 }
12276f45ec7bSml29623 
1228678453a8Sspeer /*
1229678453a8Sspeer  * nxge_init_hv_fzc_txdma_channel_pages
1230678453a8Sspeer  *
1231678453a8Sspeer  *	Configure a TDC's logical pages.
1232678453a8Sspeer  *
1233678453a8Sspeer  * Arguments:
1234678453a8Sspeer  * 	nxgep
1235678453a8Sspeer  * 	channel		The channel to initialize.
1236678453a8Sspeer  * 	tx_ring_p	The transmit ring.
1237678453a8Sspeer  *
1238678453a8Sspeer  * Notes:
1239678453a8Sspeer  *	I think that this function can be called from any
1240678453a8Sspeer  *	domain, but I need to check.
1241678453a8Sspeer  *
1242678453a8Sspeer  * NPI/NXGE function calls:
1243678453a8Sspeer  *	hv_niu_tx_logical_page_conf()
1244678453a8Sspeer  *	hv_niu_tx_logical_page_info()
1245678453a8Sspeer  *
1246678453a8Sspeer  * Context:
1247678453a8Sspeer  *	Any domain
1248678453a8Sspeer  */
12496f45ec7bSml29623 #if defined(sun4v) && defined(NIU_LP_WORKAROUND)
12506f45ec7bSml29623 nxge_status_t
nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_tx_ring_t tx_ring_p)12516f45ec7bSml29623 nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
12526f45ec7bSml29623 	p_tx_ring_t tx_ring_p)
12536f45ec7bSml29623 {
12546f45ec7bSml29623 	int			err;
12556f45ec7bSml29623 	uint64_t		hverr;
12566f45ec7bSml29623 #ifdef	DEBUG
12576f45ec7bSml29623 	uint64_t		ra, size;
12586f45ec7bSml29623 #endif
12596f45ec7bSml29623 
12606f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
12616f45ec7bSml29623 	    "==> nxge_init_hv_fzc_txdma_channel_pages"));
12626f45ec7bSml29623 
12636f45ec7bSml29623 	if (tx_ring_p->hv_set) {
12646f45ec7bSml29623 		return (NXGE_OK);
12656f45ec7bSml29623 	}
12666f45ec7bSml29623 
12676f45ec7bSml29623 	/*
12686f45ec7bSml29623 	 * Initialize logical page 1 for data buffers.
12696f45ec7bSml29623 	 */
1270*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1271*4df55fdeSJanie Lu 	    (uint64_t)0, N2NIU_TX_LP_CONF,
12726f45ec7bSml29623 	    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
12736f45ec7bSml29623 	    tx_ring_p->hv_tx_buf_ioaddr_size);
12746f45ec7bSml29623 
12756f45ec7bSml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
12766f45ec7bSml29623 	if (err != 0) {
12776f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12786f45ec7bSml29623 		    "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d "
12796f45ec7bSml29623 		    "error status 0x%x "
12806f45ec7bSml29623 		    "(page 0 data buf) hverr 0x%llx "
12816f45ec7bSml29623 		    "ioaddr_pp $%p "
12826f45ec7bSml29623 		    "size 0x%llx ",
12836f45ec7bSml29623 		    channel,
12846f45ec7bSml29623 		    err,
12856f45ec7bSml29623 		    hverr,
12866f45ec7bSml29623 		    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
12876f45ec7bSml29623 		    tx_ring_p->hv_tx_buf_ioaddr_size));
12886f45ec7bSml29623 		return (NXGE_ERROR | err);
12896f45ec7bSml29623 	}
12906f45ec7bSml29623 
12916f45ec7bSml29623 #ifdef	DEBUG
12926f45ec7bSml29623 	ra = size = 0;
1293*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1294*4df55fdeSJanie Lu 	    (uint64_t)0, N2NIU_TX_LP_INFO,
1295*4df55fdeSJanie Lu 	    (uint64_t)&ra, (uint64_t)&size);
12966f45ec7bSml29623 
12976f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
12986f45ec7bSml29623 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
12996f45ec7bSml29623 	    "ok status 0x%x "
13006f45ec7bSml29623 	    "(page 0 data buf) hverr 0x%llx "
13016f45ec7bSml29623 	    "set ioaddr_pp $%p "
13026f45ec7bSml29623 	    "set size 0x%llx "
13036f45ec7bSml29623 	    "get ra ioaddr_pp $%p "
13046f45ec7bSml29623 	    "get size 0x%llx ",
13056f45ec7bSml29623 	    channel,
13066f45ec7bSml29623 	    err,
13076f45ec7bSml29623 	    hverr,
13086f45ec7bSml29623 	    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
13096f45ec7bSml29623 	    tx_ring_p->hv_tx_buf_ioaddr_size,
13106f45ec7bSml29623 	    ra,
13116f45ec7bSml29623 	    size));
13126f45ec7bSml29623 #endif
13136f45ec7bSml29623 
13146f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13156f45ec7bSml29623 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
13166f45ec7bSml29623 	    "(page 0 data buf) hverr 0x%llx "
13176f45ec7bSml29623 	    "ioaddr_pp $%p "
13186f45ec7bSml29623 	    "size 0x%llx ",
13196f45ec7bSml29623 	    channel,
13206f45ec7bSml29623 	    hverr,
13216f45ec7bSml29623 	    tx_ring_p->hv_tx_buf_base_ioaddr_pp,
13226f45ec7bSml29623 	    tx_ring_p->hv_tx_buf_ioaddr_size));
13236f45ec7bSml29623 
13246f45ec7bSml29623 	/*
13256f45ec7bSml29623 	 * Initialize logical page 2 for control buffers.
13266f45ec7bSml29623 	 */
1327*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1328*4df55fdeSJanie Lu 	    (uint64_t)1, N2NIU_TX_LP_CONF,
13296f45ec7bSml29623 	    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13306f45ec7bSml29623 	    tx_ring_p->hv_tx_cntl_ioaddr_size);
13316f45ec7bSml29623 
13326f45ec7bSml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
13336f45ec7bSml29623 
13346f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13356f45ec7bSml29623 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d"
13366f45ec7bSml29623 	    "ok status 0x%x "
13376f45ec7bSml29623 	    "(page 1 cntl buf) hverr 0x%llx "
13386f45ec7bSml29623 	    "ioaddr_pp $%p "
13396f45ec7bSml29623 	    "size 0x%llx ",
13406f45ec7bSml29623 	    channel,
13416f45ec7bSml29623 	    err,
13426f45ec7bSml29623 	    hverr,
13436f45ec7bSml29623 	    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13446f45ec7bSml29623 	    tx_ring_p->hv_tx_cntl_ioaddr_size));
13456f45ec7bSml29623 
13466f45ec7bSml29623 	if (err != 0) {
13476f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13486f45ec7bSml29623 		    "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d"
13496f45ec7bSml29623 		    "error status 0x%x "
13506f45ec7bSml29623 		    "(page 1 cntl buf) hverr 0x%llx "
13516f45ec7bSml29623 		    "ioaddr_pp $%p "
13526f45ec7bSml29623 		    "size 0x%llx ",
13536f45ec7bSml29623 		    channel,
13546f45ec7bSml29623 		    err,
13556f45ec7bSml29623 		    hverr,
13566f45ec7bSml29623 		    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13576f45ec7bSml29623 		    tx_ring_p->hv_tx_cntl_ioaddr_size));
13586f45ec7bSml29623 		return (NXGE_ERROR | err);
13596f45ec7bSml29623 	}
13606f45ec7bSml29623 
13616f45ec7bSml29623 #ifdef	DEBUG
13626f45ec7bSml29623 	ra = size = 0;
1363*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1364*4df55fdeSJanie Lu 	    (uint64_t)1, N2NIU_TX_LP_INFO,
1365*4df55fdeSJanie Lu 	    (uint64_t)&ra, (uint64_t)&size);
13666f45ec7bSml29623 
13676f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13686f45ec7bSml29623 	    "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
13696f45ec7bSml29623 	    "(page 1 cntl buf) hverr 0x%llx "
13706f45ec7bSml29623 	    "set ioaddr_pp $%p "
13716f45ec7bSml29623 	    "set size 0x%llx "
13726f45ec7bSml29623 	    "get ra ioaddr_pp $%p "
13736f45ec7bSml29623 	    "get size 0x%llx ",
13746f45ec7bSml29623 	    channel,
13756f45ec7bSml29623 	    hverr,
13766f45ec7bSml29623 	    tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
13776f45ec7bSml29623 	    tx_ring_p->hv_tx_cntl_ioaddr_size,
13786f45ec7bSml29623 	    ra,
13796f45ec7bSml29623 	    size));
13806f45ec7bSml29623 #endif
13816f45ec7bSml29623 
13826f45ec7bSml29623 	tx_ring_p->hv_set = B_TRUE;
13836f45ec7bSml29623 
13846f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
13856f45ec7bSml29623 	    "<== nxge_init_hv_fzc_txdma_channel_pages"));
13866f45ec7bSml29623 
13876f45ec7bSml29623 	return (NXGE_OK);
13886f45ec7bSml29623 }
13896f45ec7bSml29623 
13906f45ec7bSml29623 /*ARGSUSED*/
13916f45ec7bSml29623 nxge_status_t
nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_rx_rbr_ring_t rbrp)13926f45ec7bSml29623 nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep,
13936f45ec7bSml29623 		uint16_t channel, p_rx_rbr_ring_t rbrp)
13946f45ec7bSml29623 {
13956f45ec7bSml29623 	int			err;
13966f45ec7bSml29623 	uint64_t		hverr;
13976f45ec7bSml29623 #ifdef	DEBUG
13986f45ec7bSml29623 	uint64_t		ra, size;
13996f45ec7bSml29623 #endif
14006f45ec7bSml29623 
14016f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
14026f45ec7bSml29623 	    "==> nxge_init_hv_fzc_rxdma_channel_pages"));
14036f45ec7bSml29623 
14046f45ec7bSml29623 	if (rbrp->hv_set) {
14056f45ec7bSml29623 		return (NXGE_OK);
14066f45ec7bSml29623 	}
14076f45ec7bSml29623 
14086f45ec7bSml29623 	/* Initialize data buffers for page 0 */
1409*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1410*4df55fdeSJanie Lu 	    (uint64_t)0, N2NIU_RX_LP_CONF,
14116f45ec7bSml29623 	    rbrp->hv_rx_buf_base_ioaddr_pp,
14126f45ec7bSml29623 	    rbrp->hv_rx_buf_ioaddr_size);
1413*4df55fdeSJanie Lu 
14146f45ec7bSml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
14156f45ec7bSml29623 	if (err != 0) {
14166f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14176f45ec7bSml29623 		    "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
14186f45ec7bSml29623 		    "error status 0x%x "
14196f45ec7bSml29623 		    "(page 0 data buf) hverr 0x%llx "
14206f45ec7bSml29623 		    "ioaddr_pp $%p "
14216f45ec7bSml29623 		    "size 0x%llx ",
14226f45ec7bSml29623 		    channel,
14236f45ec7bSml29623 		    err,
14246f45ec7bSml29623 		    hverr,
14256f45ec7bSml29623 		    rbrp->hv_rx_buf_base_ioaddr_pp,
14266f45ec7bSml29623 		    rbrp->hv_rx_buf_ioaddr_size));
14276f45ec7bSml29623 
14286f45ec7bSml29623 		return (NXGE_ERROR | err);
14296f45ec7bSml29623 	}
14306f45ec7bSml29623 
14316f45ec7bSml29623 #ifdef	DEBUG
14326f45ec7bSml29623 	ra = size = 0;
1433*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1434*4df55fdeSJanie Lu 	    (uint64_t)0, N2NIU_RX_LP_INFO,
1435*4df55fdeSJanie Lu 	    (uint64_t)&ra, (uint64_t)&size);
14366f45ec7bSml29623 
14376f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
14386f45ec7bSml29623 	    "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
14396f45ec7bSml29623 	    "ok status 0x%x "
14406f45ec7bSml29623 	    "(page 0 data buf) hverr 0x%llx "
14416f45ec7bSml29623 	    "set databuf ioaddr_pp $%p "
14426f45ec7bSml29623 	    "set databuf size 0x%llx "
14436f45ec7bSml29623 	    "get databuf ra ioaddr_pp %p "
14446f45ec7bSml29623 	    "get databuf size 0x%llx",
14456f45ec7bSml29623 	    channel,
14466f45ec7bSml29623 	    err,
14476f45ec7bSml29623 	    hverr,
14486f45ec7bSml29623 	    rbrp->hv_rx_buf_base_ioaddr_pp,
14496f45ec7bSml29623 	    rbrp->hv_rx_buf_ioaddr_size,
14506f45ec7bSml29623 	    ra,
14516f45ec7bSml29623 	    size));
14526f45ec7bSml29623 #endif
14536f45ec7bSml29623 
14546f45ec7bSml29623 	/* Initialize control buffers for logical page 1.  */
1455*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1456*4df55fdeSJanie Lu 	    (uint64_t)1, N2NIU_RX_LP_CONF,
14576f45ec7bSml29623 	    rbrp->hv_rx_cntl_base_ioaddr_pp,
14586f45ec7bSml29623 	    rbrp->hv_rx_cntl_ioaddr_size);
14596f45ec7bSml29623 
14606f45ec7bSml29623 	err = (nxge_status_t)nxge_herr2kerr(hverr);
14616f45ec7bSml29623 	if (err != 0) {
14626f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14636f45ec7bSml29623 		    "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
14646f45ec7bSml29623 		    "error status 0x%x "
14656f45ec7bSml29623 		    "(page 1 cntl buf) hverr 0x%llx "
14666f45ec7bSml29623 		    "ioaddr_pp $%p "
14676f45ec7bSml29623 		    "size 0x%llx ",
14686f45ec7bSml29623 		    channel,
14696f45ec7bSml29623 		    err,
14706f45ec7bSml29623 		    hverr,
14716f45ec7bSml29623 		    rbrp->hv_rx_buf_base_ioaddr_pp,
14726f45ec7bSml29623 		    rbrp->hv_rx_buf_ioaddr_size));
14736f45ec7bSml29623 
14746f45ec7bSml29623 		return (NXGE_ERROR | err);
14756f45ec7bSml29623 	}
14766f45ec7bSml29623 
14776f45ec7bSml29623 #ifdef	DEBUG
14786f45ec7bSml29623 	ra = size = 0;
1479*4df55fdeSJanie Lu 	hverr = nxge_init_hv_fzc_lp_op(nxgep, (uint64_t)channel,
1480*4df55fdeSJanie Lu 	    (uint64_t)1, N2NIU_RX_LP_INFO,
1481*4df55fdeSJanie Lu 	    (uint64_t)&ra, (uint64_t)&size);
14826f45ec7bSml29623 
14836f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
14846f45ec7bSml29623 	    "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
14856f45ec7bSml29623 	    "error status 0x%x "
14866f45ec7bSml29623 	    "(page 1 cntl buf) hverr 0x%llx "
14876f45ec7bSml29623 	    "set cntl ioaddr_pp $%p "
14886f45ec7bSml29623 	    "set cntl size 0x%llx "
14896f45ec7bSml29623 	    "get cntl ioaddr_pp $%p "
14906f45ec7bSml29623 	    "get cntl size 0x%llx ",
14916f45ec7bSml29623 	    channel,
14926f45ec7bSml29623 	    err,
14936f45ec7bSml29623 	    hverr,
14946f45ec7bSml29623 	    rbrp->hv_rx_cntl_base_ioaddr_pp,
14956f45ec7bSml29623 	    rbrp->hv_rx_cntl_ioaddr_size,
14966f45ec7bSml29623 	    ra,
14976f45ec7bSml29623 	    size));
14986f45ec7bSml29623 #endif
14996f45ec7bSml29623 
15006f45ec7bSml29623 	rbrp->hv_set = B_FALSE;
15016f45ec7bSml29623 
15026f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
15036f45ec7bSml29623 	    "<== nxge_init_hv_fzc_rxdma_channel_pages"));
15046f45ec7bSml29623 
15056f45ec7bSml29623 	return (NXGE_OK);
15066f45ec7bSml29623 }
15076f45ec7bSml29623 
15086f45ec7bSml29623 /*
15096f45ec7bSml29623  * Map hypervisor error code to errno. Only
15106f45ec7bSml29623  * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful
15116f45ec7bSml29623  * for niu driver. Any other error codes are mapped to EINVAL.
15126f45ec7bSml29623  */
15136f45ec7bSml29623 static int
nxge_herr2kerr(uint64_t hv_errcode)15146f45ec7bSml29623 nxge_herr2kerr(uint64_t hv_errcode)
15156f45ec7bSml29623 {
15166f45ec7bSml29623 	int	s_errcode;
15176f45ec7bSml29623 
15186f45ec7bSml29623 	switch (hv_errcode) {
15196f45ec7bSml29623 	case H_ENORADDR:
15206f45ec7bSml29623 	case H_EBADALIGN:
15216f45ec7bSml29623 		s_errcode = EFAULT;
15226f45ec7bSml29623 		break;
15236f45ec7bSml29623 	case H_EOK:
15246f45ec7bSml29623 		s_errcode = 0;
15256f45ec7bSml29623 		break;
15266f45ec7bSml29623 	default:
15276f45ec7bSml29623 		s_errcode = EINVAL;
15286f45ec7bSml29623 		break;
15296f45ec7bSml29623 	}
15306f45ec7bSml29623 	return (s_errcode);
15316f45ec7bSml29623 }
15326f45ec7bSml29623 
1533*4df55fdeSJanie Lu 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*4df55fdeSJanie Lu nxge_init_hv_fzc_lp_op(p_nxge_t nxgep, uint64_t channel,
1535*4df55fdeSJanie Lu     uint64_t page_no, uint64_t op_type,
1536*4df55fdeSJanie Lu     uint64_t ioaddr_pp, uint64_t ioaddr_size)
1537*4df55fdeSJanie Lu {
1538*4df55fdeSJanie Lu 	uint64_t		hverr;
1539*4df55fdeSJanie Lu 	uint64_t		major;
1540*4df55fdeSJanie Lu 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxgep->nxge_hw_p->hio;
1541*4df55fdeSJanie Lu 	nxhv_dc_fp_t		*io_fp;
1542*4df55fdeSJanie Lu 
1543*4df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1544*4df55fdeSJanie Lu 	    "==> nxge_init_hv_fzc_lp_op"));
1545*4df55fdeSJanie Lu 
1546*4df55fdeSJanie Lu 	major = nxgep->niu_hsvc.hsvc_major;
1547*4df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, NXGE_ERR_CTL,
1548*4df55fdeSJanie Lu 	    "==> nxge_init_hv_fzc_lp_op (major %d): channel %d op_type 0x%x "
1549*4df55fdeSJanie Lu 	    "page_no %d ioaddr_pp $%p ioaddr_size 0x%llx",
1550*4df55fdeSJanie Lu 	    major, channel, op_type, page_no, ioaddr_pp, ioaddr_size));
1551*4df55fdeSJanie Lu 
1552*4df55fdeSJanie Lu 	/* Call the transmit conf function. */
1553*4df55fdeSJanie Lu 	switch (major) {
1554*4df55fdeSJanie Lu 	case NIU_MAJOR_VER: /* 1 */
1555*4df55fdeSJanie Lu 		switch (op_type) {
1556*4df55fdeSJanie Lu 		case N2NIU_TX_LP_CONF:
1557*4df55fdeSJanie Lu 			io_fp = &nhd->hio.tx;
1558*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_conf)((uint64_t)channel,
1559*4df55fdeSJanie Lu 			    (uint64_t)page_no,
1560*4df55fdeSJanie Lu 			    (uint64_t)ioaddr_pp,
1561*4df55fdeSJanie Lu 			    (uint64_t)ioaddr_size);
1562*4df55fdeSJanie Lu 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1563*4df55fdeSJanie Lu 			    "==> nxge_init_hv_fzc_lp_op(tx_conf): major %d "
1564*4df55fdeSJanie Lu 			    "op 0x%x hverr 0x%x", major, op_type, hverr));
1565*4df55fdeSJanie Lu 			break;
1566*4df55fdeSJanie Lu 
1567*4df55fdeSJanie Lu 		case N2NIU_TX_LP_INFO:
1568*4df55fdeSJanie Lu 			io_fp = &nhd->hio.tx;
1569*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_info)((uint64_t)channel,
1570*4df55fdeSJanie Lu 			    (uint64_t)page_no,
1571*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_pp,
1572*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_size);
1573*4df55fdeSJanie Lu 			break;
1574*4df55fdeSJanie Lu 
1575*4df55fdeSJanie Lu 		case N2NIU_RX_LP_CONF:
1576*4df55fdeSJanie Lu 			io_fp = &nhd->hio.rx;
1577*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_conf)((uint64_t)channel,
1578*4df55fdeSJanie Lu 			    (uint64_t)page_no,
1579*4df55fdeSJanie Lu 			    (uint64_t)ioaddr_pp,
1580*4df55fdeSJanie Lu 			    (uint64_t)ioaddr_size);
1581*4df55fdeSJanie Lu 			break;
1582*4df55fdeSJanie Lu 
1583*4df55fdeSJanie Lu 		case N2NIU_RX_LP_INFO:
1584*4df55fdeSJanie Lu 			io_fp = &nhd->hio.rx;
1585*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_info)((uint64_t)channel,
1586*4df55fdeSJanie Lu 			    (uint64_t)page_no,
1587*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_pp,
1588*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_size);
1589*4df55fdeSJanie Lu 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1590*4df55fdeSJanie Lu 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1591*4df55fdeSJanie Lu 			    "op 0x%x hverr 0x%x", major, op_type, hverr));
1592*4df55fdeSJanie Lu 			break;
1593*4df55fdeSJanie Lu 
1594*4df55fdeSJanie Lu 		default:
1595*4df55fdeSJanie Lu 			hverr = EINVAL;
1596*4df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1597*4df55fdeSJanie Lu 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1598*4df55fdeSJanie Lu 			    "invalid op 0x%x hverr 0x%x", major,
1599*4df55fdeSJanie Lu 			    op_type, hverr));
1600*4df55fdeSJanie Lu 			break;
1601*4df55fdeSJanie Lu 		}
1602*4df55fdeSJanie Lu 
1603*4df55fdeSJanie Lu 		break;
1604*4df55fdeSJanie Lu 
1605*4df55fdeSJanie Lu 	case NIU_MAJOR_VER_2: /* 2 */
1606*4df55fdeSJanie Lu 		switch (op_type) {
1607*4df55fdeSJanie Lu 		case N2NIU_TX_LP_CONF:
1608*4df55fdeSJanie Lu 			io_fp = &nhd->hio.tx;
1609*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_cfgh_conf)(nxgep->niu_cfg_hdl,
1610*4df55fdeSJanie Lu 			    (uint64_t)channel,
1611*4df55fdeSJanie Lu 			    (uint64_t)page_no, ioaddr_pp, ioaddr_size);
1612*4df55fdeSJanie Lu 
1613*4df55fdeSJanie Lu 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1614*4df55fdeSJanie Lu 			    "==> nxge_init_hv_fzc_lp_op(tx_conf): major %d "
1615*4df55fdeSJanie Lu 			    "op 0x%x hverr 0x%x", major, op_type, hverr));
1616*4df55fdeSJanie Lu 			break;
1617*4df55fdeSJanie Lu 
1618*4df55fdeSJanie Lu 		case N2NIU_TX_LP_INFO:
1619*4df55fdeSJanie Lu 			io_fp = &nhd->hio.tx;
1620*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_cfgh_info)(nxgep->niu_cfg_hdl,
1621*4df55fdeSJanie Lu 			    (uint64_t)channel,
1622*4df55fdeSJanie Lu 			    (uint64_t)page_no,
1623*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_pp,
1624*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_size);
1625*4df55fdeSJanie Lu 			break;
1626*4df55fdeSJanie Lu 
1627*4df55fdeSJanie Lu 		case N2NIU_RX_LP_CONF:
1628*4df55fdeSJanie Lu 			io_fp = &nhd->hio.rx;
1629*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_cfgh_conf)(nxgep->niu_cfg_hdl,
1630*4df55fdeSJanie Lu 			    (uint64_t)channel,
1631*4df55fdeSJanie Lu 			    (uint64_t)page_no,
1632*4df55fdeSJanie Lu 			    (uint64_t)ioaddr_pp,
1633*4df55fdeSJanie Lu 			    (uint64_t)ioaddr_size);
1634*4df55fdeSJanie Lu 			NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1635*4df55fdeSJanie Lu 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1636*4df55fdeSJanie Lu 			    "hverr 0x%x", major, hverr));
1637*4df55fdeSJanie Lu 			break;
1638*4df55fdeSJanie Lu 
1639*4df55fdeSJanie Lu 		case N2NIU_RX_LP_INFO:
1640*4df55fdeSJanie Lu 			io_fp = &nhd->hio.rx;
1641*4df55fdeSJanie Lu 			hverr = (*io_fp->lp_cfgh_info)(nxgep->niu_cfg_hdl,
1642*4df55fdeSJanie Lu 			    (uint64_t)channel,
1643*4df55fdeSJanie Lu 			    (uint64_t)page_no,
1644*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_pp,
1645*4df55fdeSJanie Lu 			    (uint64_t *)ioaddr_size);
1646*4df55fdeSJanie Lu 			break;
1647*4df55fdeSJanie Lu 
1648*4df55fdeSJanie Lu 		default:
1649*4df55fdeSJanie Lu 			hverr = EINVAL;
1650*4df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1651*4df55fdeSJanie Lu 			    "==> nxge_init_hv_fzc_lp_op(rx_conf): major %d "
1652*4df55fdeSJanie Lu 			    "invalid op 0x%x hverr 0x%x", major,
1653*4df55fdeSJanie Lu 			    op_type, hverr));
1654*4df55fdeSJanie Lu 			break;
1655*4df55fdeSJanie Lu 		}
1656*4df55fdeSJanie Lu 
1657*4df55fdeSJanie Lu 		break;
1658*4df55fdeSJanie Lu 
1659*4df55fdeSJanie Lu 	default:
1660*4df55fdeSJanie Lu 		hverr = EINVAL;
1661*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1662*4df55fdeSJanie Lu 		    "==> nxge_init_hv_fzc_lp_op(rx_conf): invalid major %d "
1663*4df55fdeSJanie Lu 		    "op 0x%x hverr 0x%x", major, op_type, hverr));
1664*4df55fdeSJanie Lu 		break;
1665*4df55fdeSJanie Lu 	}
1666*4df55fdeSJanie Lu 
1667*4df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1668*4df55fdeSJanie Lu 	    "<== nxge_init_hv_fzc_lp_op: 0x%x", hverr));
1669*4df55fdeSJanie Lu 
1670*4df55fdeSJanie Lu 	return (hverr);
1671*4df55fdeSJanie Lu }
1672*4df55fdeSJanie Lu 
16736f45ec7bSml29623 #endif	/* sun4v and NIU_LP_WORKAROUND */
1674