xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fzc.c (revision 678453a8)
144961713Sgirish /*
244961713Sgirish  * CDDL HEADER START
344961713Sgirish  *
444961713Sgirish  * The contents of this file are subject to the terms of the
544961713Sgirish  * Common Development and Distribution License (the "License").
644961713Sgirish  * You may not use this file except in compliance with the License.
744961713Sgirish  *
844961713Sgirish  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
944961713Sgirish  * or http://www.opensolaris.org/os/licensing.
1044961713Sgirish  * See the License for the specific language governing permissions
1144961713Sgirish  * and limitations under the License.
1244961713Sgirish  *
1344961713Sgirish  * When distributing Covered Code, include this CDDL HEADER in each
1444961713Sgirish  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1544961713Sgirish  * If applicable, add the following below this CDDL HEADER, with the
1644961713Sgirish  * fields enclosed by brackets "[]" replaced with your own identifying
1744961713Sgirish  * information: Portions Copyright [yyyy] [name of copyright owner]
1844961713Sgirish  *
1944961713Sgirish  * CDDL HEADER END
2044961713Sgirish  */
2144961713Sgirish /*
22*678453a8Sspeer  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2344961713Sgirish  * Use is subject to license terms.
2444961713Sgirish  */
2544961713Sgirish 
2644961713Sgirish #pragma ident	"%Z%%M%	%I%	%E% SMI"
2744961713Sgirish 
2844961713Sgirish #include	<nxge_impl.h>
2944961713Sgirish #include	<npi_mac.h>
3044961713Sgirish #include	<npi_rxdma.h>
31*678453a8Sspeer #include	<nxge_hio.h>
3244961713Sgirish 
3344961713Sgirish #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
3444961713Sgirish static int	nxge_herr2kerr(uint64_t);
3544961713Sgirish #endif
3644961713Sgirish 
37*678453a8Sspeer static nxge_status_t nxge_init_fzc_rdc_pages(p_nxge_t,
38*678453a8Sspeer     uint16_t, dma_log_page_t *, dma_log_page_t *);
39*678453a8Sspeer 
40*678453a8Sspeer static nxge_status_t nxge_init_fzc_tdc_pages(p_nxge_t,
41*678453a8Sspeer     uint16_t, dma_log_page_t *, dma_log_page_t *);
42*678453a8Sspeer 
4344961713Sgirish /*
4444961713Sgirish  * The following interfaces are controlled by the
4544961713Sgirish  * function control registers. Some global registers
4644961713Sgirish  * are to be initialized by only byt one of the 2/4 functions.
4744961713Sgirish  * Use the test and set register.
4844961713Sgirish  */
4944961713Sgirish /*ARGSUSED*/
5044961713Sgirish nxge_status_t
5144961713Sgirish nxge_test_and_set(p_nxge_t nxgep, uint8_t tas)
5244961713Sgirish {
5344961713Sgirish 	npi_handle_t		handle;
5444961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
5544961713Sgirish 
5644961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5744961713Sgirish 	if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas))
5844961713Sgirish 			!= NPI_SUCCESS) {
5944961713Sgirish 		return (NXGE_ERROR | rs);
6044961713Sgirish 	}
6144961713Sgirish 
6244961713Sgirish 	return (NXGE_OK);
6344961713Sgirish }
6444961713Sgirish 
6544961713Sgirish nxge_status_t
6644961713Sgirish nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc)
6744961713Sgirish {
6844961713Sgirish 	npi_handle_t		handle;
6944961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
7044961713Sgirish 
7144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl"));
7244961713Sgirish 
7344961713Sgirish 	/*
7444961713Sgirish 	 * In multi-partitioning, the partition manager
7544961713Sgirish 	 * who owns function zero should set this multi-partition
7644961713Sgirish 	 * control bit.
7744961713Sgirish 	 */
7844961713Sgirish 	if (nxgep->use_partition && nxgep->function_num) {
7944961713Sgirish 		return (NXGE_ERROR);
8044961713Sgirish 	}
8144961713Sgirish 
8244961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
8344961713Sgirish 	if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) {
8444961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
8544961713Sgirish 			"<== nxge_set_fzc_multi_part_ctl"));
8644961713Sgirish 		return (NXGE_ERROR | rs);
8744961713Sgirish 	}
8844961713Sgirish 
8944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl"));
9044961713Sgirish 
9144961713Sgirish 	return (NXGE_OK);
9244961713Sgirish }
9344961713Sgirish 
9444961713Sgirish nxge_status_t
9544961713Sgirish nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p)
9644961713Sgirish {
9744961713Sgirish 	npi_handle_t		handle;
9844961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
9944961713Sgirish 
10044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
10144961713Sgirish 
10244961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
10344961713Sgirish 	if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) {
10444961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
10544961713Sgirish 			"<== nxge_set_fzc_multi_part_ctl"));
10644961713Sgirish 		return (NXGE_ERROR | rs);
10744961713Sgirish 	}
10844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
10944961713Sgirish 
11044961713Sgirish 	return (NXGE_OK);
11144961713Sgirish }
11244961713Sgirish 
11344961713Sgirish /*
11444961713Sgirish  * System interrupt registers that are under function zero
11544961713Sgirish  * management.
11644961713Sgirish  */
11744961713Sgirish nxge_status_t
11844961713Sgirish nxge_fzc_intr_init(p_nxge_t nxgep)
11944961713Sgirish {
12044961713Sgirish 	nxge_status_t	status = NXGE_OK;
12144961713Sgirish 
12244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init"));
12344961713Sgirish 
12444961713Sgirish 	/* Configure the initial timer resolution */
12544961713Sgirish 	if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) {
12644961713Sgirish 		return (status);
12744961713Sgirish 	}
12844961713Sgirish 
1292e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
13044961713Sgirish 		/*
13144961713Sgirish 		 * Set up the logical device group's logical devices that
13244961713Sgirish 		 * the group owns.
13344961713Sgirish 		 */
13459ac0c16Sdavemq 		if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK)
13559ac0c16Sdavemq 			goto fzc_intr_init_exit;
13644961713Sgirish 
13744961713Sgirish 		/* Configure the system interrupt data */
13859ac0c16Sdavemq 		if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK)
13959ac0c16Sdavemq 			goto fzc_intr_init_exit;
14044961713Sgirish 	}
14144961713Sgirish 
14259ac0c16Sdavemq fzc_intr_init_exit:
14359ac0c16Sdavemq 
14444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init"));
14544961713Sgirish 
14644961713Sgirish 	return (status);
14744961713Sgirish }
14844961713Sgirish 
14944961713Sgirish nxge_status_t
15044961713Sgirish nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)
15144961713Sgirish {
15244961713Sgirish 	p_nxge_ldg_t	ldgp;
15344961713Sgirish 	p_nxge_ldv_t	ldvp;
15444961713Sgirish 	npi_handle_t	handle;
15544961713Sgirish 	int		i, j;
15644961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
15744961713Sgirish 
15844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set"));
15944961713Sgirish 
16044961713Sgirish 	if (nxgep->ldgvp == NULL) {
16144961713Sgirish 		return (NXGE_ERROR);
16244961713Sgirish 	}
16344961713Sgirish 
16444961713Sgirish 	ldgp = nxgep->ldgvp->ldgp;
16544961713Sgirish 	ldvp = nxgep->ldgvp->ldvp;
16644961713Sgirish 	if (ldgp == NULL || ldvp == NULL) {
16744961713Sgirish 		return (NXGE_ERROR);
16844961713Sgirish 	}
16944961713Sgirish 
17044961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
17144961713Sgirish 
17244961713Sgirish 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
17344961713Sgirish 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
17444961713Sgirish 			"==> nxge_fzc_intr_ldg_num_set "
17544961713Sgirish 			"<== nxge_f(Neptune): # ldv %d "
17644961713Sgirish 			"in group %d", ldgp->nldvs, ldgp->ldg));
17744961713Sgirish 
17844961713Sgirish 		for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
17944961713Sgirish 			rs = npi_fzc_ldg_num_set(handle, ldvp->ldv,
18044961713Sgirish 				ldvp->ldg_assigned);
18144961713Sgirish 			if (rs != NPI_SUCCESS) {
18244961713Sgirish 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
18344961713Sgirish 					"<== nxge_fzc_intr_ldg_num_set failed "
18444961713Sgirish 					" rs 0x%x ldv %d ldg %d",
18544961713Sgirish 					rs, ldvp->ldv, ldvp->ldg_assigned));
18644961713Sgirish 				return (NXGE_ERROR | rs);
18744961713Sgirish 			}
18844961713Sgirish 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
18944961713Sgirish 				"<== nxge_fzc_intr_ldg_num_set OK "
19044961713Sgirish 				" ldv %d ldg %d",
19144961713Sgirish 				ldvp->ldv, ldvp->ldg_assigned));
19244961713Sgirish 		}
19344961713Sgirish 	}
19444961713Sgirish 
19544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set"));
19644961713Sgirish 
19744961713Sgirish 	return (NXGE_OK);
19844961713Sgirish }
19944961713Sgirish 
20044961713Sgirish nxge_status_t
20144961713Sgirish nxge_fzc_intr_tmres_set(p_nxge_t nxgep)
20244961713Sgirish {
20344961713Sgirish 	npi_handle_t	handle;
20444961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
20544961713Sgirish 
20644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set"));
20744961713Sgirish 	if (nxgep->ldgvp == NULL) {
20844961713Sgirish 		return (NXGE_ERROR);
20944961713Sgirish 	}
21044961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
21144961713Sgirish 	if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) {
21244961713Sgirish 		return (NXGE_ERROR | rs);
21344961713Sgirish 	}
21444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set"));
21544961713Sgirish 
21644961713Sgirish 	return (NXGE_OK);
21744961713Sgirish }
21844961713Sgirish 
21944961713Sgirish nxge_status_t
22044961713Sgirish nxge_fzc_intr_sid_set(p_nxge_t nxgep)
22144961713Sgirish {
22244961713Sgirish 	npi_handle_t	handle;
22344961713Sgirish 	p_nxge_ldg_t	ldgp;
22444961713Sgirish 	fzc_sid_t	sid;
22544961713Sgirish 	int		i;
22644961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
22744961713Sgirish 
22844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set"));
22944961713Sgirish 	if (nxgep->ldgvp == NULL) {
23044961713Sgirish 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
23144961713Sgirish 			"<== nxge_fzc_intr_sid_set: no ldg"));
23244961713Sgirish 		return (NXGE_ERROR);
23344961713Sgirish 	}
23444961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
23544961713Sgirish 	ldgp = nxgep->ldgvp->ldgp;
23644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
23744961713Sgirish 		"==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs));
23844961713Sgirish 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
23944961713Sgirish 		sid.ldg = ldgp->ldg;
24044961713Sgirish 		sid.niu = B_FALSE;
24144961713Sgirish 		sid.func = ldgp->func;
24244961713Sgirish 		sid.vector = ldgp->vector;
24344961713Sgirish 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
24444961713Sgirish 			"==> nxge_fzc_intr_sid_set(%d): func %d group %d "
24544961713Sgirish 			"vector %d",
24644961713Sgirish 			i, sid.func, sid.ldg, sid.vector));
24744961713Sgirish 		rs = npi_fzc_sid_set(handle, sid);
24844961713Sgirish 		if (rs != NPI_SUCCESS) {
24944961713Sgirish 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
25044961713Sgirish 				"<== nxge_fzc_intr_sid_set:failed 0x%x",
25144961713Sgirish 				rs));
25244961713Sgirish 			return (NXGE_ERROR | rs);
25344961713Sgirish 		}
25444961713Sgirish 	}
25544961713Sgirish 
25644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set"));
25744961713Sgirish 
25844961713Sgirish 	return (NXGE_OK);
25944961713Sgirish 
26044961713Sgirish }
26144961713Sgirish 
26244961713Sgirish /*
263*678453a8Sspeer  * nxge_init_fzc_rdc
264*678453a8Sspeer  *
265*678453a8Sspeer  *	Initialize all of a RDC's FZC_DMC registers.
266*678453a8Sspeer  *	This is executed by the service domain, on behalf of a
267*678453a8Sspeer  *	guest domain, who cannot access these registers.
268*678453a8Sspeer  *
269*678453a8Sspeer  * Arguments:
270*678453a8Sspeer  * 	nxgep
271*678453a8Sspeer  * 	channel		The channel to initialize.
272*678453a8Sspeer  *
273*678453a8Sspeer  * NPI_NXGE function calls:
274*678453a8Sspeer  *	nxge_init_fzc_rdc_pages()
275*678453a8Sspeer  *
276*678453a8Sspeer  * Context:
277*678453a8Sspeer  *	Service Domain
27844961713Sgirish  */
27944961713Sgirish /*ARGSUSED*/
28044961713Sgirish nxge_status_t
281*678453a8Sspeer nxge_init_fzc_rdc(p_nxge_t nxgep, uint16_t channel)
28244961713Sgirish {
28344961713Sgirish 	nxge_status_t	status = NXGE_OK;
284*678453a8Sspeer 
285*678453a8Sspeer 	dma_log_page_t	page1, page2;
286*678453a8Sspeer 	npi_handle_t	handle;
287*678453a8Sspeer 	rdc_red_para_t	red;
288*678453a8Sspeer 
289*678453a8Sspeer 	/*
290*678453a8Sspeer 	 * Initialize the RxDMA channel-specific FZC control
291*678453a8Sspeer 	 * registers.
292*678453a8Sspeer 	 */
293*678453a8Sspeer 
294*678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc"));
295*678453a8Sspeer 
296*678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
297*678453a8Sspeer 
298*678453a8Sspeer 	/* Reset RXDMA channel */
299*678453a8Sspeer 	status = npi_rxdma_cfg_rdc_reset(handle, channel);
300*678453a8Sspeer 	if (status != NPI_SUCCESS) {
301*678453a8Sspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
302*678453a8Sspeer 		    "==> nxge_init_fzc_rdc: npi_rxdma_cfg_rdc_reset(%d) "
303*678453a8Sspeer 		    "returned 0x%08x", channel, status));
304*678453a8Sspeer 		return (NXGE_ERROR | status);
305*678453a8Sspeer 	}
306*678453a8Sspeer 
307*678453a8Sspeer 	/*
308*678453a8Sspeer 	 * These values have been copied from
309*678453a8Sspeer 	 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring().
310*678453a8Sspeer 	 */
311*678453a8Sspeer 	page1.page_num = 0;
312*678453a8Sspeer 	page1.valid = 1;
313*678453a8Sspeer 	page1.func_num = nxgep->function_num;
314*678453a8Sspeer 	page1.mask = 0;
315*678453a8Sspeer 	page1.value = 0;
316*678453a8Sspeer 	page1.reloc = 0;
317*678453a8Sspeer 
318*678453a8Sspeer 	page2.page_num = 1;
319*678453a8Sspeer 	page2.valid = 1;
320*678453a8Sspeer 	page2.func_num = nxgep->function_num;
321*678453a8Sspeer 	page2.mask = 0;
322*678453a8Sspeer 	page2.value = 0;
323*678453a8Sspeer 	page2.reloc = 0;
324*678453a8Sspeer 
325*678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
326*678453a8Sspeer #if !defined(NIU_HV_WORKAROUND)
327*678453a8Sspeer 		status = NXGE_OK;
328*678453a8Sspeer #else
329*678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
330*678453a8Sspeer 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
331*678453a8Sspeer 		    "set up logical pages"));
332*678453a8Sspeer 		/* Initialize the RXDMA logical pages */
333*678453a8Sspeer 		status = nxge_init_fzc_rdc_pages(nxgep, channel,
334*678453a8Sspeer 		    &page1, &page2);
335*678453a8Sspeer 		if (status != NXGE_OK) {
336*678453a8Sspeer 			return (status);
337*678453a8Sspeer 		}
338*678453a8Sspeer #endif
339*678453a8Sspeer 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
340*678453a8Sspeer 		/* Initialize the RXDMA logical pages */
341*678453a8Sspeer 		status = nxge_init_fzc_rdc_pages(nxgep, channel,
342*678453a8Sspeer 		    &page1, &page2);
343*678453a8Sspeer 		if (status != NXGE_OK) {
344*678453a8Sspeer 			return (status);
345*678453a8Sspeer 		}
346*678453a8Sspeer 	} else {
347*678453a8Sspeer 		return (NXGE_ERROR);
348*678453a8Sspeer 	}
349*678453a8Sspeer 
350*678453a8Sspeer 	/*
351*678453a8Sspeer 	 * Configure RED parameters
352*678453a8Sspeer 	 */
353*678453a8Sspeer 	red.value = 0;
354*678453a8Sspeer 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
355*678453a8Sspeer 	red.bits.ldw.thre =
356*678453a8Sspeer 	    (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES);
357*678453a8Sspeer 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
358*678453a8Sspeer 	red.bits.ldw.thre_sync =
359*678453a8Sspeer 	    (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES);
360*678453a8Sspeer 
361*678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
362*678453a8Sspeer 		"==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
363*678453a8Sspeer 		red.bits.ldw.thre_sync,
364*678453a8Sspeer 		red.bits.ldw.thre_sync));
365*678453a8Sspeer 
366*678453a8Sspeer 	status |= npi_rxdma_cfg_wred_param(handle, channel, &red);
367*678453a8Sspeer 
368*678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc"));
369*678453a8Sspeer 
370*678453a8Sspeer 	return (status);
371*678453a8Sspeer }
372*678453a8Sspeer 
373*678453a8Sspeer /*
374*678453a8Sspeer  * nxge_init_fzc_rxdma_channel
375*678453a8Sspeer  *
376*678453a8Sspeer  *	Initialize all per-channel FZC_DMC registers.
377*678453a8Sspeer  *
378*678453a8Sspeer  * Arguments:
379*678453a8Sspeer  * 	nxgep
380*678453a8Sspeer  * 	channel		The channel to start
381*678453a8Sspeer  *
382*678453a8Sspeer  * NPI_NXGE function calls:
383*678453a8Sspeer  *	nxge_init_hv_fzc_rxdma_channel_pages()
384*678453a8Sspeer  *	nxge_init_fzc_rxdma_channel_pages()
385*678453a8Sspeer  *	nxge_init_fzc_rxdma_channel_red()
386*678453a8Sspeer  *
387*678453a8Sspeer  * Context:
388*678453a8Sspeer  *	Service Domain
389*678453a8Sspeer  */
390*678453a8Sspeer /*ARGSUSED*/
391*678453a8Sspeer nxge_status_t
392*678453a8Sspeer nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel)
393*678453a8Sspeer {
394*678453a8Sspeer 	rx_rbr_ring_t		*rbr_ring;
395*678453a8Sspeer 	rx_rcr_ring_t		*rcr_ring;
396*678453a8Sspeer 
397*678453a8Sspeer 	nxge_status_t		status = NXGE_OK;
398*678453a8Sspeer 
39944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel"));
40044961713Sgirish 
401*678453a8Sspeer 	rbr_ring = nxgep->rx_rbr_rings->rbr_rings[channel];
402*678453a8Sspeer 	rcr_ring = nxgep->rx_rcr_rings->rcr_rings[channel];
403*678453a8Sspeer 
40459ac0c16Sdavemq 	if (nxgep->niu_type == N2_NIU) {
40544961713Sgirish #ifndef	NIU_HV_WORKAROUND
40644961713Sgirish #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
40744961713Sgirish 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
40859ac0c16Sdavemq 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV "
40959ac0c16Sdavemq 		    "set up logical pages"));
41044961713Sgirish 		/* Initialize the RXDMA logical pages */
41144961713Sgirish 		status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel,
412*678453a8Sspeer 		    rbr_ring);
41344961713Sgirish 		if (status != NXGE_OK) {
41444961713Sgirish 			return (status);
41544961713Sgirish 		}
41644961713Sgirish #endif
41759ac0c16Sdavemq 		status = NXGE_OK;
41844961713Sgirish #else
41944961713Sgirish 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
42059ac0c16Sdavemq 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
42159ac0c16Sdavemq 		    "set up logical pages"));
42244961713Sgirish 		/* Initialize the RXDMA logical pages */
42344961713Sgirish 		status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel,
424*678453a8Sspeer 		    rbr_ring);
42544961713Sgirish 		if (status != NXGE_OK) {
42644961713Sgirish 			return (status);
42744961713Sgirish 		}
42844961713Sgirish #endif
4292e59129aSraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
43059ac0c16Sdavemq 		/* Initialize the RXDMA logical pages */
43159ac0c16Sdavemq 		status = nxge_init_fzc_rxdma_channel_pages(nxgep,
432*678453a8Sspeer 		    channel, rbr_ring);
43359ac0c16Sdavemq 		if (status != NXGE_OK) {
43459ac0c16Sdavemq 			return (status);
43559ac0c16Sdavemq 		}
43659ac0c16Sdavemq 	} else {
43759ac0c16Sdavemq 		return (NXGE_ERROR);
43844961713Sgirish 	}
43944961713Sgirish 
44044961713Sgirish 	/* Configure RED parameters */
441*678453a8Sspeer 	status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_ring);
44244961713Sgirish 
44344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel"));
44444961713Sgirish 	return (status);
44544961713Sgirish }
44644961713Sgirish 
447*678453a8Sspeer /*
448*678453a8Sspeer  * nxge_init_fzc_rdc_pages
449*678453a8Sspeer  *
450*678453a8Sspeer  *	Configure a TDC's logical pages.
451*678453a8Sspeer  *
452*678453a8Sspeer  *	This function is executed by the service domain, on behalf of
453*678453a8Sspeer  *	a guest domain, to whom this RDC has been loaned.
454*678453a8Sspeer  *
455*678453a8Sspeer  * Arguments:
456*678453a8Sspeer  * 	nxgep
457*678453a8Sspeer  * 	channel		The channel to initialize.
458*678453a8Sspeer  * 	page0		Logical page 0 definition.
459*678453a8Sspeer  * 	page1		Logical page 1 definition.
460*678453a8Sspeer  *
461*678453a8Sspeer  * Notes:
462*678453a8Sspeer  *	I think that this function can be called from any
463*678453a8Sspeer  *	domain, but I need to check.
464*678453a8Sspeer  *
465*678453a8Sspeer  * NPI/NXGE function calls:
466*678453a8Sspeer  *	hv_niu_tx_logical_page_conf()
467*678453a8Sspeer  *	hv_niu_tx_logical_page_info()
468*678453a8Sspeer  *
469*678453a8Sspeer  * Context:
470*678453a8Sspeer  *	Any domain
471*678453a8Sspeer  */
472*678453a8Sspeer nxge_status_t
473*678453a8Sspeer nxge_init_fzc_rdc_pages(
474*678453a8Sspeer 	p_nxge_t nxgep,
475*678453a8Sspeer 	uint16_t channel,
476*678453a8Sspeer 	dma_log_page_t *page0,
477*678453a8Sspeer 	dma_log_page_t *page1)
478*678453a8Sspeer {
479*678453a8Sspeer 	npi_handle_t handle;
480*678453a8Sspeer 	npi_status_t rs;
481*678453a8Sspeer 
482*678453a8Sspeer 	uint64_t page_handle;
483*678453a8Sspeer 
484*678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
485*678453a8Sspeer 		"==> nxge_init_fzc_txdma_channel_pages"));
486*678453a8Sspeer 
487*678453a8Sspeer #ifndef	NIU_HV_WORKAROUND
488*678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
489*678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
490*678453a8Sspeer 			"<== nxge_init_fzc_rdc_pages: "
491*678453a8Sspeer 			"N2_NIU: no need to set rxdma logical pages"));
492*678453a8Sspeer 		return (NXGE_OK);
493*678453a8Sspeer 	}
494*678453a8Sspeer #else
495*678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
496*678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
497*678453a8Sspeer 			"<== nxge_init_fzc_rdc_pages: "
498*678453a8Sspeer 			"N2_NIU: NEED to set rxdma logical pages"));
499*678453a8Sspeer 	}
500*678453a8Sspeer #endif
501*678453a8Sspeer 
502*678453a8Sspeer 	/*
503*678453a8Sspeer 	 * Initialize logical page 1.
504*678453a8Sspeer 	 */
505*678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
506*678453a8Sspeer 	if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page0))
507*678453a8Sspeer 	    != NPI_SUCCESS)
508*678453a8Sspeer 		return (NXGE_ERROR | rs);
509*678453a8Sspeer 
510*678453a8Sspeer 	/*
511*678453a8Sspeer 	 * Initialize logical page 2.
512*678453a8Sspeer 	 */
513*678453a8Sspeer 	if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page1))
514*678453a8Sspeer 	    != NPI_SUCCESS)
515*678453a8Sspeer 		return (NXGE_ERROR | rs);
516*678453a8Sspeer 
517*678453a8Sspeer 	/*
518*678453a8Sspeer 	 * Initialize the page handle.
519*678453a8Sspeer 	 * (In the current driver, this is always set to 0.)
520*678453a8Sspeer 	 */
521*678453a8Sspeer 	page_handle = 0;
522*678453a8Sspeer 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel, page_handle);
523*678453a8Sspeer 	if (rs == NPI_SUCCESS) {
524*678453a8Sspeer 		return (NXGE_OK);
525*678453a8Sspeer 	} else {
526*678453a8Sspeer 		return (NXGE_ERROR | rs);
527*678453a8Sspeer 	}
528*678453a8Sspeer }
529*678453a8Sspeer 
53044961713Sgirish /*ARGSUSED*/
53144961713Sgirish nxge_status_t
53244961713Sgirish nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,
53344961713Sgirish 		uint16_t channel, p_rx_rbr_ring_t rbrp)
53444961713Sgirish {
53544961713Sgirish 	npi_handle_t		handle;
53644961713Sgirish 	dma_log_page_t		cfg;
53744961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
53844961713Sgirish 
53944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
54044961713Sgirish 		"==> nxge_init_fzc_rxdma_channel_pages"));
54144961713Sgirish 
54244961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
54344961713Sgirish 	/*
54444961713Sgirish 	 * Initialize logical page 1.
54544961713Sgirish 	 */
54644961713Sgirish 	cfg.func_num = nxgep->function_num;
54744961713Sgirish 	cfg.page_num = 0;
54844961713Sgirish 	cfg.valid = rbrp->page_valid.bits.ldw.page0;
54944961713Sgirish 	cfg.value = rbrp->page_value_1.value;
55044961713Sgirish 	cfg.mask = rbrp->page_mask_1.value;
55144961713Sgirish 	cfg.reloc = rbrp->page_reloc_1.value;
55244961713Sgirish 	rs = npi_rxdma_cfg_logical_page(handle, channel,
55344961713Sgirish 			(p_dma_log_page_t)&cfg);
55444961713Sgirish 	if (rs != NPI_SUCCESS) {
55544961713Sgirish 		return (NXGE_ERROR | rs);
55644961713Sgirish 	}
55744961713Sgirish 
55844961713Sgirish 	/*
55944961713Sgirish 	 * Initialize logical page 2.
56044961713Sgirish 	 */
56144961713Sgirish 	cfg.page_num = 1;
56244961713Sgirish 	cfg.valid = rbrp->page_valid.bits.ldw.page1;
56344961713Sgirish 	cfg.value = rbrp->page_value_2.value;
56444961713Sgirish 	cfg.mask = rbrp->page_mask_2.value;
56544961713Sgirish 	cfg.reloc = rbrp->page_reloc_2.value;
56644961713Sgirish 
56744961713Sgirish 	rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg);
56844961713Sgirish 	if (rs != NPI_SUCCESS) {
56944961713Sgirish 		return (NXGE_ERROR | rs);
57044961713Sgirish 	}
57144961713Sgirish 
57244961713Sgirish 	/* Initialize the page handle */
57344961713Sgirish 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel,
57444961713Sgirish 			rbrp->page_hdl.bits.ldw.handle);
57544961713Sgirish 
57644961713Sgirish 	if (rs != NPI_SUCCESS) {
57744961713Sgirish 		return (NXGE_ERROR | rs);
57844961713Sgirish 	}
57944961713Sgirish 
58044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
58144961713Sgirish 		"<== nxge_init_fzc_rxdma_channel_pages"));
58244961713Sgirish 
58344961713Sgirish 	return (NXGE_OK);
58444961713Sgirish }
58544961713Sgirish 
58644961713Sgirish /*ARGSUSED*/
58744961713Sgirish nxge_status_t
58844961713Sgirish nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,
58944961713Sgirish 	uint16_t channel, p_rx_rcr_ring_t rcr_p)
59044961713Sgirish {
59144961713Sgirish 	npi_handle_t		handle;
59244961713Sgirish 	rdc_red_para_t		red;
59344961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
59444961713Sgirish 
59544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red"));
59644961713Sgirish 
59744961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
59844961713Sgirish 	red.value = 0;
59944961713Sgirish 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
60044961713Sgirish 	red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
60144961713Sgirish 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
60244961713Sgirish 	red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
60344961713Sgirish 
60444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
60544961713Sgirish 		"==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
60644961713Sgirish 		red.bits.ldw.thre_sync,
60744961713Sgirish 		red.bits.ldw.thre_sync));
60844961713Sgirish 
60944961713Sgirish 	rs = npi_rxdma_cfg_wred_param(handle, channel, &red);
61044961713Sgirish 	if (rs != NPI_SUCCESS) {
61144961713Sgirish 		return (NXGE_ERROR | rs);
61244961713Sgirish 	}
61344961713Sgirish 
61444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
61544961713Sgirish 		"<== nxge_init_fzc_rxdma_channel_red"));
61644961713Sgirish 
61744961713Sgirish 	return (NXGE_OK);
61844961713Sgirish }
61944961713Sgirish 
620*678453a8Sspeer /*
621*678453a8Sspeer  * nxge_init_fzc_tdc
622*678453a8Sspeer  *
623*678453a8Sspeer  *	Initialize all of a TDC's FZC_DMC registers.
624*678453a8Sspeer  *	This is executed by the service domain, on behalf of a
625*678453a8Sspeer  *	guest domain, who cannot access these registers.
626*678453a8Sspeer  *
627*678453a8Sspeer  * Arguments:
628*678453a8Sspeer  * 	nxgep
629*678453a8Sspeer  * 	channel		The channel to initialize.
630*678453a8Sspeer  *
631*678453a8Sspeer  * NPI_NXGE function calls:
632*678453a8Sspeer  *	nxge_init_fzc_tdc_pages()
633*678453a8Sspeer  *	npi_txc_dma_max_burst_set()
634*678453a8Sspeer  *
635*678453a8Sspeer  * Registers accessed:
636*678453a8Sspeer  *	TXC_DMA_MAX_BURST
637*678453a8Sspeer  *
638*678453a8Sspeer  * Context:
639*678453a8Sspeer  *	Service Domain
640*678453a8Sspeer  */
641*678453a8Sspeer /*ARGSUSED*/
642*678453a8Sspeer nxge_status_t
643*678453a8Sspeer nxge_init_fzc_tdc(p_nxge_t nxgep, uint16_t channel)
644*678453a8Sspeer {
645*678453a8Sspeer 	nxge_status_t	status = NXGE_OK;
646*678453a8Sspeer 
647*678453a8Sspeer 	dma_log_page_t	page1, page2;
648*678453a8Sspeer 	npi_handle_t	handle;
649*678453a8Sspeer 
650*678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc"));
651*678453a8Sspeer 
652*678453a8Sspeer 	/*
653*678453a8Sspeer 	 * These values have been copied from
654*678453a8Sspeer 	 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring().
655*678453a8Sspeer 	 */
656*678453a8Sspeer 	page1.page_num = 0;
657*678453a8Sspeer 	page1.valid = 1;
658*678453a8Sspeer 	page1.func_num = nxgep->function_num;
659*678453a8Sspeer 	page1.mask = 0;
660*678453a8Sspeer 	page1.value = 0;
661*678453a8Sspeer 	page1.reloc = 0;
662*678453a8Sspeer 
663*678453a8Sspeer 	page1.page_num = 1;
664*678453a8Sspeer 	page1.valid = 1;
665*678453a8Sspeer 	page1.func_num = nxgep->function_num;
666*678453a8Sspeer 	page1.mask = 0;
667*678453a8Sspeer 	page1.value = 0;
668*678453a8Sspeer 	page1.reloc = 0;
669*678453a8Sspeer 
670*678453a8Sspeer #ifdef	NIU_HV_WORKAROUND
671*678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
672*678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
673*678453a8Sspeer 		    "==> nxge_init_fzc_txdma_channel "
674*678453a8Sspeer 		    "N2_NIU: NEED to set up txdma logical pages"));
675*678453a8Sspeer 		/* Initialize the TXDMA logical pages */
676*678453a8Sspeer 		(void) nxge_init_fzc_tdc_pages(nxgep, channel,
677*678453a8Sspeer 		    &page1, &page2);
678*678453a8Sspeer 	}
679*678453a8Sspeer #endif
680*678453a8Sspeer 	if (nxgep->niu_type != N2_NIU) {
681*678453a8Sspeer 		if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
682*678453a8Sspeer 			/* Initialize the TXDMA logical pages */
683*678453a8Sspeer 			(void) nxge_init_fzc_tdc_pages(nxgep, channel,
684*678453a8Sspeer 			    &page1, &page2);
685*678453a8Sspeer 		} else
686*678453a8Sspeer 			return (NXGE_ERROR);
687*678453a8Sspeer 	}
688*678453a8Sspeer 
689*678453a8Sspeer 	/*
690*678453a8Sspeer 	 * Configure the TXC DMA Max Burst value.
691*678453a8Sspeer 	 *
692*678453a8Sspeer 	 * PRM.13.5
693*678453a8Sspeer 	 *
694*678453a8Sspeer 	 * TXC DMA Max Burst. TXC_DMA_MAX (FZC_TXC + 0000016)
695*678453a8Sspeer 	 * 19:0		dma_max_burst		RW
696*678453a8Sspeer 	 * Max burst value associated with DMA. Used by DRR engine
697*678453a8Sspeer 	 * for computing when DMA has gone into deficit.
698*678453a8Sspeer 	 */
699*678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
700*678453a8Sspeer 	(void) npi_txc_dma_max_burst_set(
701*678453a8Sspeer 		handle, channel, TXC_DMA_MAX_BURST_DEFAULT);
702*678453a8Sspeer 
703*678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_tdc"));
704*678453a8Sspeer 
705*678453a8Sspeer 	return (status);
706*678453a8Sspeer }
707*678453a8Sspeer 
70844961713Sgirish /*ARGSUSED*/
70944961713Sgirish nxge_status_t
71044961713Sgirish nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel,
71144961713Sgirish 	p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p)
71244961713Sgirish {
71344961713Sgirish 	nxge_status_t	status = NXGE_OK;
71444961713Sgirish 
71544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
71644961713Sgirish 		"==> nxge_init_fzc_txdma_channel"));
71744961713Sgirish 
71859ac0c16Sdavemq 	if (nxgep->niu_type == N2_NIU) {
71944961713Sgirish #ifndef	NIU_HV_WORKAROUND
72044961713Sgirish #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
72144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
72259ac0c16Sdavemq 		    "==> nxge_init_fzc_txdma_channel "
72359ac0c16Sdavemq 		    "N2_NIU: call HV to set up txdma logical pages"));
72444961713Sgirish 		status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel,
72559ac0c16Sdavemq 		    tx_ring_p);
72644961713Sgirish 		if (status != NXGE_OK) {
72744961713Sgirish 			return (status);
72844961713Sgirish 		}
72944961713Sgirish #endif
73059ac0c16Sdavemq 		status = NXGE_OK;
73144961713Sgirish #else
73244961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
73359ac0c16Sdavemq 		    "==> nxge_init_fzc_txdma_channel "
73459ac0c16Sdavemq 		    "N2_NIU: NEED to set up txdma logical pages"));
73544961713Sgirish 		/* Initialize the TXDMA logical pages */
73644961713Sgirish 		(void) nxge_init_fzc_txdma_channel_pages(nxgep, channel,
73759ac0c16Sdavemq 		    tx_ring_p);
73844961713Sgirish #endif
7392e59129aSraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
74059ac0c16Sdavemq 		/* Initialize the TXDMA logical pages */
74159ac0c16Sdavemq 		(void) nxge_init_fzc_txdma_channel_pages(nxgep,
74259ac0c16Sdavemq 		    channel, tx_ring_p);
74359ac0c16Sdavemq 	} else {
74459ac0c16Sdavemq 		return (NXGE_ERROR);
74544961713Sgirish 	}
74644961713Sgirish 
74744961713Sgirish 	/*
74844961713Sgirish 	 * Configure Transmit DRR Weight parameters
74944961713Sgirish 	 * (It actually programs the TXC max burst register).
75044961713Sgirish 	 */
75144961713Sgirish 	(void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p);
75244961713Sgirish 
75344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
75444961713Sgirish 		"<== nxge_init_fzc_txdma_channel"));
75544961713Sgirish 	return (status);
75644961713Sgirish }
75744961713Sgirish 
75844961713Sgirish nxge_status_t
75944961713Sgirish nxge_init_fzc_common(p_nxge_t nxgep)
76044961713Sgirish {
76144961713Sgirish 	nxge_status_t	status = NXGE_OK;
76244961713Sgirish 
76344961713Sgirish 	(void) nxge_init_fzc_rx_common(nxgep);
76444961713Sgirish 
76544961713Sgirish 	return (status);
76644961713Sgirish }
76744961713Sgirish 
76844961713Sgirish nxge_status_t
76944961713Sgirish nxge_init_fzc_rx_common(p_nxge_t nxgep)
77044961713Sgirish {
77144961713Sgirish 	npi_handle_t	handle;
77244961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
77344961713Sgirish 	nxge_status_t	status = NXGE_OK;
77444961713Sgirish 	clock_t		lbolt;
775*678453a8Sspeer 	int		table;
776*678453a8Sspeer 
777*678453a8Sspeer 	nxge_hw_pt_cfg_t *hardware;
77844961713Sgirish 
77944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common"));
78044961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
78144961713Sgirish 	if (!handle.regp) {
78244961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
78344961713Sgirish 			"==> nxge_init_fzc_rx_common null ptr"));
78444961713Sgirish 		return (NXGE_ERROR);
78544961713Sgirish 	}
78644961713Sgirish 
78744961713Sgirish 	/*
78844961713Sgirish 	 * Configure the rxdma clock divider
78944961713Sgirish 	 * This is the granularity counter based on
79044961713Sgirish 	 * the hardware system clock (i.e. 300 Mhz) and
79144961713Sgirish 	 * it is running around 3 nanoseconds.
79244961713Sgirish 	 * So, set the clock divider counter to 1000 to get
79344961713Sgirish 	 * microsecond granularity.
79444961713Sgirish 	 * For example, for a 3 microsecond timeout, the timeout
79544961713Sgirish 	 * will be set to 1.
79644961713Sgirish 	 */
79744961713Sgirish 	rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT);
79844961713Sgirish 	if (rs != NPI_SUCCESS)
79944961713Sgirish 		return (NXGE_ERROR | rs);
80044961713Sgirish 
80144961713Sgirish #if defined(__i386)
80244961713Sgirish 	rs = npi_rxdma_cfg_32bitmode_enable(handle);
80344961713Sgirish 	if (rs != NPI_SUCCESS)
80444961713Sgirish 		return (NXGE_ERROR | rs);
80544961713Sgirish 	rs = npi_txdma_mode32_set(handle, B_TRUE);
80644961713Sgirish 	if (rs != NPI_SUCCESS)
80744961713Sgirish 		return (NXGE_ERROR | rs);
80844961713Sgirish #endif
80944961713Sgirish 
81044961713Sgirish 	/*
81144961713Sgirish 	 * Enable WRED and program an initial value.
81244961713Sgirish 	 * Use time to set the initial random number.
81344961713Sgirish 	 */
81444961713Sgirish 	(void) drv_getparm(LBOLT, &lbolt);
81544961713Sgirish 	rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt);
81644961713Sgirish 	if (rs != NPI_SUCCESS)
81744961713Sgirish 		return (NXGE_ERROR | rs);
81844961713Sgirish 
819*678453a8Sspeer 	hardware = &nxgep->pt_config.hw_config;
820*678453a8Sspeer 	for (table = 0; table < NXGE_MAX_RDC_GRPS; table++) {
821*678453a8Sspeer 		/* Does this table belong to <nxgep>? */
822*678453a8Sspeer 		if (hardware->grpids[table] == (nxgep->function_num + 256))
823*678453a8Sspeer 			status = nxge_init_fzc_rdc_tbl(nxgep, table);
824*678453a8Sspeer 	}
82544961713Sgirish 
82644961713Sgirish 	/* Ethernet Timeout Counter (?) */
82744961713Sgirish 
82844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
82944961713Sgirish 		"<== nxge_init_fzc_rx_common:status 0x%08x", status));
83044961713Sgirish 
83144961713Sgirish 	return (status);
83244961713Sgirish }
83344961713Sgirish 
83444961713Sgirish nxge_status_t
835*678453a8Sspeer nxge_init_fzc_rdc_tbl(p_nxge_t nxge, int rdc_tbl)
83644961713Sgirish {
837*678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
838*678453a8Sspeer 	nx_rdc_tbl_t	*table;
839*678453a8Sspeer 	nxge_rdc_grp_t	*group;
840*678453a8Sspeer 	npi_handle_t	handle;
84144961713Sgirish 
842*678453a8Sspeer 	npi_status_t	rs = NPI_SUCCESS;
843*678453a8Sspeer 	nxge_status_t	status = NXGE_OK;
84444961713Sgirish 
845*678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_init_fzc_rdc_tbl(%d)", table));
846*678453a8Sspeer 
847*678453a8Sspeer 	group = &nxge->pt_config.rdc_grps[rdc_tbl];
848*678453a8Sspeer 
849*678453a8Sspeer 	/* This RDC table must have been previously bound to <nxge>. */
850*678453a8Sspeer 	MUTEX_ENTER(&nhd->lock);
851*678453a8Sspeer 	table = &nhd->rdc_tbl[rdc_tbl];
852*678453a8Sspeer 	if (table->nxge != (uintptr_t)nxge) {
853*678453a8Sspeer 		MUTEX_EXIT(&nhd->lock);
854*678453a8Sspeer 		NXGE_ERROR_MSG((nxge, DMA_CTL,
855*678453a8Sspeer 		    "nxge_init_fzc_rdc_tbl(%d): not owner", table));
856*678453a8Sspeer 		return (NXGE_ERROR);
857*678453a8Sspeer 	} else {
858*678453a8Sspeer 		table->map = group->map;
859*678453a8Sspeer 	}
860*678453a8Sspeer 	MUTEX_EXIT(&nhd->lock);
861*678453a8Sspeer 
862*678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxge);
863*678453a8Sspeer 
864*678453a8Sspeer 	rs = npi_rxdma_rdc_table_config(handle, rdc_tbl,
865*678453a8Sspeer 	    group->map, group->max_rdcs);
866*678453a8Sspeer 
867*678453a8Sspeer 	if (rs != NPI_SUCCESS) {
868*678453a8Sspeer 		status = NXGE_ERROR | rs;
86944961713Sgirish 	}
87044961713Sgirish 
871*678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_init_fzc_rdc_tbl(%d)", table));
87244961713Sgirish 	return (status);
87344961713Sgirish }
87444961713Sgirish 
875*678453a8Sspeer static
876*678453a8Sspeer int
877*678453a8Sspeer rdc_tbl_bind(p_nxge_t nxge, int rdc_tbl)
878*678453a8Sspeer {
879*678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
880*678453a8Sspeer 	nx_rdc_tbl_t *table;
881*678453a8Sspeer 	int i;
882*678453a8Sspeer 
883*678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_bind"));
884*678453a8Sspeer 
885*678453a8Sspeer 	MUTEX_ENTER(&nhd->lock);
886*678453a8Sspeer 	/* is the caller asking for a particular table? */
887*678453a8Sspeer 	if (rdc_tbl >= 0 && rdc_tbl < NXGE_MAX_RDC_GROUPS) {
888*678453a8Sspeer 		table = &nhd->rdc_tbl[rdc_tbl];
889*678453a8Sspeer 		if (table->nxge == 0) {
890*678453a8Sspeer 			table->nxge = (uintptr_t)nxge; /* It is now bound. */
891*678453a8Sspeer 			NXGE_DEBUG_MSG((nxge, DMA_CTL,
892*678453a8Sspeer 			    "<== nxge_fzc_rdc_tbl_bind(%d)", rdc_tbl));
893*678453a8Sspeer 			MUTEX_EXIT(&nhd->lock);
894*678453a8Sspeer 			return (rdc_tbl);
895*678453a8Sspeer 		}
896*678453a8Sspeer 	} else {	/* The caller will take any old RDC table. */
897*678453a8Sspeer 		for (i = 0; i < NXGE_MAX_RDC_GROUPS; i++) {
898*678453a8Sspeer 			nx_rdc_tbl_t *table = &nhd->rdc_tbl[i];
899*678453a8Sspeer 			if (table->nxge == 0) {
900*678453a8Sspeer 				table->nxge = (uintptr_t)nxge;
901*678453a8Sspeer 				/* It is now bound. */
902*678453a8Sspeer 				MUTEX_EXIT(&nhd->lock);
903*678453a8Sspeer 				NXGE_DEBUG_MSG((nxge, DMA_CTL,
904*678453a8Sspeer 				    "<== nxge_fzc_rdc_tbl_bind: %d", i));
905*678453a8Sspeer 				return (i);
906*678453a8Sspeer 			}
907*678453a8Sspeer 		}
908*678453a8Sspeer 	}
909*678453a8Sspeer 	MUTEX_EXIT(&nhd->lock);
910*678453a8Sspeer 
911*678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_fzc_rdc_tbl_bind"));
912*678453a8Sspeer 
913*678453a8Sspeer 	return (-EBUSY);	/* RDC tables are bound. */
914*678453a8Sspeer }
915*678453a8Sspeer 
916*678453a8Sspeer int
917*678453a8Sspeer nxge_fzc_rdc_tbl_bind(
918*678453a8Sspeer 	nxge_t *nxge,
919*678453a8Sspeer 	int grp_index,
920*678453a8Sspeer 	int acceptNoSubstitutes)
921*678453a8Sspeer {
922*678453a8Sspeer 	nxge_hw_pt_cfg_t *hardware;
923*678453a8Sspeer 	int index;
924*678453a8Sspeer 
925*678453a8Sspeer 	hardware = &nxge->pt_config.hw_config;
926*678453a8Sspeer 
927*678453a8Sspeer 	if ((index = rdc_tbl_bind(nxge, grp_index)) < 0) {
928*678453a8Sspeer 		if (acceptNoSubstitutes)
929*678453a8Sspeer 			return (index);
930*678453a8Sspeer 		index = rdc_tbl_bind(nxge, grp_index);
931*678453a8Sspeer 		if (index < 0) {
932*678453a8Sspeer 			NXGE_ERROR_MSG((nxge, OBP_CTL,
933*678453a8Sspeer 			    "nxge_fzc_rdc_tbl_init: "
934*678453a8Sspeer 			    "there are no free RDC tables!"));
935*678453a8Sspeer 			return (index);
936*678453a8Sspeer 		}
937*678453a8Sspeer 	}
938*678453a8Sspeer 
939*678453a8Sspeer 	hardware->grpids[index] = nxge->function_num + 256;
940*678453a8Sspeer 
941*678453a8Sspeer 	return (index);
942*678453a8Sspeer }
943*678453a8Sspeer 
944*678453a8Sspeer int
945*678453a8Sspeer nxge_fzc_rdc_tbl_unbind(p_nxge_t nxge, int rdc_tbl)
946*678453a8Sspeer {
947*678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
948*678453a8Sspeer 	nx_rdc_tbl_t *table;
949*678453a8Sspeer 
950*678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_unbind(%d)",
951*678453a8Sspeer 	    rdc_tbl));
952*678453a8Sspeer 
953*678453a8Sspeer 	table = &nhd->rdc_tbl[rdc_tbl];
954*678453a8Sspeer 	if (table->nxge != (uintptr_t)nxge) {
955*678453a8Sspeer 		NXGE_ERROR_MSG((nxge, DMA_CTL,
956*678453a8Sspeer 		    "nxge_fzc_rdc_tbl_unbind(%d): func%d not owner",
957*678453a8Sspeer 		    nxge->function_num, rdc_tbl));
958*678453a8Sspeer 		return (EINVAL);
959*678453a8Sspeer 	} else {
960*678453a8Sspeer 		bzero(table, sizeof (*table));
961*678453a8Sspeer 	}
962*678453a8Sspeer 
963*678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_fzc_rdc_tbl_unbind(%d)",
964*678453a8Sspeer 	    rdc_tbl));
965*678453a8Sspeer 
966*678453a8Sspeer 	return (0);
967*678453a8Sspeer }
968*678453a8Sspeer 
96944961713Sgirish nxge_status_t
97044961713Sgirish nxge_init_fzc_rxdma_port(p_nxge_t nxgep)
97144961713Sgirish {
97244961713Sgirish 	npi_handle_t		handle;
97344961713Sgirish 	p_nxge_dma_pt_cfg_t	p_all_cfgp;
97444961713Sgirish 	p_nxge_hw_pt_cfg_t	p_cfgp;
97544961713Sgirish 	hostinfo_t 		hostinfo;
97644961713Sgirish 	int			i;
97744961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
97844961713Sgirish 	p_nxge_class_pt_cfg_t 	p_class_cfgp;
97944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port"));
98044961713Sgirish 
98144961713Sgirish 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
98244961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
98344961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
98444961713Sgirish 	/*
98544961713Sgirish 	 * Initialize the port scheduler DRR weight.
98644961713Sgirish 	 * npi_rxdma_cfg_port_ddr_weight();
98744961713Sgirish 	 */
98844961713Sgirish 
9892e59129aSraghus 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
9902e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_FIBER) ||
9912e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
9922e59129aSraghus 		rs = npi_rxdma_cfg_port_ddr_weight(handle,
9932e59129aSraghus 		    nxgep->function_num, NXGE_RX_DRR_WT_1G);
9942e59129aSraghus 		if (rs != NPI_SUCCESS) {
9952e59129aSraghus 			return (NXGE_ERROR | rs);
99644961713Sgirish 		}
99744961713Sgirish 	}
99844961713Sgirish 
99944961713Sgirish 	/* Program the default RDC of a port */
100044961713Sgirish 	rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num,
1001*678453a8Sspeer 	    p_cfgp->def_rdc);
100244961713Sgirish 	if (rs != NPI_SUCCESS) {
100344961713Sgirish 		return (NXGE_ERROR | rs);
100444961713Sgirish 	}
100544961713Sgirish 
100644961713Sgirish 	/*
100744961713Sgirish 	 * Configure the MAC host info table with RDC tables
100844961713Sgirish 	 */
100944961713Sgirish 	hostinfo.value = 0;
101044961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
101144961713Sgirish 	for (i = 0; i < p_cfgp->max_macs; i++) {
1012*678453a8Sspeer 		hostinfo.bits.w0.rdc_tbl_num = p_cfgp->def_mac_rxdma_grpid;
101344961713Sgirish 		hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref;
101444961713Sgirish 		if (p_class_cfgp->mac_host_info[i].flag) {
101544961713Sgirish 			hostinfo.bits.w0.rdc_tbl_num =
101644961713Sgirish 				p_class_cfgp->mac_host_info[i].rdctbl;
101744961713Sgirish 			hostinfo.bits.w0.mac_pref =
101844961713Sgirish 				p_class_cfgp->mac_host_info[i].mpr_npr;
101944961713Sgirish 		}
102044961713Sgirish 
102144961713Sgirish 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
102244961713Sgirish 				nxgep->function_num, i, &hostinfo);
102344961713Sgirish 		if (rs != NPI_SUCCESS)
102444961713Sgirish 			return (NXGE_ERROR | rs);
102544961713Sgirish 	}
102644961713Sgirish 
102744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
102844961713Sgirish 		"<== nxge_init_fzc_rxdma_port rs 0x%08x", rs));
102944961713Sgirish 
103044961713Sgirish 	return (NXGE_OK);
103144961713Sgirish 
103244961713Sgirish }
103344961713Sgirish 
103444961713Sgirish nxge_status_t
103544961713Sgirish nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc)
103644961713Sgirish {
103744961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
103844961713Sgirish 	rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle,
103944961713Sgirish 				    port, rdc);
104044961713Sgirish 	if (rs & NPI_FAILURE)
104144961713Sgirish 		return (NXGE_ERROR | rs);
104244961713Sgirish 	return (NXGE_OK);
104344961713Sgirish }
104444961713Sgirish 
1045*678453a8Sspeer /*
1046*678453a8Sspeer  * nxge_init_fzc_tdc_pages
1047*678453a8Sspeer  *
1048*678453a8Sspeer  *	Configure a TDC's logical pages.
1049*678453a8Sspeer  *
1050*678453a8Sspeer  *	This function is executed by the service domain, on behalf of
1051*678453a8Sspeer  *	a guest domain, to whom this TDC has been loaned.
1052*678453a8Sspeer  *
1053*678453a8Sspeer  * Arguments:
1054*678453a8Sspeer  * 	nxgep
1055*678453a8Sspeer  * 	channel		The channel to initialize.
1056*678453a8Sspeer  * 	page0		Logical page 0 definition.
1057*678453a8Sspeer  * 	page1		Logical page 1 definition.
1058*678453a8Sspeer  *
1059*678453a8Sspeer  * Notes:
1060*678453a8Sspeer  *	I think that this function can be called from any
1061*678453a8Sspeer  *	domain, but I need to check.
1062*678453a8Sspeer  *
1063*678453a8Sspeer  * NPI/NXGE function calls:
1064*678453a8Sspeer  *	hv_niu_tx_logical_page_conf()
1065*678453a8Sspeer  *	hv_niu_tx_logical_page_info()
1066*678453a8Sspeer  *
1067*678453a8Sspeer  * Context:
1068*678453a8Sspeer  *	Any domain
1069*678453a8Sspeer  */
1070*678453a8Sspeer nxge_status_t
1071*678453a8Sspeer nxge_init_fzc_tdc_pages(
1072*678453a8Sspeer 	p_nxge_t nxgep,
1073*678453a8Sspeer 	uint16_t channel,
1074*678453a8Sspeer 	dma_log_page_t *page0,
1075*678453a8Sspeer 	dma_log_page_t *page1)
1076*678453a8Sspeer {
1077*678453a8Sspeer 	npi_handle_t handle;
1078*678453a8Sspeer 	npi_status_t rs;
1079*678453a8Sspeer 
1080*678453a8Sspeer 	log_page_hdl_t page_handle;
1081*678453a8Sspeer 
1082*678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1083*678453a8Sspeer 		"==> nxge_init_fzc_txdma_channel_pages"));
1084*678453a8Sspeer 
1085*678453a8Sspeer #ifndef	NIU_HV_WORKAROUND
1086*678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
1087*678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1088*678453a8Sspeer 			"<== nxge_init_fzc_tdc_pages: "
1089*678453a8Sspeer 			"N2_NIU: no need to set txdma logical pages"));
1090*678453a8Sspeer 		return (NXGE_OK);
1091*678453a8Sspeer 	}
1092*678453a8Sspeer #else
1093*678453a8Sspeer 	if (nxgep->niu_type == N2_NIU) {
1094*678453a8Sspeer 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
1095*678453a8Sspeer 			"<== nxge_init_fzc_tdc_pages: "
1096*678453a8Sspeer 			"N2_NIU: NEED to set txdma logical pages"));
1097*678453a8Sspeer 	}
1098*678453a8Sspeer #endif
1099*678453a8Sspeer 
1100*678453a8Sspeer 	/*
1101*678453a8Sspeer 	 * Initialize logical page 1.
1102*678453a8Sspeer 	 */
1103*678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
1104*678453a8Sspeer 	if ((rs = npi_txdma_log_page_set(handle, channel, page0))
1105*678453a8Sspeer 	    != NPI_SUCCESS)
1106*678453a8Sspeer 		return (NXGE_ERROR | rs);
1107*678453a8Sspeer 
1108*678453a8Sspeer 	/*
1109*678453a8Sspeer 	 * Initialize logical page 2.
1110*678453a8Sspeer 	 */
1111*678453a8Sspeer 	if ((rs = npi_txdma_log_page_set(handle, channel, page1))
1112*678453a8Sspeer 	    != NPI_SUCCESS)
1113*678453a8Sspeer 		return (NXGE_ERROR | rs);
1114*678453a8Sspeer 
1115*678453a8Sspeer 	/*
1116*678453a8Sspeer 	 * Initialize the page handle.
1117*678453a8Sspeer 	 * (In the current driver, this is always set to 0.)
1118*678453a8Sspeer 	 */
1119*678453a8Sspeer 	page_handle.value = 0;
1120*678453a8Sspeer 	rs = npi_txdma_log_page_handle_set(handle, channel, &page_handle);
1121*678453a8Sspeer 	if (rs == NPI_SUCCESS) {
1122*678453a8Sspeer 		return (NXGE_OK);
1123*678453a8Sspeer 	} else {
1124*678453a8Sspeer 		return (NXGE_ERROR | rs);
1125*678453a8Sspeer 	}
1126*678453a8Sspeer }
1127*678453a8Sspeer 
112844961713Sgirish nxge_status_t
112944961713Sgirish nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
113044961713Sgirish 	p_tx_ring_t tx_ring_p)
113144961713Sgirish {
113244961713Sgirish 	npi_handle_t		handle;
113344961713Sgirish 	dma_log_page_t		cfg;
113444961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
113544961713Sgirish 
113644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
113744961713Sgirish 		"==> nxge_init_fzc_txdma_channel_pages"));
113844961713Sgirish 
113944961713Sgirish #ifndef	NIU_HV_WORKAROUND
114044961713Sgirish 	if (nxgep->niu_type == N2_NIU) {
114144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
114244961713Sgirish 			"<== nxge_init_fzc_txdma_channel_pages: "
114344961713Sgirish 			"N2_NIU: no need to set txdma logical pages"));
114444961713Sgirish 		return (NXGE_OK);
114544961713Sgirish 	}
114644961713Sgirish #else
114744961713Sgirish 	if (nxgep->niu_type == N2_NIU) {
114844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
114944961713Sgirish 			"<== nxge_init_fzc_txdma_channel_pages: "
115044961713Sgirish 			"N2_NIU: NEED to set txdma logical pages"));
115144961713Sgirish 	}
115244961713Sgirish #endif
115344961713Sgirish 
115444961713Sgirish 	/*
115544961713Sgirish 	 * Initialize logical page 1.
115644961713Sgirish 	 */
115744961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
115844961713Sgirish 	cfg.func_num = nxgep->function_num;
115944961713Sgirish 	cfg.page_num = 0;
116044961713Sgirish 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page0;
116144961713Sgirish 	cfg.value = tx_ring_p->page_value_1.value;
116244961713Sgirish 	cfg.mask = tx_ring_p->page_mask_1.value;
116344961713Sgirish 	cfg.reloc = tx_ring_p->page_reloc_1.value;
116444961713Sgirish 
116544961713Sgirish 	rs = npi_txdma_log_page_set(handle, channel,
116644961713Sgirish 		(p_dma_log_page_t)&cfg);
116744961713Sgirish 	if (rs != NPI_SUCCESS) {
116844961713Sgirish 		return (NXGE_ERROR | rs);
116944961713Sgirish 	}
117044961713Sgirish 
117144961713Sgirish 	/*
117244961713Sgirish 	 * Initialize logical page 2.
117344961713Sgirish 	 */
117444961713Sgirish 	cfg.page_num = 1;
117544961713Sgirish 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page1;
117644961713Sgirish 	cfg.value = tx_ring_p->page_value_2.value;
117744961713Sgirish 	cfg.mask = tx_ring_p->page_mask_2.value;
117844961713Sgirish 	cfg.reloc = tx_ring_p->page_reloc_2.value;
117944961713Sgirish 
118044961713Sgirish 	rs = npi_txdma_log_page_set(handle, channel, &cfg);
118144961713Sgirish 	if (rs != NPI_SUCCESS) {
118244961713Sgirish 		return (NXGE_ERROR | rs);
118344961713Sgirish 	}
118444961713Sgirish 
118544961713Sgirish 	/* Initialize the page handle */
118644961713Sgirish 	rs = npi_txdma_log_page_handle_set(handle, channel,
118744961713Sgirish 			&tx_ring_p->page_hdl);
118844961713Sgirish 
118944961713Sgirish 	if (rs == NPI_SUCCESS) {
119044961713Sgirish 		return (NXGE_OK);
119144961713Sgirish 	} else {
119244961713Sgirish 		return (NXGE_ERROR | rs);
119344961713Sgirish 	}
119444961713Sgirish }
119544961713Sgirish 
119644961713Sgirish 
119744961713Sgirish nxge_status_t
119844961713Sgirish nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel,
119944961713Sgirish 	p_tx_ring_t tx_ring_p)
120044961713Sgirish {
120144961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
120244961713Sgirish 	npi_handle_t	handle;
120344961713Sgirish 
120444961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
120544961713Sgirish 	rs = npi_txc_dma_max_burst_set(handle, channel,
120644961713Sgirish 			tx_ring_p->max_burst.value);
120744961713Sgirish 	if (rs == NPI_SUCCESS) {
120844961713Sgirish 		return (NXGE_OK);
120944961713Sgirish 	} else {
121044961713Sgirish 		return (NXGE_ERROR | rs);
121144961713Sgirish 	}
121244961713Sgirish }
121344961713Sgirish 
121444961713Sgirish nxge_status_t
121544961713Sgirish nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask)
121644961713Sgirish {
121744961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
121844961713Sgirish 	npi_handle_t	handle;
121944961713Sgirish 
122044961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
122144961713Sgirish 	rs = npi_fzc_sys_err_mask_set(handle, mask);
122244961713Sgirish 	if (rs == NPI_SUCCESS) {
122344961713Sgirish 		return (NXGE_OK);
122444961713Sgirish 	} else {
122544961713Sgirish 		return (NXGE_ERROR | rs);
122644961713Sgirish 	}
122744961713Sgirish }
122844961713Sgirish 
1229*678453a8Sspeer /*
1230*678453a8Sspeer  * nxge_init_hv_fzc_txdma_channel_pages
1231*678453a8Sspeer  *
1232*678453a8Sspeer  *	Configure a TDC's logical pages.
1233*678453a8Sspeer  *
1234*678453a8Sspeer  * Arguments:
1235*678453a8Sspeer  * 	nxgep
1236*678453a8Sspeer  * 	channel		The channel to initialize.
1237*678453a8Sspeer  * 	tx_ring_p	The transmit ring.
1238*678453a8Sspeer  *
1239*678453a8Sspeer  * Notes:
1240*678453a8Sspeer  *	I think that this function can be called from any
1241*678453a8Sspeer  *	domain, but I need to check.
1242*678453a8Sspeer  *
1243*678453a8Sspeer  * NPI/NXGE function calls:
1244*678453a8Sspeer  *	hv_niu_tx_logical_page_conf()
1245*678453a8Sspeer  *	hv_niu_tx_logical_page_info()
1246*678453a8Sspeer  *
1247*678453a8Sspeer  * Context:
1248*678453a8Sspeer  *	Any domain
1249*678453a8Sspeer  */
1250*678453a8Sspeer #if defined(sun4v) && defined(NIU_LP_WORKAROUND)
125144961713Sgirish nxge_status_t
125244961713Sgirish nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
125344961713Sgirish 	p_tx_ring_t tx_ring_p)
125444961713Sgirish {
125544961713Sgirish 	int			err;
125644961713Sgirish 	uint64_t		hverr;
125744961713Sgirish #ifdef	DEBUG
125844961713Sgirish 	uint64_t		ra, size;
125944961713Sgirish #endif
126044961713Sgirish 
126144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
126244961713Sgirish 		"==> nxge_init_hv_fzc_txdma_channel_pages"));
126344961713Sgirish 
126444961713Sgirish 	if (tx_ring_p->hv_set) {
126544961713Sgirish 		return (NXGE_OK);
126644961713Sgirish 	}
126744961713Sgirish 
126844961713Sgirish 	/*
126944961713Sgirish 	 * Initialize logical page 1 for data buffers.
127044961713Sgirish 	 */
127144961713Sgirish 	hverr = hv_niu_tx_logical_page_conf((uint64_t)channel,
127244961713Sgirish 			(uint64_t)0,
127344961713Sgirish 			tx_ring_p->hv_tx_buf_base_ioaddr_pp,
127444961713Sgirish 			tx_ring_p->hv_tx_buf_ioaddr_size);
127544961713Sgirish 
127644961713Sgirish 	err = (nxge_status_t)nxge_herr2kerr(hverr);
127744961713Sgirish 	if (err != 0) {
127844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
127944961713Sgirish 			"<== nxge_init_hv_fzc_txdma_channel_pages: channel %d "
128044961713Sgirish 			"error status 0x%x "
128144961713Sgirish 			"(page 0 data buf) hverr 0x%llx "
128244961713Sgirish 			"ioaddr_pp $%p "
128344961713Sgirish 			"size 0x%llx ",
128444961713Sgirish 			channel,
128544961713Sgirish 			err,
128644961713Sgirish 			hverr,
128744961713Sgirish 			tx_ring_p->hv_tx_buf_base_ioaddr_pp,
128844961713Sgirish 			tx_ring_p->hv_tx_buf_ioaddr_size));
128944961713Sgirish 		return (NXGE_ERROR | err);
129044961713Sgirish 	}
129144961713Sgirish 
129244961713Sgirish #ifdef	DEBUG
129344961713Sgirish 	ra = size = 0;
129444961713Sgirish 	hverr = hv_niu_tx_logical_page_info((uint64_t)channel,
129544961713Sgirish 			(uint64_t)0,
129644961713Sgirish 			&ra,
129744961713Sgirish 			&size);
129844961713Sgirish 
129944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
130044961713Sgirish 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
130144961713Sgirish 		"ok status 0x%x "
130244961713Sgirish 		"(page 0 data buf) hverr 0x%llx "
130344961713Sgirish 		"set ioaddr_pp $%p "
130444961713Sgirish 		"set size 0x%llx "
130544961713Sgirish 		"get ra ioaddr_pp $%p "
130644961713Sgirish 		"get size 0x%llx ",
130744961713Sgirish 		channel,
130844961713Sgirish 		err,
130944961713Sgirish 		hverr,
131044961713Sgirish 		tx_ring_p->hv_tx_buf_base_ioaddr_pp,
131144961713Sgirish 		tx_ring_p->hv_tx_buf_ioaddr_size,
131244961713Sgirish 		ra,
131344961713Sgirish 		size));
131444961713Sgirish #endif
131544961713Sgirish 
131644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
131744961713Sgirish 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
131844961713Sgirish 		"(page 0 data buf) hverr 0x%llx "
131944961713Sgirish 		"ioaddr_pp $%p "
132044961713Sgirish 		"size 0x%llx ",
132144961713Sgirish 		channel,
132244961713Sgirish 		hverr,
132344961713Sgirish 		tx_ring_p->hv_tx_buf_base_ioaddr_pp,
132444961713Sgirish 		tx_ring_p->hv_tx_buf_ioaddr_size));
132544961713Sgirish 
132644961713Sgirish 	/*
132744961713Sgirish 	 * Initialize logical page 2 for control buffers.
132844961713Sgirish 	 */
132944961713Sgirish 	hverr = hv_niu_tx_logical_page_conf((uint64_t)channel,
133044961713Sgirish 			(uint64_t)1,
133144961713Sgirish 			tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
133244961713Sgirish 			tx_ring_p->hv_tx_cntl_ioaddr_size);
133344961713Sgirish 
133444961713Sgirish 	err = (nxge_status_t)nxge_herr2kerr(hverr);
133544961713Sgirish 
133644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
133744961713Sgirish 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d"
133844961713Sgirish 		"ok status 0x%x "
133944961713Sgirish 		"(page 1 cntl buf) hverr 0x%llx "
134044961713Sgirish 		"ioaddr_pp $%p "
134144961713Sgirish 		"size 0x%llx ",
134244961713Sgirish 		channel,
134344961713Sgirish 		err,
134444961713Sgirish 		hverr,
134544961713Sgirish 		tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
134644961713Sgirish 		tx_ring_p->hv_tx_cntl_ioaddr_size));
134744961713Sgirish 
134844961713Sgirish 	if (err != 0) {
134944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
135044961713Sgirish 			"<== nxge_init_hv_fzc_txdma_channel_pages: channel %d"
135144961713Sgirish 			"error status 0x%x "
135244961713Sgirish 			"(page 1 cntl buf) hverr 0x%llx "
135344961713Sgirish 			"ioaddr_pp $%p "
135444961713Sgirish 			"size 0x%llx ",
135544961713Sgirish 			channel,
135644961713Sgirish 			err,
135744961713Sgirish 			hverr,
135844961713Sgirish 			tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
135944961713Sgirish 			tx_ring_p->hv_tx_cntl_ioaddr_size));
136044961713Sgirish 		return (NXGE_ERROR | err);
136144961713Sgirish 	}
136244961713Sgirish 
136344961713Sgirish #ifdef	DEBUG
136444961713Sgirish 	ra = size = 0;
136544961713Sgirish 	hverr = hv_niu_tx_logical_page_info((uint64_t)channel,
136644961713Sgirish 			(uint64_t)1,
136744961713Sgirish 			&ra,
136844961713Sgirish 			&size);
136944961713Sgirish 
137044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
137144961713Sgirish 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
137244961713Sgirish 		"(page 1 cntl buf) hverr 0x%llx "
137344961713Sgirish 		"set ioaddr_pp $%p "
137444961713Sgirish 		"set size 0x%llx "
137544961713Sgirish 		"get ra ioaddr_pp $%p "
137644961713Sgirish 		"get size 0x%llx ",
137744961713Sgirish 		channel,
137844961713Sgirish 		hverr,
137944961713Sgirish 		tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
138044961713Sgirish 		tx_ring_p->hv_tx_cntl_ioaddr_size,
138144961713Sgirish 		ra,
138244961713Sgirish 		size));
138344961713Sgirish #endif
138444961713Sgirish 
138544961713Sgirish 	tx_ring_p->hv_set = B_TRUE;
138644961713Sgirish 
138744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
138844961713Sgirish 		"<== nxge_init_hv_fzc_txdma_channel_pages"));
138944961713Sgirish 
139044961713Sgirish 	return (NXGE_OK);
139144961713Sgirish }
139244961713Sgirish 
139344961713Sgirish /*ARGSUSED*/
139444961713Sgirish nxge_status_t
139544961713Sgirish nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep,
139644961713Sgirish 		uint16_t channel, p_rx_rbr_ring_t rbrp)
139744961713Sgirish {
139844961713Sgirish 	int			err;
139944961713Sgirish 	uint64_t		hverr;
140044961713Sgirish #ifdef	DEBUG
140144961713Sgirish 	uint64_t		ra, size;
140244961713Sgirish #endif
140344961713Sgirish 
140444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
140544961713Sgirish 		"==> nxge_init_hv_fzc_rxdma_channel_pages"));
140644961713Sgirish 
140744961713Sgirish 	if (rbrp->hv_set) {
140844961713Sgirish 		return (NXGE_OK);
140944961713Sgirish 	}
141044961713Sgirish 
141144961713Sgirish 	/* Initialize data buffers for page 0 */
141244961713Sgirish 	hverr = hv_niu_rx_logical_page_conf((uint64_t)channel,
141344961713Sgirish 			(uint64_t)0,
141444961713Sgirish 			rbrp->hv_rx_buf_base_ioaddr_pp,
141544961713Sgirish 			rbrp->hv_rx_buf_ioaddr_size);
141644961713Sgirish 	err = (nxge_status_t)nxge_herr2kerr(hverr);
141744961713Sgirish 	if (err != 0) {
141844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
141944961713Sgirish 			"<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
142044961713Sgirish 			"error status 0x%x "
142144961713Sgirish 			"(page 0 data buf) hverr 0x%llx "
142244961713Sgirish 			"ioaddr_pp $%p "
142344961713Sgirish 			"size 0x%llx ",
142444961713Sgirish 			channel,
142544961713Sgirish 			err,
142644961713Sgirish 			hverr,
142744961713Sgirish 			rbrp->hv_rx_buf_base_ioaddr_pp,
142844961713Sgirish 			rbrp->hv_rx_buf_ioaddr_size));
142944961713Sgirish 
143044961713Sgirish 		return (NXGE_ERROR | err);
143144961713Sgirish 	}
143244961713Sgirish 
143344961713Sgirish #ifdef	DEBUG
143444961713Sgirish 	ra = size = 0;
143544961713Sgirish 	(void) hv_niu_rx_logical_page_info((uint64_t)channel,
143644961713Sgirish 			(uint64_t)0,
143744961713Sgirish 			&ra,
143844961713Sgirish 			&size);
143944961713Sgirish 
144044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
144144961713Sgirish 		"==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
144244961713Sgirish 		"ok status 0x%x "
144344961713Sgirish 		"(page 0 data buf) hverr 0x%llx "
144444961713Sgirish 		"set databuf ioaddr_pp $%p "
144544961713Sgirish 		"set databuf size 0x%llx "
144644961713Sgirish 		"get databuf ra ioaddr_pp %p "
144744961713Sgirish 		"get databuf size 0x%llx",
144844961713Sgirish 		channel,
144944961713Sgirish 		err,
145044961713Sgirish 		hverr,
145144961713Sgirish 		rbrp->hv_rx_buf_base_ioaddr_pp,
145244961713Sgirish 		rbrp->hv_rx_buf_ioaddr_size,
145344961713Sgirish 		ra,
145444961713Sgirish 		size));
145544961713Sgirish #endif
145644961713Sgirish 
145744961713Sgirish 	/* Initialize control buffers for logical page 1.  */
145844961713Sgirish 	hverr = hv_niu_rx_logical_page_conf((uint64_t)channel,
145944961713Sgirish 			(uint64_t)1,
146044961713Sgirish 			rbrp->hv_rx_cntl_base_ioaddr_pp,
146144961713Sgirish 			rbrp->hv_rx_cntl_ioaddr_size);
146244961713Sgirish 
146344961713Sgirish 	err = (nxge_status_t)nxge_herr2kerr(hverr);
146444961713Sgirish 	if (err != 0) {
146544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
146644961713Sgirish 			"<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
146744961713Sgirish 			"error status 0x%x "
146844961713Sgirish 			"(page 1 cntl buf) hverr 0x%llx "
146944961713Sgirish 			"ioaddr_pp $%p "
147044961713Sgirish 			"size 0x%llx ",
147144961713Sgirish 			channel,
147244961713Sgirish 			err,
147344961713Sgirish 			hverr,
147444961713Sgirish 			rbrp->hv_rx_buf_base_ioaddr_pp,
147544961713Sgirish 			rbrp->hv_rx_buf_ioaddr_size));
147644961713Sgirish 
147744961713Sgirish 		return (NXGE_ERROR | err);
147844961713Sgirish 	}
147944961713Sgirish 
148044961713Sgirish #ifdef	DEBUG
148144961713Sgirish 	ra = size = 0;
148244961713Sgirish 	(void) hv_niu_rx_logical_page_info((uint64_t)channel,
148344961713Sgirish 			(uint64_t)1,
148444961713Sgirish 			&ra,
148544961713Sgirish 			&size);
148644961713Sgirish 
148744961713Sgirish 
148844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
148944961713Sgirish 		"==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
149044961713Sgirish 		"error status 0x%x "
149144961713Sgirish 		"(page 1 cntl buf) hverr 0x%llx "
149244961713Sgirish 		"set cntl ioaddr_pp $%p "
149344961713Sgirish 		"set cntl size 0x%llx "
149444961713Sgirish 		"get cntl ioaddr_pp $%p "
149544961713Sgirish 		"get cntl size 0x%llx ",
149644961713Sgirish 		channel,
149744961713Sgirish 		err,
149844961713Sgirish 		hverr,
149944961713Sgirish 		rbrp->hv_rx_cntl_base_ioaddr_pp,
150044961713Sgirish 		rbrp->hv_rx_cntl_ioaddr_size,
150144961713Sgirish 		ra,
150244961713Sgirish 		size));
150344961713Sgirish #endif
150444961713Sgirish 
150544961713Sgirish 	rbrp->hv_set = B_FALSE;
150644961713Sgirish 
150744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
150844961713Sgirish 		"<== nxge_init_hv_fzc_rxdma_channel_pages"));
150944961713Sgirish 
151044961713Sgirish 	return (NXGE_OK);
151144961713Sgirish }
151244961713Sgirish 
151344961713Sgirish /*
151444961713Sgirish  * Map hypervisor error code to errno. Only
151544961713Sgirish  * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful
151644961713Sgirish  * for niu driver. Any other error codes are mapped to EINVAL.
151744961713Sgirish  */
151844961713Sgirish static int
151944961713Sgirish nxge_herr2kerr(uint64_t hv_errcode)
152044961713Sgirish {
152144961713Sgirish 	int	s_errcode;
152244961713Sgirish 
152344961713Sgirish 	switch (hv_errcode) {
152444961713Sgirish 	case H_ENORADDR:
152544961713Sgirish 	case H_EBADALIGN:
152644961713Sgirish 		s_errcode = EFAULT;
152744961713Sgirish 		break;
152844961713Sgirish 	case H_EOK:
152944961713Sgirish 		s_errcode = 0;
153044961713Sgirish 		break;
153144961713Sgirish 	default:
153244961713Sgirish 		s_errcode = EINVAL;
153344961713Sgirish 		break;
153444961713Sgirish 	}
153544961713Sgirish 	return (s_errcode);
153644961713Sgirish }
153744961713Sgirish 
153844961713Sgirish #endif	/* sun4v and NIU_LP_WORKAROUND */
1539